Hi Andrew, Today's linux-next merge of the akpm tree got a conflict in ipc/util.c between commit 823a5ed16606 ("ipc_schedule_free() can do vfree() now") from the vfs tree and commit "ipc: make refcounter atomic" from the akpm tree. I fixed it up (I hope - see below) and can carry the fix as necessary (no action is required). -- Cheers, Stephen Rothwell sfr@canb.auug.org.au diff --cc ipc/util.c index 6515f95,5e60ebd..0000000 --- a/ipc/util.c +++ b/ipc/util.c @@@ -477,7 -478,8 +477,7 @@@ void ipc_free(void* ptr, int size */ struct ipc_rcu_hdr { - int refcount; + atomic_t refcount; - int is_vmalloc; void *data[0]; }; @@@ -497,30 -516,48 +497,28 @@@ struct ipc_rcu_grac * @size: size desired * * Allocate memory for the rcu header structure + the object. - * Returns the pointer to the object. - * NULL is returned if the allocation fails. + * Returns the pointer to the object or NULL upon failure. */ - - void* ipc_rcu_alloc(int size) + void *ipc_rcu_alloc(int size) { - void* out; - - /* - * We prepend the allocation with the rcu struct, and - * workqueue if necessary (for vmalloc). + size_t len = size + HDRLEN; + void *out; + /* + * We prepend the allocation with the rcu struct */ - if (rcu_use_vmalloc(size)) { - out = vmalloc(HDRLEN_VMALLOC + size); - if (!out) - goto done; - - out += HDRLEN_VMALLOC; - container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 1; - } else { - out = kmalloc(HDRLEN_KMALLOC + size, GFP_KERNEL); - if (!out) - goto done; - - out += HDRLEN_KMALLOC; - container_of(out, struct ipc_rcu_hdr, data)->is_vmalloc = 0; + out = (len > PAGE_SIZE) ? vmalloc(len) : kmalloc(len, GFP_KERNEL); + if (out) { + out += HDRLEN; - container_of(out, struct ipc_rcu_hdr, data)->refcount = 1; ++ atomic_set(&container_of(out, struct ipc_rcu_hdr, data)->refcount, 1); } return out; } - void ipc_rcu_getref(void *ptr) + int ipc_rcu_getref(void *ptr) { - container_of(ptr, struct ipc_rcu_hdr, data)->refcount++; + return atomic_inc_not_zero(&container_of(ptr, struct ipc_rcu_hdr, data)->refcount); } -static void ipc_do_vfree(struct work_struct *work) -{ - vfree(container_of(work, struct ipc_rcu_sched, work)); -} - /** * ipc_schedule_free - free ipc + rcu space * @head: RCU callback structure for queued work @@@ -534,10 -580,10 +532,10 @@@ static void ipc_schedule_free(struct rc void ipc_rcu_putref(void *ptr) { - if (--container_of(ptr, struct ipc_rcu_hdr, data)->refcount > 0) + if (!atomic_dec_and_test(&container_of(ptr, struct ipc_rcu_hdr, data)->refcount)) return; - if (container_of(ptr, struct ipc_rcu_hdr, data)->is_vmalloc) { + if (is_vmalloc_addr(ptr)) { call_rcu(&container_of(ptr, struct ipc_rcu_grace, data)->rcu, ipc_schedule_free); } else {