All pastes #519962 Raw Edit

Someone

public c v1 · immutable
#519962 ·published 2007-05-29 20:19 UTC
rendered paste body
static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags){        int batchcount;        struct kmem_list3 *l3;        struct array_cache *ac;        int node;        node = numa_node_id();        check_irq_off();        ac = cpu_cache_get(cachep);retry:        batchcount = ac->batchcount;        if (!ac->touched && batchcount > BATCHREFILL_LIMIT) {                /*                 * If there was little recent activity on this cache, then                 * perform only a partial refill.  Otherwise we could generate                 * refill bouncing.                 */                batchcount = BATCHREFILL_LIMIT;        }        l3 = cachep->nodelists[node];        BUG_ON(ac->avail > 0 || !l3);        spin_lock(&l3->list_lock);        /* See if we can refill from the shared array */        if (l3->shared && transfer_objects(ac, l3->shared, batchcount))                goto alloc_done;        while (batchcount > 0) {                struct list_head *entry;                struct slab *slabp;                /* Get slab alloc is to come from. */                entry = l3->slabs_partial.next;                if (entry == &l3->slabs_partial) {                        l3->free_touched = 1;                        entry = l3->slabs_free.next;                        if (entry == &l3->slabs_free)                                goto must_grow;                }                slabp = list_entry(entry, struct slab, list);                check_slabp(cachep, slabp);                check_spinlock_acquired(cachep);                while (slabp->inuse < cachep->num && batchcount--) {                        STATS_INC_ALLOCED(cachep);                        STATS_INC_ACTIVE(cachep);                        STATS_SET_HIGH(cachep);                        ac->entry[ac->avail++] = slab_get_obj(cachep, slabp,                                                            node);                }                check_slabp(cachep, slabp);                /* move slabp to correct slabp list: */                list_del(&slabp->list);                if (slabp->free == BUFCTL_END)                        list_add(&slabp->list, &l3->slabs_full);                else                        list_add(&slabp->list, &l3->slabs_partial);        }must_grow:        l3->free_objects -= ac->avail;alloc_done:        spin_unlock(&l3->list_lock);        if (unlikely(!ac->avail)) {                int x;                x = cache_grow(cachep, flags, node);                /* cache_grow can reenable interrupts, then ac could change. */                ac = cpu_cache_get(cachep);                if (!x && ac->avail == 0)       /* no objects in sight? abort */                        return NULL;                if (!ac->avail)         /* objects refilled by interrupt? */                        goto retry;        }        ac->touched = 1;        return ac->entry[--ac->avail];}