Chapter3:MemoryManagement
struct kmem_list3 *l3;
for (i = 0; i < nr_objects; i++) {
void *objp = objpp[i];
struct slab *slabp;
...
The following operations must be performed for each object:
mm/slab.c
slabp = virt_to_slab(objp)
l3 = cachep->nodelists[node];
list_del(&slabp->list);
slab_put_obj(cachep, slabp, objp, node);
slabp->inuse--;
l3->free_objects++;
Before it can be established to which slab an object belongs, it is first necessary to invokevirt_to_page
to find the page in which the object is located. The association with the slab is determined using
page_get_slabas discussed above.
The slab is (temporarily) removed from the lists of the cache.slab_put_objis used to reflect this action
in the freelist: The first object to be used for allocation purposes is the one just removed, and the next
object in the list is the one that was previously first.
Thereafter, the slab is reinserted in the linked lists of the cache:
mm/slab.c
...
/* fixup slab chains */
if (slabp->inuse == 0) {
if (l3->free_objects > l3->free_limit) {
l3->free_objects -= cachep->num;
slab_destroy(cachep, slabp);
} else {
list_add(&slabp->list, &l3->slabs_free);
}
} else {
list_add(&slabp->list, &l3->slabs_partial);
}
}
}
The slab is normally placed on theslabs_freelist if, after deletion, all objects in the slab are unused
(slab->inuse == 0).
Exception: The number of free objects in the cache is above the predefined limitcachep->free_limit.
In this case, the complete slab is returned to the buddy system usingslab_destroy.
The slab is inserted into theslabs_partiallist of the cache if it contains both used and unused
objects.