mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-22 07:04:39 +00:00
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). [akpm@linux-foundation.org: checkpatch fixes] Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Cc: Serge Hallyn <serge.hallyn@canonical.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
9afdacda02
commit
03f5956680
5 changed files with 65 additions and 4 deletions
|
@ -38,6 +38,7 @@ show up in /proc/sys/kernel:
|
||||||
- l2cr [ PPC only ]
|
- l2cr [ PPC only ]
|
||||||
- modprobe ==> Documentation/debugging-modules.txt
|
- modprobe ==> Documentation/debugging-modules.txt
|
||||||
- modules_disabled
|
- modules_disabled
|
||||||
|
- msg_next_id [ sysv ipc ]
|
||||||
- msgmax
|
- msgmax
|
||||||
- msgmnb
|
- msgmnb
|
||||||
- msgmni
|
- msgmni
|
||||||
|
@ -62,7 +63,9 @@ show up in /proc/sys/kernel:
|
||||||
- rtsig-max
|
- rtsig-max
|
||||||
- rtsig-nr
|
- rtsig-nr
|
||||||
- sem
|
- sem
|
||||||
|
- sem_next_id [ sysv ipc ]
|
||||||
- sg-big-buff [ generic SCSI device (sg) ]
|
- sg-big-buff [ generic SCSI device (sg) ]
|
||||||
|
- shm_next_id [ sysv ipc ]
|
||||||
- shm_rmid_forced
|
- shm_rmid_forced
|
||||||
- shmall
|
- shmall
|
||||||
- shmmax [ sysv ipc ]
|
- shmmax [ sysv ipc ]
|
||||||
|
@ -320,6 +323,22 @@ to false.
|
||||||
|
|
||||||
==============================================================
|
==============================================================
|
||||||
|
|
||||||
|
msg_next_id, sem_next_id, and shm_next_id:
|
||||||
|
|
||||||
|
These three toggles allows to specify desired id for next allocated IPC
|
||||||
|
object: message, semaphore or shared memory respectively.
|
||||||
|
|
||||||
|
By default they are equal to -1, which means generic allocation logic.
|
||||||
|
Possible values to set are in range {0..INT_MAX}.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
1) kernel doesn't guarantee, that new object will have desired id. So,
|
||||||
|
it's up to userspace, how to handle an object with "wrong" id.
|
||||||
|
2) Toggle with non-default value will be set back to -1 by kernel after
|
||||||
|
successful IPC object allocation.
|
||||||
|
|
||||||
|
==============================================================
|
||||||
|
|
||||||
nmi_watchdog:
|
nmi_watchdog:
|
||||||
|
|
||||||
Enables/Disables the NMI watchdog on x86 systems. When the value is
|
Enables/Disables the NMI watchdog on x86 systems. When the value is
|
||||||
|
|
|
@ -24,6 +24,7 @@ struct ipc_ids {
|
||||||
unsigned short seq_max;
|
unsigned short seq_max;
|
||||||
struct rw_semaphore rw_mutex;
|
struct rw_semaphore rw_mutex;
|
||||||
struct idr ipcs_idr;
|
struct idr ipcs_idr;
|
||||||
|
int next_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ipc_namespace {
|
struct ipc_namespace {
|
||||||
|
|
|
@ -158,6 +158,9 @@ static int proc_ipcauto_dointvec_minmax(ctl_table *table, int write,
|
||||||
|
|
||||||
static int zero;
|
static int zero;
|
||||||
static int one = 1;
|
static int one = 1;
|
||||||
|
#ifdef CONFIG_CHECKPOINT_RESTORE
|
||||||
|
static int int_max = INT_MAX;
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct ctl_table ipc_kern_table[] = {
|
static struct ctl_table ipc_kern_table[] = {
|
||||||
{
|
{
|
||||||
|
@ -227,6 +230,35 @@ static struct ctl_table ipc_kern_table[] = {
|
||||||
.extra1 = &zero,
|
.extra1 = &zero,
|
||||||
.extra2 = &one,
|
.extra2 = &one,
|
||||||
},
|
},
|
||||||
|
#ifdef CONFIG_CHECKPOINT_RESTORE
|
||||||
|
{
|
||||||
|
.procname = "sem_next_id",
|
||||||
|
.data = &init_ipc_ns.ids[IPC_SEM_IDS].next_id,
|
||||||
|
.maxlen = sizeof(init_ipc_ns.ids[IPC_SEM_IDS].next_id),
|
||||||
|
.mode = 0644,
|
||||||
|
.proc_handler = proc_ipc_dointvec_minmax,
|
||||||
|
.extra1 = &zero,
|
||||||
|
.extra2 = &int_max,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.procname = "msg_next_id",
|
||||||
|
.data = &init_ipc_ns.ids[IPC_MSG_IDS].next_id,
|
||||||
|
.maxlen = sizeof(init_ipc_ns.ids[IPC_MSG_IDS].next_id),
|
||||||
|
.mode = 0644,
|
||||||
|
.proc_handler = proc_ipc_dointvec_minmax,
|
||||||
|
.extra1 = &zero,
|
||||||
|
.extra2 = &int_max,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.procname = "shm_next_id",
|
||||||
|
.data = &init_ipc_ns.ids[IPC_SHM_IDS].next_id,
|
||||||
|
.maxlen = sizeof(init_ipc_ns.ids[IPC_SHM_IDS].next_id),
|
||||||
|
.mode = 0644,
|
||||||
|
.proc_handler = proc_ipc_dointvec_minmax,
|
||||||
|
.extra1 = &zero,
|
||||||
|
.extra2 = &int_max,
|
||||||
|
},
|
||||||
|
#endif
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
16
ipc/util.c
16
ipc/util.c
|
@ -122,6 +122,7 @@ void ipc_init_ids(struct ipc_ids *ids)
|
||||||
|
|
||||||
ids->in_use = 0;
|
ids->in_use = 0;
|
||||||
ids->seq = 0;
|
ids->seq = 0;
|
||||||
|
ids->next_id = -1;
|
||||||
{
|
{
|
||||||
int seq_limit = INT_MAX/SEQ_MULTIPLIER;
|
int seq_limit = INT_MAX/SEQ_MULTIPLIER;
|
||||||
if (seq_limit > USHRT_MAX)
|
if (seq_limit > USHRT_MAX)
|
||||||
|
@ -252,6 +253,7 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
||||||
kuid_t euid;
|
kuid_t euid;
|
||||||
kgid_t egid;
|
kgid_t egid;
|
||||||
int id, err;
|
int id, err;
|
||||||
|
int next_id = ids->next_id;
|
||||||
|
|
||||||
if (size > IPCMNI)
|
if (size > IPCMNI)
|
||||||
size = IPCMNI;
|
size = IPCMNI;
|
||||||
|
@ -264,7 +266,8 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
spin_lock(&new->lock);
|
spin_lock(&new->lock);
|
||||||
|
|
||||||
err = idr_get_new(&ids->ipcs_idr, new, &id);
|
err = idr_get_new_above(&ids->ipcs_idr, new,
|
||||||
|
(next_id < 0) ? 0 : ipcid_to_idx(next_id), &id);
|
||||||
if (err) {
|
if (err) {
|
||||||
spin_unlock(&new->lock);
|
spin_unlock(&new->lock);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
@ -277,9 +280,14 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
||||||
new->cuid = new->uid = euid;
|
new->cuid = new->uid = euid;
|
||||||
new->gid = new->cgid = egid;
|
new->gid = new->cgid = egid;
|
||||||
|
|
||||||
new->seq = ids->seq++;
|
if (next_id < 0) {
|
||||||
if(ids->seq > ids->seq_max)
|
new->seq = ids->seq++;
|
||||||
ids->seq = 0;
|
if (ids->seq > ids->seq_max)
|
||||||
|
ids->seq = 0;
|
||||||
|
} else {
|
||||||
|
new->seq = ipcid_to_seqx(next_id);
|
||||||
|
ids->next_id = -1;
|
||||||
|
}
|
||||||
|
|
||||||
new->id = ipc_buildid(id, new->seq);
|
new->id = ipc_buildid(id, new->seq);
|
||||||
return id;
|
return id;
|
||||||
|
|
|
@ -92,6 +92,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
|
||||||
#define IPC_SHM_IDS 2
|
#define IPC_SHM_IDS 2
|
||||||
|
|
||||||
#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
|
#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER)
|
||||||
|
#define ipcid_to_seqx(id) ((id) / SEQ_MULTIPLIER)
|
||||||
|
|
||||||
/* must be called with ids->rw_mutex acquired for writing */
|
/* must be called with ids->rw_mutex acquired for writing */
|
||||||
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
|
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
|
||||||
|
|
Loading…
Add table
Reference in a new issue