summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bevitt <cyfred@gentoo.org>2004-11-26 01:47:14 +0000
committerAndrew Bevitt <cyfred@gentoo.org>2004-11-26 01:47:14 +0000
commit7e353060b6bff24cd25c4f1d029d23a278348a7a (patch)
treede58f2634e866adf96d62dd2a3a9f63a5d450dcd /media-video/nvidia-kernel/files
parentPut detect_version back in for now (Manifest recommit) (diff)
downloadgentoo-2-7e353060b6bff24cd25c4f1d029d23a278348a7a.tar.gz
gentoo-2-7e353060b6bff24cd25c4f1d029d23a278348a7a.tar.bz2
gentoo-2-7e353060b6bff24cd25c4f1d029d23a278348a7a.zip
Fixing bug #71684 with supplied patch
Diffstat (limited to 'media-video/nvidia-kernel/files')
-rw-r--r--media-video/nvidia-kernel/files/1.0.6629/nv-fix-memory-limit.patch548
1 files changed, 548 insertions, 0 deletions
diff --git a/media-video/nvidia-kernel/files/1.0.6629/nv-fix-memory-limit.patch b/media-video/nvidia-kernel/files/1.0.6629/nv-fix-memory-limit.patch
new file mode 100644
index 000000000000..21c68a98aeb0
--- /dev/null
+++ b/media-video/nvidia-kernel/files/1.0.6629/nv-fix-memory-limit.patch
@@ -0,0 +1,548 @@
+diff -ru usr/src/nv/nv-linux.h usr/src/nv.1161283/nv-linux.h
+--- usr/src/nv/nv-linux.h 2004-11-03 22:53:00.000000000 +0100
++++ usr/src/nv.1161283/nv-linux.h 2004-11-16 22:56:41.000000000 +0100
+@@ -429,6 +429,30 @@
+ free_pages(ptr, order); \
+ }
+
++#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type) \
++ { \
++ kmem_cache = kmem_cache_create(name, sizeof(type), \
++ 0, 0, NULL, NULL); \
++ }
++
++#define NV_KMEM_CACHE_DESTROY(kmem_cache) \
++ { \
++ kmem_cache_destroy(kmem_cache); \
++ kmem_cache = NULL; \
++ }
++
++#define NV_KMEM_CACHE_ALLOC(ptr, kmem_cache, type) \
++ { \
++ (ptr) = kmem_cache_alloc(kmem_cache, GFP_KERNEL); \
++ KM_ALLOC_RECORD(ptr, sizeof(type), "km_cache_alloc"); \
++ }
++
++#define NV_KMEM_CACHE_FREE(ptr, type, kmem_cache) \
++ { \
++ KM_FREE_RECORD(ptr, sizeof(type), "km_cache_free"); \
++ kmem_cache_free(kmem_cache, ptr); \
++ }
++
+ #endif /* !defined NVWATCH */
+
+
+@@ -776,6 +800,9 @@
+ unsigned long phys_addr;
+ unsigned long virt_addr;
+ dma_addr_t dma_addr;
++#ifdef NV_SG_MAP_BUFFERS
++ struct scatterlist sg_list;
++#endif
+ #ifdef CONFIG_SWIOTLB
+ unsigned long orig_phys_addr;
+ unsigned long orig_virt_addr;
+@@ -789,15 +816,11 @@
+ unsigned int num_pages;
+ unsigned int order;
+ unsigned int size;
+- nv_pte_t *page_table; /* list of physical pages allocated */
++ nv_pte_t **page_table; /* list of physical pages allocated */
+ void *key_mapping; /* mapping used as a key for finding this nv_alloc_t */
+ /* may be the same as page_table */
+ unsigned int class;
+ void *priv_data;
+-#if defined(NV_SG_MAP_BUFFERS)
+- struct pci_dev *dev;
+- struct scatterlist *sg_list; /* list of physical pages allocated */
+-#endif
+ } nv_alloc_t;
+
+
+diff -ru usr/src/nv/nv-vm.c usr/src/nv.1161283/nv-vm.c
+--- usr/src/nv/nv-vm.c 2004-11-03 22:53:00.000000000 +0100
++++ usr/src/nv.1161283/nv-vm.c 2004-11-16 22:56:41.000000000 +0100
+@@ -138,13 +138,18 @@
+ */
+
+ int nv_vm_malloc_pages(
+- nv_alloc_t *at
++ nv_state_t *nv,
++ nv_alloc_t *at
+ )
+ {
+ /* point page_ptr at the start of the actual page list */
+- nv_pte_t *page_ptr = at->page_table;
++ nv_pte_t *page_ptr = *at->page_table;
+ int i;
+ unsigned long virt_addr = 0, phys_addr;
++#if defined(NV_SG_MAP_BUFFERS)
++ nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv);
++ struct pci_dev *dev = nvl->dev;
++#endif
+
+ nv_printf(NV_DBG_MEMINFO, "NVRM: VM: nv_vm_malloc_pages: %d pages\n",
+ at->num_pages);
+@@ -175,7 +180,7 @@
+ // for amd 64-bit platforms, remap pages to make them 32-bit addressable
+ // in this case, we need the final remapping to be contiguous, so we
+ // have to do the whole mapping at once, instead of page by page
+- if (nv_sg_map_buffer(at->dev, &at->sg_list[0],
++ if (nv_sg_map_buffer(dev, &at->page_table[0]->sg_list,
+ (void *) virt_addr, at->num_pages))
+ {
+ nv_printf(NV_DBG_ERRORS,
+@@ -224,7 +229,7 @@
+ /* lock the page for dma purposes */
+ SetPageReserved(NV_GET_PAGE_STRUCT(phys_addr));
+
+- page_ptr = &at->page_table[i];
++ page_ptr = at->page_table[i];
+ page_ptr->phys_addr = phys_addr;
+ page_ptr->virt_addr = virt_addr;
+ page_ptr->dma_addr = page_ptr->phys_addr;
+@@ -235,7 +240,7 @@
+ #if defined(NV_SG_MAP_BUFFERS)
+ if (!NV_ALLOC_MAPPING_CONTIG(at->flags))
+ {
+- if (nv_sg_map_buffer(at->dev, &at->sg_list[i],
++ if (nv_sg_map_buffer(dev, &at->page_table[i]->sg_list,
+ __va(page_ptr->phys_addr), 1))
+ {
+ nv_printf(NV_DBG_ERRORS,
+@@ -243,7 +248,7 @@
+ goto failed;
+ }
+ }
+- nv_sg_load(&at->sg_list[i], page_ptr);
++ nv_sg_load(&at->page_table[i]->sg_list, page_ptr);
+ #endif
+ virt_addr += PAGE_SIZE;
+ }
+@@ -258,7 +263,7 @@
+
+ for (; i >= 0; i--)
+ {
+- page_ptr = &at->page_table[i];
++ page_ptr = at->page_table[i];
+
+ // if we failed when allocating this page, skip over it
+ // but if we failed pci_map_sg, make sure to free this page
+@@ -267,7 +272,7 @@
+ NV_UNLOCK_PAGE(page_ptr);
+ #if defined(NV_SG_MAP_BUFFERS)
+ if (!NV_ALLOC_MAPPING_CONTIG(at->flags))
+- nv_sg_unmap_buffer(at->dev, &at->sg_list[i], page_ptr);
++ nv_sg_unmap_buffer(dev, &at->page_table[i]->sg_list, page_ptr);
+ #endif
+ if (!NV_ALLOC_MAPPING_CACHED(at->flags))
+ NV_SET_PAGE_ATTRIB_CACHED(page_ptr);
+@@ -279,15 +284,15 @@
+
+ if (NV_ALLOC_MAPPING_CONTIG(at->flags))
+ {
+- page_ptr = at->page_table;
++ page_ptr = *at->page_table;
+ #if defined(NV_SG_MAP_BUFFERS)
+- nv_sg_unmap_buffer(at->dev, &at->sg_list[0], page_ptr);
++ nv_sg_unmap_buffer(dev, &at->page_table[0]->sg_list, page_ptr);
+ #endif
+ NV_FREE_PAGES(page_ptr->virt_addr, at->order);
+ }
+ else if (NV_ALLOC_MAPPING_VMALLOC(at->flags))
+ {
+- page_ptr = at->page_table;
++ page_ptr = *at->page_table;
+ NV_VFREE((void *) page_ptr->virt_addr, at->size);
+ }
+
+@@ -296,7 +301,7 @@
+
+ // unlock the pages we've locked down for dma purposes
+ void nv_vm_unlock_pages(
+- nv_alloc_t *at
++ nv_alloc_t *at
+ )
+ {
+ nv_pte_t *page_ptr;
+@@ -315,17 +320,22 @@
+
+ for (i = 0; i < at->num_pages; i++)
+ {
+- page_ptr = &at->page_table[i];
++ page_ptr = at->page_table[i];
+ NV_UNLOCK_PAGE(page_ptr);
+ }
+ }
+
+ void nv_vm_free_pages(
+- nv_alloc_t *at
++ nv_state_t *nv,
++ nv_alloc_t *at
+ )
+ {
+ nv_pte_t *page_ptr;
+ int i;
++#if defined(NV_SG_MAP_BUFFERS)
++ nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv);
++ struct pci_dev *dev = nvl->dev;
++#endif
+
+ nv_printf(NV_DBG_MEMINFO, "NVRM: VM: nv_vm_free_pages: %d pages\n",
+ at->num_pages);
+@@ -339,10 +349,10 @@
+
+ for (i = 0; i < at->num_pages; i++)
+ {
+- page_ptr = &at->page_table[i];
++ page_ptr = at->page_table[i];
+ #if defined(NV_SG_MAP_BUFFERS)
+ if (!NV_ALLOC_MAPPING_CONTIG(at->flags))
+- nv_sg_unmap_buffer(at->dev, &at->sg_list[i], page_ptr);
++ nv_sg_unmap_buffer(dev, &at->page_table[i]->sg_list, page_ptr);
+ #endif
+ if (!NV_ALLOC_MAPPING_CACHED(at->flags))
+ NV_SET_PAGE_ATTRIB_CACHED(page_ptr);
+@@ -353,15 +363,15 @@
+
+ if (NV_ALLOC_MAPPING_CONTIG(at->flags))
+ {
+- page_ptr = at->page_table;
++ page_ptr = *at->page_table;
+ #if defined(NV_SG_MAP_BUFFERS)
+- nv_sg_unmap_buffer(at->dev, &at->sg_list[0], page_ptr);
++ nv_sg_unmap_buffer(dev, &at->page_table[0]->sg_list, page_ptr);
+ #endif
+ NV_FREE_PAGES(page_ptr->virt_addr, at->order);
+ }
+ else if (NV_ALLOC_MAPPING_VMALLOC(at->flags))
+ {
+- page_ptr = at->page_table;
++ page_ptr = *at->page_table;
+ NV_VFREE((void *) page_ptr->virt_addr, at->size);
+ }
+ }
+diff -ru usr/src/nv/nv-vm.h usr/src/nv.1161283/nv-vm.h
+--- usr/src/nv/nv-vm.h 2004-11-03 22:53:00.000000000 +0100
++++ usr/src/nv.1161283/nv-vm.h 2004-11-16 22:56:41.000000000 +0100
+@@ -11,9 +11,9 @@
+ #ifndef _NV_VM_H_
+ #define _NV_VM_H_
+
+-int nv_vm_malloc_pages(nv_alloc_t *);
++int nv_vm_malloc_pages(nv_state_t *, nv_alloc_t *);
+ void nv_vm_unlock_pages(nv_alloc_t *);
+-void nv_vm_free_pages(nv_alloc_t *);
++void nv_vm_free_pages(nv_state_t *, nv_alloc_t *);
+
+ #if defined(NV_DBG_MEM)
+ void nv_vm_list_page_count(nv_pte_t *, unsigned long);
+@@ -21,11 +21,12 @@
+ #define nv_vm_list_page_count(page_ptr, num_pages)
+ #endif
+
+-#define nv_vm_unlock_and_free_pages(at_count, at) \
+- if (at->page_table) { \
+- if (at_count == 0) \
+- nv_vm_unlock_pages(at); \
+- nv_vm_free_pages(at); \
++#define NV_VM_UNLOCK_AND_FREE_PAGES(nv, at_count, at) \
++ if (at->page_table) \
++ { \
++ if (at_count == 0) \
++ nv_vm_unlock_pages(at); \
++ nv_vm_free_pages(nv, at); \
+ }
+
+ #endif
+diff -ru usr/src/nv/nv.c usr/src/nv.1161283/nv.c
+--- usr/src/nv/nv.c 2004-11-03 22:53:00.000000000 +0100
++++ usr/src/nv.1161283/nv.c 2004-11-16 22:57:24.000000000 +0100
+@@ -63,6 +63,8 @@
+ int nv_swiotlb = 0;
+ #endif
+
++static kmem_cache_t *nv_pte_t_cache = NULL;
++
+ // allow an easy way to convert all debug printfs related to events
+ // back and forth between 'info' and 'errors'
+ #if defined(NV_DBG_EVENTS)
+@@ -266,42 +268,41 @@
+ )
+ {
+ nv_alloc_t *at;
+- int pt_size;
++ unsigned int pt_size, i;
+
+ NV_KMALLOC(at, sizeof(nv_alloc_t));
+ if (at == NULL)
+ {
+- nv_printf(NV_DBG_ERRORS, "NVRM: failed to allocate alloc_t\n");
++ nv_printf(NV_DBG_ERRORS, "NVRM: failed to allocate alloc info\n");
+ return NULL;
+ }
+
+ memset(at, 0, sizeof(nv_alloc_t));
+
+- pt_size = num_pages * sizeof(nv_pte_t);
+- NV_KMALLOC(at->page_table, pt_size);
+- if (at->page_table == NULL)
++ pt_size = num_pages * sizeof(nv_pte_t *);
++ if (os_alloc_mem((void **)&at->page_table, pt_size) != RM_OK)
+ {
+ nv_printf(NV_DBG_ERRORS, "NVRM: failed to allocate page table\n");
+ NV_KFREE(at, sizeof(nv_alloc_t));
+ return NULL;
+ }
++
+ memset(at->page_table, 0, pt_size);
+ at->num_pages = num_pages;
+ NV_ATOMIC_SET(at->usage_count, 0);
+
+-#if defined(NV_SG_MAP_BUFFERS)
+- at->dev = dev;
+- pt_size = num_pages * sizeof(struct scatterlist);
+- NV_KMALLOC(at->sg_list, pt_size);
+- if (at->sg_list == NULL)
++ for (i = 0; i < at->num_pages; i++)
+ {
+- nv_printf(NV_DBG_ERRORS, "NVRM: failed to allocate scatter gather list\n");
+- NV_KFREE(at->page_table, pt_size);
+- NV_KFREE(at, sizeof(nv_alloc_t));
+- return NULL;
++ NV_KMEM_CACHE_ALLOC(at->page_table[i], nv_pte_t_cache, nv_pte_t);
++ if (at->page_table[i] == NULL)
++ {
++ nv_printf(NV_DBG_ERRORS,
++ "NVRM: failed to allocate page table entry\n");
++ nvos_free_alloc(at);
++ return NULL;
++ }
++ memset(at->page_table[i], 0, sizeof(nv_pte_t));
+ }
+- memset(at->sg_list, 0, pt_size);
+-#endif
+
+ return at;
+ }
+@@ -311,6 +312,8 @@
+ nv_alloc_t *at
+ )
+ {
++ unsigned int pt_size, i;
++
+ if (at == NULL)
+ return -1;
+
+@@ -320,13 +323,16 @@
+ // we keep the page_table around after freeing the pages
+ // for bookkeeping reasons. Free the page_table and assume
+ // the underlying pages are already unlocked and freed.
+- if (at->page_table)
+- NV_KFREE(at->page_table, at->num_pages * sizeof(nv_pte_t));
+-
+-#if defined(NV_SG_MAP_BUFFERS)
+- if (at->sg_list)
+- NV_KFREE(at->sg_list, at->num_pages * sizeof(struct scatterlist));
+-#endif
++ if (at->page_table != NULL)
++ {
++ for (i = 0; i < at->num_pages; i++)
++ {
++ if (at->page_table[i] != NULL)
++ NV_KMEM_CACHE_FREE(at->page_table[i], nv_pte_t, nv_pte_t_cache);
++ }
++ pt_size = at->num_pages * sizeof(nv_pte_t *);
++ os_free_mem(at->page_table);
++ }
+
+ NV_KFREE(at, sizeof(nv_alloc_t));
+
+@@ -594,7 +600,7 @@
+ int i;
+ for (i = 0; i < at->num_pages; i++)
+ {
+- unsigned long offset = at->page_table[i].phys_addr;
++ unsigned long offset = at->page_table[i]->phys_addr;
+ if ((address >= offset) &&
+ (address < (offset + PAGE_SIZE)))
+ return at;
+@@ -931,6 +937,13 @@
+ }
+ #endif
+
++ NV_KMEM_CACHE_CREATE(nv_pte_t_cache, "nv_pte_t", nv_pte_t);
++ if (nv_pte_t_cache == NULL)
++ {
++ nv_printf(NV_DBG_ERRORS, "NVRM: pte cache allocation failed\n");
++ goto failed;
++ }
++
+ // Init the resource manager
+ if (!rm_init_rm())
+ {
+@@ -972,6 +985,14 @@
+ return 0;
+
+ failed:
++ if (nv_pte_t_cache != NULL)
++ NV_KMEM_CACHE_DESTROY(nv_pte_t_cache);
++
++#if defined(NV_PM_SUPPORT_APM)
++ for (i = 0; i < num_nv_devices; i++)
++ if (apm_nv_dev[i] != NULL) pm_unregister(apm_nv_dev[i]);
++#endif
++
+ #ifdef CONFIG_DEVFS_FS
+ NV_DEVFS_REMOVE_CONTROL();
+ for (i = 0; i < num_nv_devices; i++)
+@@ -1101,6 +1122,8 @@
+ nv_printf(NV_DBG_ERRORS, "NVRM: final mem usage: vm 0x%x km 0x%x fp 0x%x\n",
+ vm_usage, km_usage, fp_usage);
+ #endif
++
++ NV_KMEM_CACHE_DESTROY(nv_pte_t_cache);
+ }
+
+ module_init(nvidia_init_module);
+@@ -1249,15 +1272,15 @@
+ index = (address - vma->vm_start)>>PAGE_SHIFT;
+
+ // save that index into our page list (make sure it doesn't already exist)
+- if (at->page_table[index].phys_addr)
++ if (at->page_table[index]->phys_addr)
+ {
+ nv_printf(NV_DBG_ERRORS, "NVRM: page slot already filled in nopage handler!\n");
+ os_dbg_breakpoint();
+ }
+
+- at->page_table[index].phys_addr = (page_to_pfn(page_ptr) << PAGE_SHIFT);
+- at->page_table[index].dma_addr = (page_to_pfn(page_ptr) << PAGE_SHIFT);
+- at->page_table[index].virt_addr = (unsigned long) __va(page_to_pfn(page_ptr) << PAGE_SHIFT);
++ at->page_table[index]->phys_addr = (page_to_pfn(page_ptr) << PAGE_SHIFT);
++ at->page_table[index]->dma_addr = (page_to_pfn(page_ptr) << PAGE_SHIFT);
++ at->page_table[index]->virt_addr = (unsigned long) __va(page_to_pfn(page_ptr) << PAGE_SHIFT);
+
+ return page_ptr;
+ #endif
+@@ -1670,7 +1693,7 @@
+ start = vma->vm_start;
+ while (pages--)
+ {
+- page = (unsigned long) at->page_table[i++].phys_addr;
++ page = (unsigned long) at->page_table[i++]->phys_addr;
+ if (NV_REMAP_PAGE_RANGE(start, page, PAGE_SIZE, vma->vm_page_prot))
+ return -EAGAIN;
+ start += PAGE_SIZE;
+@@ -2368,8 +2391,8 @@
+
+ for (i = 0; i < at->num_pages; i++)
+ {
+- if (address == at->page_table[i].phys_addr)
+- return (void *)(at->page_table[i].virt_addr + offset);
++ if (address == at->page_table[i]->phys_addr)
++ return (void *)(at->page_table[i]->virt_addr + offset);
+ }
+ }
+
+@@ -2400,8 +2423,8 @@
+
+ for (i = 0; i < at->num_pages; i++)
+ {
+- if (address == at->page_table[i].phys_addr)
+- return (unsigned long)at->page_table[i].dma_addr + offset;
++ if (address == at->page_table[i]->phys_addr)
++ return (unsigned long)at->page_table[i]->dma_addr + offset;
+ }
+ }
+
+@@ -2427,9 +2450,9 @@
+ unsigned long address = dma_address & PAGE_MASK;
+ for (i = 0; i < at->num_pages; i++)
+ {
+- if (address == at->page_table[i].dma_addr)
++ if (address == at->page_table[i]->dma_addr)
+ {
+- return at->page_table[i].phys_addr + offset;
++ return at->page_table[i]->phys_addr + offset;
+ }
+ }
+ }
+@@ -2466,7 +2489,7 @@
+ int i;
+ for (i = 0; i < at->num_pages; i++)
+ {
+- if (address == (unsigned long) at->page_table[i].dma_addr)
++ if (address == (unsigned long) at->page_table[i]->dma_addr)
+ {
+ return (void *)((unsigned long) at->key_mapping +
+ (i * PAGE_SIZE));
+@@ -2630,7 +2653,7 @@
+ nvl_add_alloc(nvl, at);
+ } else {
+ /* use nvidia's nvagp support */
+- if (nv_vm_malloc_pages(at))
++ if (nv_vm_malloc_pages(nv, at))
+ goto failed;
+
+ at->class = class;
+@@ -2654,7 +2677,7 @@
+ if (rm_status)
+ {
+ nvl_remove_alloc(nvl, at);
+- nv_vm_unlock_and_free_pages(NV_ATOMIC_READ(at->usage_count), at);
++ NV_VM_UNLOCK_AND_FREE_PAGES(nv, NV_ATOMIC_READ(at->usage_count), at);
+ goto failed;
+ }
+ at->priv_data = *priv_data;
+@@ -2666,12 +2689,12 @@
+ else
+ {
+
+- if (nv_vm_malloc_pages(at))
++ if (nv_vm_malloc_pages(nv, at))
+ goto failed;
+
+ if (kernel)
+ {
+- *pAddress = (void *) at->page_table[0].virt_addr;
++ *pAddress = (void *) at->page_table[0]->virt_addr;
+ }
+ else
+ {
+@@ -2679,7 +2702,7 @@
+ * so use the first page, which is page-aligned. this way, our
+ * allocated page table does not need to be page-aligned
+ */
+- *pAddress = (void *) at->page_table[0].phys_addr;
++ *pAddress = (void *) at->page_table[0]->phys_addr;
+ }
+
+ nvl_add_alloc(nvl, at);
+@@ -2743,7 +2766,7 @@
+ rmStatus = rm_free_agp_pages(nv, pAddress, priv_data);
+ if (rmStatus == RM_OK)
+ {
+- nv_vm_unlock_and_free_pages(NV_ATOMIC_READ(at->usage_count), at);
++ NV_VM_UNLOCK_AND_FREE_PAGES(nv, NV_ATOMIC_READ(at->usage_count), at);
+ }
+ }
+ } else {
+@@ -2759,7 +2782,7 @@
+
+ NV_ATOMIC_DEC(at->usage_count);
+
+- nv_vm_unlock_and_free_pages(NV_ATOMIC_READ(at->usage_count), at);
++ NV_VM_UNLOCK_AND_FREE_PAGES(nv, NV_ATOMIC_READ(at->usage_count), at);
+ }
+
+ if (NV_ATOMIC_READ(at->usage_count) == 0)
+@@ -3065,7 +3088,7 @@
+ }
+
+ /* get the physical address of this page */
+- *paddr = (U032) ((NV_UINTPTR_T)at->page_table[index].dma_addr);
++ *paddr = (U032) ((NV_UINTPTR_T)at->page_table[index]->dma_addr);
+
+ return RM_OK;
+ }