diff options
author | Manfred Spraul <manfred@colorfullife.com> | 2017-07-12 17:34:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-07-12 19:26:01 -0400 |
commit | dba4cdd39e698d8dcdad0656825423052ac90ccd (patch) | |
tree | 908f984f4652a42f603aac8f2db4edd059d11256 /ipc/shm.c | |
parent | 1a23395672658969a4035dcc518ea6cab835c579 (diff) |
ipc: merge ipc_rcu and kern_ipc_perm
ipc has two management structures that exist for every id:
- struct kern_ipc_perm, it contains e.g. the permissions.
- struct ipc_rcu, it contains the rcu head for rcu handling and the
refcount.
The patch merges both structures.
As a bonus, we may save one cacheline, because both structures are
cacheline aligned. In addition, it reduces the number of casts, instead
most codepaths can use container_of.
To simplify code, the ipc_rcu_alloc initializes the allocation to 0.
[manfred@colorfullife.com: really include the memset() into ipc_alloc_rcu()]
Link: http://lkml.kernel.org/r/564f8612-0601-b267-514f-a9f650ec9b32@colorfullife.com
Link: http://lkml.kernel.org/r/20170525185107.12869-3-manfred@colorfullife.com
Signed-off-by: Manfred Spraul <manfred@colorfullife.com>
Cc: Davidlohr Bueso <dave@stgolabs.net>
Cc: Kees Cook <keescook@chromium.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/shm.c')
-rw-r--r-- | ipc/shm.c | 18 |
1 files changed, 11 insertions, 7 deletions
@@ -174,9 +174,10 @@ static inline void shm_lock_by_ptr(struct shmid_kernel *ipcp) | |||
174 | 174 | ||
175 | static void shm_rcu_free(struct rcu_head *head) | 175 | static void shm_rcu_free(struct rcu_head *head) |
176 | { | 176 | { |
177 | struct ipc_rcu *p = container_of(head, struct ipc_rcu, rcu); | 177 | struct kern_ipc_perm *ptr = container_of(head, struct kern_ipc_perm, |
178 | struct shmid_kernel *shp = ipc_rcu_to_struct(p); | 178 | rcu); |
179 | 179 | struct shmid_kernel *shp = container_of(ptr, struct shmid_kernel, | |
180 | shm_perm); | ||
180 | security_shm_free(shp); | 181 | security_shm_free(shp); |
181 | ipc_rcu_free(head); | 182 | ipc_rcu_free(head); |
182 | } | 183 | } |
@@ -241,7 +242,7 @@ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) | |||
241 | user_shm_unlock(i_size_read(file_inode(shm_file)), | 242 | user_shm_unlock(i_size_read(file_inode(shm_file)), |
242 | shp->mlock_user); | 243 | shp->mlock_user); |
243 | fput(shm_file); | 244 | fput(shm_file); |
244 | ipc_rcu_putref(shp, shm_rcu_free); | 245 | ipc_rcu_putref(&shp->shm_perm, shm_rcu_free); |
245 | } | 246 | } |
246 | 247 | ||
247 | /* | 248 | /* |
@@ -542,7 +543,10 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | |||
542 | ns->shm_tot + numpages > ns->shm_ctlall) | 543 | ns->shm_tot + numpages > ns->shm_ctlall) |
543 | return -ENOSPC; | 544 | return -ENOSPC; |
544 | 545 | ||
545 | shp = ipc_rcu_alloc(sizeof(*shp)); | 546 | BUILD_BUG_ON(offsetof(struct shmid_kernel, shm_perm) != 0); |
547 | |||
548 | shp = container_of(ipc_rcu_alloc(sizeof(*shp)), struct shmid_kernel, | ||
549 | shm_perm); | ||
546 | if (!shp) | 550 | if (!shp) |
547 | return -ENOMEM; | 551 | return -ENOMEM; |
548 | 552 | ||
@@ -553,7 +557,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) | |||
553 | shp->shm_perm.security = NULL; | 557 | shp->shm_perm.security = NULL; |
554 | error = security_shm_alloc(shp); | 558 | error = security_shm_alloc(shp); |
555 | if (error) { | 559 | if (error) { |
556 | ipc_rcu_putref(shp, ipc_rcu_free); | 560 | ipc_rcu_putref(&shp->shm_perm, ipc_rcu_free); |
557 | return error; | 561 | return error; |
558 | } | 562 | } |
559 | 563 | ||
@@ -624,7 +628,7 @@ no_id: | |||
624 | user_shm_unlock(size, shp->mlock_user); | 628 | user_shm_unlock(size, shp->mlock_user); |
625 | fput(file); | 629 | fput(file); |
626 | no_file: | 630 | no_file: |
627 | ipc_rcu_putref(shp, shm_rcu_free); | 631 | ipc_rcu_putref(&shp->shm_perm, shm_rcu_free); |
628 | return error; | 632 | return error; |
629 | } | 633 | } |
630 | 634 | ||