summaryrefslogtreecommitdiff
path: root/ipc/util.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-14 20:13:19 +0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-02-14 20:13:19 +0400
commitf2e5d078f7f02d4289db31f5f63e23e39914075e (patch)
treec739a3e70846284ae2ce3d98cecc2be1ffebe2e2 /ipc/util.c
parentc66a566afbe6e2c94b1ae70f70cc1e3d4c73639b (diff)
parent836dc9e3fbbab0c30aa6e664417225f5c1fb1c39 (diff)
downloadlinux-f2e5d078f7f02d4289db31f5f63e23e39914075e.tar.xz
Merge tag 'v3.8-rc7' into regulator-core
Linux 3.8-rc7
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/ipc/util.c b/ipc/util.c
index 72fd0785ac94..74e1d9c7a98a 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -122,6 +122,7 @@ void ipc_init_ids(struct ipc_ids *ids)
ids->in_use = 0;
ids->seq = 0;
+ ids->next_id = -1;
{
int seq_limit = INT_MAX/SEQ_MULTIPLIER;
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;
kgid_t egid;
int id, err;
+ int next_id = ids->next_id;
if (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();
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) {
spin_unlock(&new->lock);
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->gid = new->cgid = egid;
- new->seq = ids->seq++;
- if(ids->seq > ids->seq_max)
- ids->seq = 0;
+ if (next_id < 0) {
+ new->seq = ids->seq++;
+ 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);
return id;