diff options
author | Davidlohr Bueso <dave@stgolabs.net> | 2017-11-17 18:31:08 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-17 19:10:04 -0500 |
commit | b8fd99838435f9b420c3e848192bd43abc648b7f (patch) | |
tree | 793a6390f29e27fcd9b87ba8b65c2480627491af /ipc | |
parent | e35c4c64fe492b212f9c7d9e046626e48e89f863 (diff) |
sysvipc: unteach ids->next_id for !CHECKPOINT_RESTORE
Patch series "sysvipc: ipc-key management improvements".
Here are a few improvements I spotted while eyeballing Guillaume's
rhashtable implementation for ipc keys. The first and fourth patches
are the interesting ones, the middle two are trivial.
This patch (of 4):
The next_id object-allocation functionality was introduced in commit
03f595668017 ("ipc: add sysctl to specify desired next object id").
Given that these new entries are _only_ exported under the
CONFIG_CHECKPOINT_RESTORE option, there is no point for the common case
to even know about ->next_id. As such rewrite ipc_buildid() such that
it can do away with the field as well as unnecessary branches when
adding a new identifier. The end result also better differentiates both
cases, so the code ends up being cleaner; albeit the small duplications
regarding the default case.
[akpm@linux-foundation.org: coding-style fixes]
Link: http://lkml.kernel.org/r/20170831172049.14576-2-dave@stgolabs.net
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/util.c | 60 | ||||
-rw-r--r-- | ipc/util.h | 5 |
2 files changed, 45 insertions, 20 deletions
diff --git a/ipc/util.c b/ipc/util.c index 79b30eee32cd..429c06bdb8ef 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -116,13 +116,15 @@ int ipc_init_ids(struct ipc_ids *ids) | |||
116 | int err; | 116 | int err; |
117 | ids->in_use = 0; | 117 | ids->in_use = 0; |
118 | ids->seq = 0; | 118 | ids->seq = 0; |
119 | ids->next_id = -1; | ||
120 | init_rwsem(&ids->rwsem); | 119 | init_rwsem(&ids->rwsem); |
121 | err = rhashtable_init(&ids->key_ht, &ipc_kht_params); | 120 | err = rhashtable_init(&ids->key_ht, &ipc_kht_params); |
122 | if (err) | 121 | if (err) |
123 | return err; | 122 | return err; |
124 | idr_init(&ids->ipcs_idr); | 123 | idr_init(&ids->ipcs_idr); |
125 | ids->tables_initialized = true; | 124 | ids->tables_initialized = true; |
125 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
126 | ids->next_id = -1; | ||
127 | #endif | ||
126 | return 0; | 128 | return 0; |
127 | } | 129 | } |
128 | 130 | ||
@@ -216,6 +218,46 @@ int ipc_get_maxid(struct ipc_ids *ids) | |||
216 | return max_id; | 218 | return max_id; |
217 | } | 219 | } |
218 | 220 | ||
221 | #ifdef CONFIG_CHECKPOINT_RESTORE | ||
222 | /* | ||
223 | * Specify desired id for next allocated IPC object. | ||
224 | */ | ||
225 | #define ipc_idr_alloc(ids, new) \ | ||
226 | idr_alloc(&(ids)->ipcs_idr, (new), \ | ||
227 | (ids)->next_id < 0 ? 0 : ipcid_to_idx((ids)->next_id),\ | ||
228 | 0, GFP_NOWAIT) | ||
229 | |||
230 | static inline int ipc_buildid(int id, struct ipc_ids *ids, | ||
231 | struct kern_ipc_perm *new) | ||
232 | { | ||
233 | if (ids->next_id < 0) { /* default, behave as !CHECKPOINT_RESTORE */ | ||
234 | new->seq = ids->seq++; | ||
235 | if (ids->seq > IPCID_SEQ_MAX) | ||
236 | ids->seq = 0; | ||
237 | } else { | ||
238 | new->seq = ipcid_to_seqx(ids->next_id); | ||
239 | ids->next_id = -1; | ||
240 | } | ||
241 | |||
242 | return SEQ_MULTIPLIER * new->seq + id; | ||
243 | } | ||
244 | |||
245 | #else | ||
246 | #define ipc_idr_alloc(ids, new) \ | ||
247 | idr_alloc(&(ids)->ipcs_idr, (new), 0, 0, GFP_NOWAIT) | ||
248 | |||
249 | static inline int ipc_buildid(int id, struct ipc_ids *ids, | ||
250 | struct kern_ipc_perm *new) | ||
251 | { | ||
252 | new->seq = ids->seq++; | ||
253 | if (ids->seq > IPCID_SEQ_MAX) | ||
254 | ids->seq = 0; | ||
255 | |||
256 | return SEQ_MULTIPLIER * new->seq + id; | ||
257 | } | ||
258 | |||
259 | #endif /* CONFIG_CHECKPOINT_RESTORE */ | ||
260 | |||
219 | /** | 261 | /** |
220 | * ipc_addid - add an ipc identifier | 262 | * ipc_addid - add an ipc identifier |
221 | * @ids: ipc identifier set | 263 | * @ids: ipc identifier set |
@@ -234,7 +276,6 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) | |||
234 | kuid_t euid; | 276 | kuid_t euid; |
235 | kgid_t egid; | 277 | kgid_t egid; |
236 | int id, err; | 278 | int id, err; |
237 | int next_id = ids->next_id; | ||
238 | 279 | ||
239 | if (size > IPCMNI) | 280 | if (size > IPCMNI) |
240 | size = IPCMNI; | 281 | size = IPCMNI; |
@@ -254,9 +295,7 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) | |||
254 | new->cuid = new->uid = euid; | 295 | new->cuid = new->uid = euid; |
255 | new->gid = new->cgid = egid; | 296 | new->gid = new->cgid = egid; |
256 | 297 | ||
257 | id = idr_alloc(&ids->ipcs_idr, new, | 298 | id = ipc_idr_alloc(ids, new); |
258 | (next_id < 0) ? 0 : ipcid_to_idx(next_id), 0, | ||
259 | GFP_NOWAIT); | ||
260 | idr_preload_end(); | 299 | idr_preload_end(); |
261 | 300 | ||
262 | if (id >= 0 && new->key != IPC_PRIVATE) { | 301 | if (id >= 0 && new->key != IPC_PRIVATE) { |
@@ -274,17 +313,8 @@ int ipc_addid(struct ipc_ids *ids, struct kern_ipc_perm *new, int size) | |||
274 | } | 313 | } |
275 | 314 | ||
276 | ids->in_use++; | 315 | ids->in_use++; |
316 | new->id = ipc_buildid(id, ids, new); | ||
277 | 317 | ||
278 | if (next_id < 0) { | ||
279 | new->seq = ids->seq++; | ||
280 | if (ids->seq > IPCID_SEQ_MAX) | ||
281 | ids->seq = 0; | ||
282 | } else { | ||
283 | new->seq = ipcid_to_seqx(next_id); | ||
284 | ids->next_id = -1; | ||
285 | } | ||
286 | |||
287 | new->id = ipc_buildid(id, new->seq); | ||
288 | return id; | 318 | return id; |
289 | } | 319 | } |
290 | 320 | ||
diff --git a/ipc/util.h b/ipc/util.h index 579112d90016..0cd6201fe63a 100644 --- a/ipc/util.h +++ b/ipc/util.h | |||
@@ -146,11 +146,6 @@ extern struct msg_msg *load_msg(const void __user *src, size_t len); | |||
146 | extern struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst); | 146 | extern struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst); |
147 | extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len); | 147 | extern int store_msg(void __user *dest, struct msg_msg *msg, size_t len); |
148 | 148 | ||
149 | static inline int ipc_buildid(int id, int seq) | ||
150 | { | ||
151 | return SEQ_MULTIPLIER * seq + id; | ||
152 | } | ||
153 | |||
154 | static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid) | 149 | static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid) |
155 | { | 150 | { |
156 | return uid / SEQ_MULTIPLIER != ipcp->seq; | 151 | return uid / SEQ_MULTIPLIER != ipcp->seq; |