diff options
author | Michael Ellerman <mpe@ellerman.id.au> | 2017-07-31 20:20:29 +1000 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-07-31 20:20:29 +1000 |
commit | bb272221e9db79f13d454e1f3fb6b05013be985e (patch) | |
tree | 36f4acc50e3fabac71fadd34c720c0a6011db470 /ipc/util.c | |
parent | 253fd51e2f533552ae35a0c661705da6c4842c1b (diff) | |
parent | 5771a8c08880cdca3bfb4a3fc6d309d6bba20877 (diff) |
Merge tag 'v4.13-rc1' into fixes
The fixes branch is based off a random pre-rc1 commit, because we had
some fixes that needed to go in before rc1 was released.
However we now need to fix some code that went in after that point, but
before rc1, so merge rc1 to get that code into fixes so we can fix it!
Diffstat (limited to 'ipc/util.c')
-rw-r--r-- | ipc/util.c | 65 |
1 files changed, 7 insertions, 58 deletions
diff --git a/ipc/util.c b/ipc/util.c index caec7b1bfaa3..1a2cb02467ab 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -232,6 +232,7 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) idr_preload(GFP_KERNEL); + atomic_set(&new->refcount, 1); spin_lock_init(&new->lock); new->deleted = false; rcu_read_lock(); @@ -394,70 +395,18 @@ void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) ipcp->deleted = true; } -/** - * ipc_alloc - allocate ipc space - * @size: size desired - * - * Allocate memory from the appropriate pools and return a pointer to it. - * NULL is returned if the allocation fails - */ -void *ipc_alloc(int size) -{ - return kvmalloc(size, GFP_KERNEL); -} - -/** - * ipc_free - free ipc space - * @ptr: pointer returned by ipc_alloc - * - * Free a block created with ipc_alloc(). - */ -void ipc_free(void *ptr) +int ipc_rcu_getref(struct kern_ipc_perm *ptr) { - kvfree(ptr); + return atomic_inc_not_zero(&ptr->refcount); } -/** - * ipc_rcu_alloc - allocate ipc and rcu space - * @size: size desired - * - * Allocate memory for the rcu header structure + the object. - * Returns the pointer to the object or NULL upon failure. - */ -void *ipc_rcu_alloc(int size) +void ipc_rcu_putref(struct kern_ipc_perm *ptr, + void (*func)(struct rcu_head *head)) { - /* - * We prepend the allocation with the rcu struct - */ - struct ipc_rcu *out = ipc_alloc(sizeof(struct ipc_rcu) + size); - if (unlikely(!out)) - return NULL; - atomic_set(&out->refcount, 1); - return out + 1; -} - -int ipc_rcu_getref(void *ptr) -{ - struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1; - - return atomic_inc_not_zero(&p->refcount); -} - -void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head)) -{ - struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1; - - if (!atomic_dec_and_test(&p->refcount)) + if (!atomic_dec_and_test(&ptr->refcount)) return; - call_rcu(&p->rcu, func); -} - -void ipc_rcu_free(struct rcu_head *head) -{ - struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); - - kvfree(p); + call_rcu(&ptr->rcu, func); } /** |