Messages in this thread Patch in this message | | | Date | Thu, 31 Dec 1998 18:56:14 +0100 (CET) | From | Andrea Arcangeli <> | Subject | Re: get_vm_area needs spin lock |
| |
On Wed, 30 Dec 1998, David Grothe wrote:
> I am enclosing a patch for 2.2.0pre1 (mm/vmalloc.c) that I think fixes > this problem. The patch is enclosed as a MIME attachment to avoid
There is no need for irqsave since vmalloc can be used only from a normal kernel context (noirq and nobh). And there's no reason for GFP_ATOMIC I think. So I changed a bit your patch this way:
Index: linux/mm/vmalloc.c diff -u linux/mm/vmalloc.c:1.1.1.2 linux/mm/vmalloc.c:1.1.1.1.2.3 --- linux/mm/vmalloc.c:1.1.1.2 Fri Nov 27 11:19:11 1998 +++ linux/mm/vmalloc.c Thu Dec 31 18:55:11 1998 @@ -10,6 +10,7 @@ #include <asm/uaccess.h> static struct vm_struct * vmlist = NULL; +static spinlock_t vmlist_spinlock; static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned long size) { @@ -158,17 +159,21 @@ if (!area) return NULL; addr = VMALLOC_START; + spin_lock(&vmlist_spinlock); for (p = &vmlist; (tmp = *p) ; p = &tmp->next) { if (size + addr < (unsigned long) tmp->addr) break; - if (addr > VMALLOC_END-size) + if (addr > VMALLOC_END-size) { + spin_unlock(&vmlist_spinlock); return NULL; + } addr = tmp->size + (unsigned long) tmp->addr; } area->addr = (void *)addr; area->size = size + PAGE_SIZE; area->next = *p; *p = area; + spin_unlock(&vmlist_spinlock); return area; } @@ -182,14 +187,18 @@ printk("Trying to vfree() bad address (%p)\n", addr); return; } + spin_lock(&vmlist_spinlock); for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) { if (tmp->addr == addr) { *p = tmp->next; - vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size); + spin_unlock(&vmlist_spinlock); + vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), + tmp->size - PAGE_SIZE); kfree(tmp); return; } } + spin_unlock(&vmlist_spinlock); printk("Trying to vfree() nonexistent vm area (%p)\n", addr); } @@ -222,6 +231,7 @@ if ((unsigned long) addr + count < count) count = -(unsigned long) addr; + spin_lock(&vmlist_spinlock); for (tmp = vmlist; tmp; tmp = tmp->next) { vaddr = (char *) tmp->addr; if (addr >= vaddr + tmp->size - PAGE_SIZE) @@ -245,5 +255,6 @@ } while (--n > 0); } finished: + spin_unlock(&vmlist_spinlock); return buf - buf_start; }
Andrea Arcangeli
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |