]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - mm/vmalloc.c
mm: percpu-vmap fix RCU list walking
[linux-2.6.git] / mm / vmalloc.c
index d55d905463ebc6186527403a5c9343894cdd189b..cf76ff6ba596bf0cdead3fb226202a8db03d24b4 100644 (file)
@@ -667,8 +667,6 @@ static bool vmap_initialized __read_mostly = false;
 struct vmap_block_queue {
        spinlock_t lock;
        struct list_head free;
-       struct list_head dirty;
-       unsigned int nr_dirty;
 };
 
 struct vmap_block {
@@ -678,10 +676,8 @@ struct vmap_block {
        unsigned long free, dirty;
        DECLARE_BITMAP(alloc_map, VMAP_BBMAP_BITS);
        DECLARE_BITMAP(dirty_map, VMAP_BBMAP_BITS);
-       union {
-               struct list_head free_list;
-               struct rcu_head rcu_head;
-       };
+       struct list_head free_list;
+       struct rcu_head rcu_head;
 };
 
 /* Queue of free and dirty vmap blocks, for allocation and flushing purposes */
@@ -757,7 +753,7 @@ static struct vmap_block *new_vmap_block(gfp_t gfp_mask)
        vbq = &get_cpu_var(vmap_block_queue);
        vb->vbq = vbq;
        spin_lock(&vbq->lock);
-       list_add(&vb->free_list, &vbq->free);
+       list_add_rcu(&vb->free_list, &vbq->free);
        spin_unlock(&vbq->lock);
        put_cpu_var(vmap_block_queue);
 
@@ -776,8 +772,6 @@ static void free_vmap_block(struct vmap_block *vb)
        struct vmap_block *tmp;
        unsigned long vb_idx;
 
-       BUG_ON(!list_empty(&vb->free_list));
-
        vb_idx = addr_to_vb_idx(vb->va->va_start);
        spin_lock(&vmap_block_tree_lock);
        tmp = radix_tree_delete(&vmap_block_tree, vb_idx);
@@ -816,7 +810,7 @@ again:
                        vb->free -= 1UL << order;
                        if (vb->free == 0) {
                                spin_lock(&vbq->lock);
-                               list_del_init(&vb->free_list);
+                               list_del_rcu(&vb->free_list);
                                spin_unlock(&vbq->lock);
                        }
                        spin_unlock(&vb->lock);
@@ -860,11 +854,11 @@ static void vb_free(const void *addr, unsigned long size)
        BUG_ON(!vb);
 
        spin_lock(&vb->lock);
-       bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order);
+       BUG_ON(bitmap_allocate_region(vb->dirty_map, offset >> PAGE_SHIFT, order));
 
        vb->dirty += 1UL << order;
        if (vb->dirty == VMAP_BBMAP_BITS) {
-               BUG_ON(vb->free || !list_empty(&vb->free_list));
+               BUG_ON(vb->free);
                spin_unlock(&vb->lock);
                free_vmap_block(vb);
        } else
@@ -1033,8 +1027,6 @@ void __init vmalloc_init(void)
                vbq = &per_cpu(vmap_block_queue, i);
                spin_lock_init(&vbq->lock);
                INIT_LIST_HEAD(&vbq->free);
-               INIT_LIST_HEAD(&vbq->dirty);
-               vbq->nr_dirty = 0;
        }
 
        /* Import existing vmlist entries. */