Skip to content
  • Lai Jiangshan's avatar
    rcu: introduce kfree_rcu() · 9ab1544e
    Lai Jiangshan authored
    Many rcu callbacks functions just call kfree() on the base structure.
    These functions are trivial, but their size adds up, and furthermore
    when they are used in a kernel module, that module must invoke the
    high-latency rcu_barrier() function at module-unload time.
    
    The kfree_rcu() function introduced by this commit addresses this issue.
    Rather than encoding a function address in the embedded rcu_head
    structure, kfree_rcu() instead encodes the offset of the rcu_head
    structure within the base structure.  Because the functions are not
    allowed in the low-order 4096 bytes of kernel virtual memory, offsets
    up to 4095 bytes can be accommodated.  If the offset is larger than
    4095 bytes, a compile-time error will be generated in __kfree_rcu().
    If this error is triggered, you can either fall back to use of call_rcu()
    or rearrange the structure to position the rcu_head structure into the
    first 4096 bytes.
    
    Note that the allowable offset might decrease in the future, for example,
    to allow something like kmem_cache_free_rcu().
    
    The new kfree_rcu() function can replace code as follows:
    
    	call_rcu(&p->rcu, simple_kfree_callback);
    
    where "simple_kfree_callback()" might be defined as follows:
    
    	void simple_kfree_callback(struct rcu_head *p)
    	{
    		struct foo *q = container_of(p, struct foo, rcu);
    
    		kfree(q);
    	}
    
    with the following:
    
    	kfree_rcu(&p->rcu, rcu);
    
    Note that the "rcu" is the name of a field in the structure being
    freed.  The reason for using this rather than passing in a pointer
    to the base structure is that the above approach allows better type
    checking.
    
    This commit is based on earlier work by Lai Jiangshan and Manfred Spraul:
    
    Lai's V1 patch: http://lkml.org/lkml/2008/9/18/1
    Manfred's patch: http://lkml.org/lkml/2009/1/2/115
    
    
    
    Signed-off-by: default avatarLai Jiangshan <laijs@cn.fujitsu.com>
    Signed-off-by: default avatarManfred Spraul <manfred@colorfullife.com>
    Signed-off-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
    Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
    Reviewed-by: default avatarJosh Triplett <josh@joshtriplett.org>
    9ab1544e