Skip to content

Commit 03f5956

Browse files
Stanislav Kinsburskytorvalds
authored andcommitted
ipc: add sysctl to specify desired next object id
Add 3 new variables and sysctls to tune them (by one "next_id" variable for messages, semaphores and shared memory respectively). This variable can be used to set desired id for next allocated IPC object. By default it's equal to -1 and old behaviour is preserved. If this variable is non-negative, then desired idr will be extracted from it and used as a start value to search for free IDR slot. Notes: 1) this patch doesn't guarantee that the new object will have desired id. So it's up to user space how to handle new object with wrong id. 2) After a sucessful id allocation attempt, "next_id" will be set back to -1 (if it was non-negative). [[email protected]: checkpatch fixes] Signed-off-by: Stanislav Kinsbursky <[email protected]> Cc: Serge Hallyn <[email protected]> Cc: "Eric W. Biederman" <[email protected]> Cc: Pavel Emelyanov <[email protected]> Cc: Al Viro <[email protected]> Cc: KOSAKI Motohiro <[email protected]> Cc: Michael Kerrisk <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 9afdacd commit 03f5956

File tree

5 files changed

+65
-4
lines changed

5 files changed

+65
-4
lines changed

Documentation/sysctl/kernel.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ show up in /proc/sys/kernel:
3838
- l2cr [ PPC only ]
3939
- modprobe ==> Documentation/debugging-modules.txt
4040
- modules_disabled
41+
- msg_next_id [ sysv ipc ]
4142
- msgmax
4243
- msgmnb
4344
- msgmni
@@ -62,7 +63,9 @@ show up in /proc/sys/kernel:
6263
- rtsig-max
6364
- rtsig-nr
6465
- sem
66+
- sem_next_id [ sysv ipc ]
6567
- sg-big-buff [ generic SCSI device (sg) ]
68+
- shm_next_id [ sysv ipc ]
6669
- shm_rmid_forced
6770
- shmall
6871
- shmmax [ sysv ipc ]
@@ -320,6 +323,22 @@ to false.
320323

321324
==============================================================
322325

326+
msg_next_id, sem_next_id, and shm_next_id:
327+
328+
These three toggles allows to specify desired id for next allocated IPC
329+
object: message, semaphore or shared memory respectively.
330+
331+
By default they are equal to -1, which means generic allocation logic.
332+
Possible values to set are in range {0..INT_MAX}.
333+
334+
Notes:
335+
1) kernel doesn't guarantee, that new object will have desired id. So,
336+
it's up to userspace, how to handle an object with "wrong" id.
337+
2) Toggle with non-default value will be set back to -1 by kernel after
338+
successful IPC object allocation.
339+
340+
==============================================================
341+
323342
nmi_watchdog:
324343

325344
Enables/Disables the NMI watchdog on x86 systems. When the value is

include/linux/ipc_namespace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct ipc_ids {
2424
unsigned short seq_max;
2525
struct rw_semaphore rw_mutex;
2626
struct idr ipcs_idr;
27+
int next_id;
2728
};
2829

2930
struct ipc_namespace {

ipc/ipc_sysctl.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,9 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
158158

159159
static int zero;
160160
static int one = 1;
161+
#ifdef CONFIG_CHECKPOINT_RESTORE
162+
static int int_max = INT_MAX;
163+
#endif
161164

162165
static struct ctl_table ipc_kern_table[] = {
163166
{
@@ -227,6 +230,35 @@ static struct ctl_table ipc_kern_table[] = {
227230
.extra1 = &zero,
228231
.extra2 = &one,
229232
},
233+
#ifdef CONFIG_CHECKPOINT_RESTORE
234+
{
235+
.procname = "sem_next_id",
236+
.data = &init_ipc_ns.ids[IPC_SEM_IDS].next_id,
237+
.maxlen = sizeof(init_ipc_ns.ids[IPC_SEM_IDS].next_id),
238+
.mode = 0644,
239+
.proc_handler = proc_ipc_dointvec_minmax,
240+
.extra1 = &zero,
241+
.extra2 = &int_max,
242+
},
243+
{
244+
.procname = "msg_next_id",
245+
.data = &init_ipc_ns.ids[IPC_MSG_IDS].next_id,
246+
.maxlen = sizeof(init_ipc_ns.ids[IPC_MSG_IDS].next_id),
247+
.mode = 0644,
248+
.proc_handler = proc_ipc_dointvec_minmax,
249+
.extra1 = &zero,
250+
.extra2 = &int_max,
251+
},
252+
{
253+
.procname = "shm_next_id",
254+
.data = &init_ipc_ns.ids[IPC_SHM_IDS].next_id,
255+
.maxlen = sizeof(init_ipc_ns.ids[IPC_SHM_IDS].next_id),
256+
.mode = 0644,
257+
.proc_handler = proc_ipc_dointvec_minmax,
258+
.extra1 = &zero,
259+
.extra2 = &int_max,
260+
},
261+
#endif
230262
{}
231263
};
232264

ipc/util.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ void ipc_init_ids(struct ipc_ids *ids)
122122

123123
ids->in_use = 0;
124124
ids->seq = 0;
125+
ids->next_id = -1;
125126
{
126127
int seq_limit = INT_MAX/SEQ_MULTIPLIER;
127128
if (seq_limit > USHRT_MAX)
@@ -252,6 +253,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
252253
kuid_t euid;
253254
kgid_t egid;
254255
int id, err;
256+
int next_id = ids->next_id;
255257

256258
if (size > IPCMNI)
257259
size = IPCMNI;
@@ -264,7 +266,8 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
264266
rcu_read_lock();
265267
spin_lock(&new->lock);
266268

267-
err = idr_get_new(&ids->ipcs_idr, new, &id);
269+
err = idr_get_new_above(&ids->ipcs_idr, new,
270+
(next_id < 0) ? 0 : ipcid_to_idx(next_id), &id);
268271
if (err) {
269272
spin_unlock(&new->lock);
270273
rcu_read_unlock();
@@ -277,9 +280,14 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
277280
new->cuid = new->uid = euid;
278281
new->gid = new->cgid = egid;
279282

280-
new->seq = ids->seq++;
281-
if(ids->seq > ids->seq_max)
282-
ids->seq = 0;
283+
if (next_id < 0) {
284+
new->seq = ids->seq++;
285+
if (ids->seq > ids->seq_max)
286+
ids->seq = 0;
287+
} else {
288+
new->seq = ipcid_to_seqx(next_id);
289+
ids->next_id = -1;
290+
}
283291

284292
new->id = ipc_buildid(id, new->seq);
285293
return id;

ipc/util.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
9292
#define IPC_SHM_IDS 2
9393

9494
#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
95+
#define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER)
9596

9697
/* must be called with ids->rw_mutex acquired for writing */
9798
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);

0 commit comments

Comments
 (0)