* [PATCH 00/11] sysv ipc shared mem optimizations
@ 2013-06-19 1:18 Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 01/11] ipc,shm: introduce lockless functions to obtain the ipc object Davidlohr Bueso
` (10 more replies)
0 siblings, 11 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
This is the third and final patchset that deals with reducing the
amount of contention we impose on the ipc lock (kern_ipc_perm.lock).
These changes mostly deal with shared memory, previous work has already
been done for semaphores and message queues:
http://lkml.org/lkml/2013/3/20/546 (sems)
http://lkml.org/lkml/2013/5/15/584 (mqueues)
With these patches applied, a custom shm microbenchmark stressing shmctl
doing IPC_STAT with 4 threads a million times, reduces the execution time by 50%.
A similar run, this time with IPC_SET, reduces the execution time from 3 mins and
35 secs to 27 seconds.
Patches 1-8: replaces blindly taking the ipc lock for a smarter combination
of rcu and ipc_obtain_object, only acquiring the spinlock when updating.
Patch 9: renames the ids rw_mutex to rwsem, which is what it already was.
Patch 10: is a trivial mqueue leftover cleanup
Patch 11: adds a brief lock scheme description, requested by Andrew.
This patchset applies on top of linux-next (3.10.0-rc6-next-20130618).
Davidlohr Bueso (11):
ipc,shm: introduce lockless functions to obtain the ipc object
ipc,shm: shorten critical region in shmctl_down
ipc: drop ipcctl_pre_down
ipc,shm: introduce shmctl_nolock
ipc,shm: make shmctl_nolock lockless
ipc,shm: shorten critical region for shmctl
ipc,shm: cleanup do_shmat pasta
ipc,shm: shorten critical region for shmat
ipc: rename ids->rw_mutex
ipc,msg: drop msg_unlock
ipc: document general ipc locking scheme
include/linux/ipc_namespace.h | 2 +-
ipc/msg.c | 25 +++--
ipc/namespace.c | 4 +-
ipc/sem.c | 24 ++---
ipc/shm.c | 239 ++++++++++++++++++++++++++----------------
ipc/util.c | 57 +++++-----
ipc/util.h | 7 +-
7 files changed, 199 insertions(+), 159 deletions(-)
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/11] ipc,shm: introduce lockless functions to obtain the ipc object
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 02/11] ipc,shm: shorten critical region in shmctl_down Davidlohr Bueso
` (9 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
Add shm_obtain_object() and shm_obtain_object_check(), which will allow us
to get the ipc object without acquiring the lock. Just as with other forms
of ipc, these functions are basically wrappers around ipc_obtain_object*().
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/shm.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/ipc/shm.c b/ipc/shm.c
index c6b4ad5..216ae72 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -124,6 +124,26 @@ void __init shm_init (void)
IPC_SHM_IDS, sysvipc_shm_proc_show);
}
+static inline struct shmid_kernel *shm_obtain_object(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_obtain_object(&shm_ids(ns), id);
+
+ if (IS_ERR(ipcp))
+ return ERR_CAST(ipcp);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&shm_ids(ns), id);
+
+ if (IS_ERR(ipcp))
+ return ERR_CAST(ipcp);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
/*
* shm_lock_(check_) routines are called in the paths where the rw_mutex
* is not necessarily held.
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 02/11] ipc,shm: shorten critical region in shmctl_down
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 01/11] ipc,shm: introduce lockless functions to obtain the ipc object Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 03/11] ipc: drop ipcctl_pre_down Davidlohr Bueso
` (8 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
Instead of holding the ipc lock for the entire function, use the
ipcctl_pre_down_nolock and only acquire the lock for specific commands:
RMID and SET.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/shm.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index 216ae72..22cffd7 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -780,11 +780,10 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
down_write(&shm_ids(ns).rw_mutex);
rcu_read_lock();
- ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd,
- &shmid64.shm_perm, 0);
+ ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
+ &shmid64.shm_perm, 0);
if (IS_ERR(ipcp)) {
err = PTR_ERR(ipcp);
- /* the ipc lock is not held upon failure */
goto out_unlock1;
}
@@ -792,14 +791,16 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
err = security_shm_shmctl(shp, cmd);
if (err)
- goto out_unlock0;
+ goto out_unlock1;
switch (cmd) {
case IPC_RMID:
+ ipc_lock_object(&shp->shm_perm);
/* do_shm_rmid unlocks the ipc object and rcu */
do_shm_rmid(ns, ipcp);
goto out_up;
case IPC_SET:
+ ipc_lock_object(&shp->shm_perm);
err = ipc_update_perm(&shmid64.shm_perm, ipcp);
if (err)
goto out_unlock0;
@@ -807,6 +808,7 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
break;
default:
err = -EINVAL;
+ goto out_unlock1;
}
out_unlock0:
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 03/11] ipc: drop ipcctl_pre_down
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 01/11] ipc,shm: introduce lockless functions to obtain the ipc object Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 02/11] ipc,shm: shorten critical region in shmctl_down Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-07-16 22:49 ` Andrew Morton
2013-06-19 1:18 ` [PATCH 04/11] ipc,shm: introduce shmctl_nolock Davidlohr Bueso
` (7 subsequent siblings)
10 siblings, 1 reply; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
Now that sem, msgque and shm, through *_down(), all use the lockless
variant of ipcctl_pre_down(), go ahead and delete it.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/util.c | 21 ++-------------------
ipc/util.h | 3 ---
2 files changed, 2 insertions(+), 22 deletions(-)
diff --git a/ipc/util.c b/ipc/util.c
index a0c139f..1893667 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -746,26 +746,10 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
* It must be called without any lock held and
* - retrieves the ipc with the given id in the given table.
* - performs some audit and permission check, depending on the given cmd
- * - returns the ipc with the ipc lock held in case of success
- * or an err-code without any lock held otherwise.
+ * - returns a pointer to the ipc object or otherwise, the corresponding error.
*
* Call holding the both the rw_mutex and the rcu read lock.
*/
-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm)
-{
- struct kern_ipc_perm *ipcp;
-
- ipcp = ipcctl_pre_down_nolock(ns, ids, id, cmd, perm, extra_perm);
- if (IS_ERR(ipcp))
- goto out;
-
- spin_lock(&ipcp->lock);
-out:
- return ipcp;
-}
-
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
struct ipc64_perm *perm, int extra_perm)
@@ -782,8 +766,7 @@ struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
audit_ipc_obj(ipcp);
if (cmd == IPC_SET)
- audit_ipc_set_perm(extra_perm, perm->uid,
- perm->gid, perm->mode);
+ audit_ipc_set_perm(extra_perm, perm->uid, perm->gid, perm->mode);
euid = current_euid();
if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) ||
diff --git a/ipc/util.h b/ipc/util.h
index b6a6a88..41a6c4d 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -131,9 +131,6 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out);
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
struct ipc64_perm *perm, int extra_perm);
-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm);
#ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
/* On IA-64, we always use the "64-bit version" of the IPC structures. */
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 04/11] ipc,shm: introduce shmctl_nolock
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
` (2 preceding siblings ...)
2013-06-19 1:18 ` [PATCH 03/11] ipc: drop ipcctl_pre_down Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 05/11] ipc,shm: make shmctl_nolock lockless Davidlohr Bueso
` (6 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
Similar to semctl and msgctl, when calling msgctl, the *_INFO and *_STAT commands
can be performed without acquiring the ipc object.
Add a shmctl_nolock() function and move the logic of *_INFO and *_STAT out of
msgctl(). Since we are just moving functionality, this change still takes the
lock and it will be properly lockless in the next patch.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/shm.c | 57 +++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 39 insertions(+), 18 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index 22cffd7..3e12398 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -820,29 +820,24 @@ out_up:
return err;
}
-SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
+ int cmd, int version, void __user *buf)
{
+ int err;
struct shmid_kernel *shp;
- int err, version;
- struct ipc_namespace *ns;
- if (cmd < 0 || shmid < 0) {
- err = -EINVAL;
- goto out;
+ /* preliminary security checks for *_INFO */
+ if (cmd == IPC_INFO || cmd == SHM_INFO) {
+ err = security_shm_shmctl(NULL, cmd);
+ if (err)
+ return err;
}
- version = ipc_parse_version(&cmd);
- ns = current->nsproxy->ipc_ns;
-
- switch (cmd) { /* replace with proc interface ? */
+ switch (cmd) {
case IPC_INFO:
{
struct shminfo64 shminfo;
- err = security_shm_shmctl(NULL, cmd);
- if (err)
- return err;
-
memset(&shminfo, 0, sizeof(shminfo));
shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
shminfo.shmmax = ns->shm_ctlmax;
@@ -864,10 +859,6 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
{
struct shm_info shm_info;
- err = security_shm_shmctl(NULL, cmd);
- if (err)
- return err;
-
memset(&shm_info, 0, sizeof(shm_info));
down_read(&shm_ids(ns).rw_mutex);
shm_info.used_ids = shm_ids(ns).in_use;
@@ -928,6 +919,36 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
err = result;
goto out;
}
+ default:
+ return -EINVAL;
+ }
+
+out_unlock:
+ shm_unlock(shp);
+out:
+ return err;
+}
+
+SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+{
+ struct shmid_kernel *shp;
+ int err, version;
+ struct ipc_namespace *ns;
+
+ if (cmd < 0 || shmid < 0) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ version = ipc_parse_version(&cmd);
+ ns = current->nsproxy->ipc_ns;
+
+ switch (cmd) {
+ case IPC_INFO:
+ case SHM_INFO:
+ case SHM_STAT:
+ case IPC_STAT:
+ return shmctl_nolock(ns, shmid, cmd, version, buf);
case SHM_LOCK:
case SHM_UNLOCK:
{
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 05/11] ipc,shm: make shmctl_nolock lockless
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
` (3 preceding siblings ...)
2013-06-19 1:18 ` [PATCH 04/11] ipc,shm: introduce shmctl_nolock Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 06/11] ipc,shm: shorten critical region for shmctl Davidlohr Bueso
` (5 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
While the INFO cmd doesn't take the ipc lock, the STAT commands do acquire
it unnecessarily. We can do the permissions and security checks only
holding the rcu lock.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/shm.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index 3e12398..43a8786 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -882,27 +882,31 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
struct shmid64_ds tbuf;
int result;
+ rcu_read_lock();
if (cmd == SHM_STAT) {
- shp = shm_lock(ns, shmid);
+ shp = shm_obtain_object(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
result = shp->shm_perm.id;
} else {
- shp = shm_lock_check(ns, shmid);
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
result = 0;
}
+
err = -EACCES;
if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
goto out_unlock;
+
err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock;
+
memset(&tbuf, 0, sizeof(tbuf));
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
tbuf.shm_segsz = shp->shm_segsz;
@@ -912,8 +916,9 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
tbuf.shm_cpid = shp->shm_cprid;
tbuf.shm_lpid = shp->shm_lprid;
tbuf.shm_nattch = shp->shm_nattch;
- shm_unlock(shp);
- if(copy_shmid_to_user (buf, &tbuf, version))
+ rcu_read_unlock();
+
+ if (copy_shmid_to_user (buf, &tbuf, version))
err = -EFAULT;
else
err = result;
@@ -924,7 +929,7 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
}
out_unlock:
- shm_unlock(shp);
+ rcu_read_unlock();
out:
return err;
}
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 06/11] ipc,shm: shorten critical region for shmctl
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
` (4 preceding siblings ...)
2013-06-19 1:18 ` [PATCH 05/11] ipc,shm: make shmctl_nolock lockless Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 07/11] ipc,shm: cleanup do_shmat pasta Davidlohr Bueso
` (4 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
With the *_INFO, *_STAT, IPC_RMID and IPC_SET commands already
optimized, deal with the remaining SHM_LOCK and SHM_UNLOCK
commands. Take the shm_perm lock after doing the initial
auditing and security checks. The rest of the logic remains
unchanged.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/shm.c | 49 +++++++++++++++++++++++++------------------------
1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index 43a8786..e4ac1c1 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -940,10 +940,8 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
int err, version;
struct ipc_namespace *ns;
- if (cmd < 0 || shmid < 0) {
- err = -EINVAL;
- goto out;
- }
+ if (cmd < 0 || shmid < 0)
+ return -EINVAL;
version = ipc_parse_version(&cmd);
ns = current->nsproxy->ipc_ns;
@@ -954,36 +952,40 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
case SHM_STAT:
case IPC_STAT:
return shmctl_nolock(ns, shmid, cmd, version, buf);
+ case IPC_RMID:
+ case IPC_SET:
+ return shmctl_down(ns, shmid, cmd, buf, version);
case SHM_LOCK:
case SHM_UNLOCK:
{
struct file *shm_file;
- shp = shm_lock_check(ns, shmid);
+ rcu_read_lock();
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock1;
}
audit_ipc_obj(&(shp->shm_perm));
+ err = security_shm_shmctl(shp, cmd);
+ if (err)
+ goto out_unlock1;
+ ipc_lock_object(&shp->shm_perm);
if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) {
kuid_t euid = current_euid();
err = -EPERM;
if (!uid_eq(euid, shp->shm_perm.uid) &&
!uid_eq(euid, shp->shm_perm.cuid))
- goto out_unlock;
+ goto out_unlock0;
if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK))
- goto out_unlock;
+ goto out_unlock0;
}
- err = security_shm_shmctl(shp, cmd);
- if (err)
- goto out_unlock;
-
shm_file = shp->shm_file;
if (is_file_hugepages(shm_file))
- goto out_unlock;
+ goto out_unlock0;
if (cmd == SHM_LOCK) {
struct user_struct *user = current_user();
@@ -992,32 +994,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
shp->shm_perm.mode |= SHM_LOCKED;
shp->mlock_user = user;
}
- goto out_unlock;
+ goto out_unlock0;
}
/* SHM_UNLOCK */
if (!(shp->shm_perm.mode & SHM_LOCKED))
- goto out_unlock;
+ goto out_unlock0;
shmem_lock(shm_file, 0, shp->mlock_user);
shp->shm_perm.mode &= ~SHM_LOCKED;
shp->mlock_user = NULL;
get_file(shm_file);
- shm_unlock(shp);
+ ipc_unlock_object(&shp->shm_perm);
+ rcu_read_unlock();
shmem_unlock_mapping(shm_file->f_mapping);
+
fput(shm_file);
- goto out;
- }
- case IPC_RMID:
- case IPC_SET:
- err = shmctl_down(ns, shmid, cmd, buf, version);
return err;
+ }
default:
return -EINVAL;
}
-out_unlock:
- shm_unlock(shp);
-out:
+out_unlock0:
+ ipc_unlock_object(&shp->shm_perm);
+out_unlock1:
+ rcu_read_unlock();
return err;
}
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 07/11] ipc,shm: cleanup do_shmat pasta
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
` (5 preceding siblings ...)
2013-06-19 1:18 ` [PATCH 06/11] ipc,shm: shorten critical region for shmctl Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 08/11] ipc,shm: shorten critical region for shmat Davidlohr Bueso
` (3 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
Clean up some of the messy do_shmat() spaghetti code, getting
rid of out_free and out_put_dentry labels. This makes shortening
the critical region of this function in the next patch a little
easier to do and read.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/shm.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index e4ac1c1..d1b3ebf 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -1108,16 +1108,21 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
err = -ENOMEM;
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
- if (!sfd)
- goto out_put_dentry;
+ if (!sfd) {
+ path_put(&path);
+ goto out_nattch;
+ }
file = alloc_file(&path, f_mode,
is_file_hugepages(shp->shm_file) ?
&shm_file_operations_huge :
&shm_file_operations);
err = PTR_ERR(file);
- if (IS_ERR(file))
- goto out_free;
+ if (IS_ERR(file)) {
+ kfree(sfd);
+ path_put(&path);
+ goto out_nattch;
+ }
file->private_data = sfd;
file->f_mapping = shp->shm_file->f_mapping;
@@ -1143,7 +1148,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
addr > current->mm->start_stack - size - PAGE_SIZE * 5)
goto invalid;
}
-
+
addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate);
*raddr = addr;
err = 0;
@@ -1167,19 +1172,12 @@ out_nattch:
else
shm_unlock(shp);
up_write(&shm_ids(ns).rw_mutex);
-
-out:
return err;
out_unlock:
shm_unlock(shp);
- goto out;
-
-out_free:
- kfree(sfd);
-out_put_dentry:
- path_put(&path);
- goto out_nattch;
+out:
+ return err;
}
SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 08/11] ipc,shm: shorten critical region for shmat
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
` (6 preceding siblings ...)
2013-06-19 1:18 ` [PATCH 07/11] ipc,shm: cleanup do_shmat pasta Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 09/11] ipc: rename ids->rw_mutex Davidlohr Bueso
` (2 subsequent siblings)
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
Similar to other system calls, acquire the kern_ipc_perm lock
after doing the initial permission and security checks.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/shm.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index d1b3ebf..2fe6170 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -19,6 +19,9 @@
* namespaces support
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
+ *
+ * Better ipc lock (kern_ipc_perm.lock) handling
+ * Davidlohr Bueso <davidlohr.bueso@hp.com>, June 2013.
*/
#include <linux/slab.h>
@@ -1086,7 +1089,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
* additional creator id...
*/
ns = current->nsproxy->ipc_ns;
- shp = shm_lock_check(ns, shmid);
+ rcu_read_lock();
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
goto out;
@@ -1100,11 +1104,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
if (err)
goto out_unlock;
+ ipc_lock_object(&shp->shm_perm);
path = shp->shm_file->f_path;
path_get(&path);
shp->shm_nattch++;
size = i_size_read(path.dentry->d_inode);
- shm_unlock(shp);
+ ipc_unlock_object(&shp->shm_perm);
+ rcu_read_unlock();
err = -ENOMEM;
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
@@ -1175,7 +1181,7 @@ out_nattch:
return err;
out_unlock:
- shm_unlock(shp);
+ rcu_read_unlock();
out:
return err;
}
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 09/11] ipc: rename ids->rw_mutex
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
` (7 preceding siblings ...)
2013-06-19 1:18 ` [PATCH 08/11] ipc,shm: shorten critical region for shmat Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 10/11] ipc,msg: drop msg_unlock Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 11/11] ipc: document general ipc locking scheme Davidlohr Bueso
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
Since in some situations the lock can be shared for readers,
we shouldn't be calling it a mutex, rename it to rwsem.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
include/linux/ipc_namespace.h | 2 +-
ipc/msg.c | 20 ++++++++--------
ipc/namespace.c | 4 ++--
ipc/sem.c | 24 +++++++++----------
ipc/shm.c | 56 +++++++++++++++++++++----------------------
ipc/util.c | 28 +++++++++++-----------
ipc/util.h | 4 ++--
7 files changed, 69 insertions(+), 69 deletions(-)
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index c4d870b..19c19a5 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -22,7 +22,7 @@ struct ipc_ids {
int in_use;
unsigned short seq;
unsigned short seq_max;
- struct rw_semaphore rw_mutex;
+ struct rw_semaphore rwsem;
struct idr ipcs_idr;
int next_id;
};
diff --git a/ipc/msg.c b/ipc/msg.c
index a1cf70e..80d8aa7 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -172,7 +172,7 @@ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
* @ns: namespace
* @params: ptr to the structure that contains the key and msgflg
*
- * Called with msg_ids.rw_mutex held (writer)
+ * Called with msg_ids.rwsem held (writer)
*/
static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{
@@ -259,8 +259,8 @@ static void expunge_all(struct msg_queue *msq, int res)
* removes the message queue from message queue ID IDR, and cleans up all the
* messages associated with this queue.
*
- * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
- * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
+ * msg_ids.rwsem (writer) and the spinlock for this message queue are held
+ * before freeque() is called. msg_ids.rwsem remains locked on exit.
*/
static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -282,7 +282,7 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
}
/*
- * Called with msg_ids.rw_mutex and ipcp locked.
+ * Called with msg_ids.rwsem and ipcp locked.
*/
static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
{
@@ -386,9 +386,9 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
}
/*
- * This function handles some msgctl commands which require the rw_mutex
+ * This function handles some msgctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
struct msqid_ds __user *buf, int version)
@@ -403,7 +403,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
return -EFAULT;
}
- down_write(&msg_ids(ns).rw_mutex);
+ down_write(&msg_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
@@ -459,7 +459,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&msg_ids(ns).rw_mutex);
+ up_write(&msg_ids(ns).rwsem);
return err;
}
@@ -494,7 +494,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
msginfo.msgmnb = ns->msg_ctlmnb;
msginfo.msgssz = MSGSSZ;
msginfo.msgseg = MSGSEG;
- down_read(&msg_ids(ns).rw_mutex);
+ down_read(&msg_ids(ns).rwsem);
if (cmd == MSG_INFO) {
msginfo.msgpool = msg_ids(ns).in_use;
msginfo.msgmap = atomic_read(&ns->msg_hdrs);
@@ -505,7 +505,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
msginfo.msgtql = MSGTQL;
}
max_id = ipc_get_maxid(&msg_ids(ns));
- up_read(&msg_ids(ns).rw_mutex);
+ up_read(&msg_ids(ns).rwsem);
if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
return -EFAULT;
return (max_id < 0) ? 0 : max_id;
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 7ee61bf..67dc744 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -81,7 +81,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
int next_id;
int total, in_use;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
in_use = ids->in_use;
@@ -93,7 +93,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
free(ns, perm);
total++;
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
}
static void free_ipc_ns(struct ipc_namespace *ns)
diff --git a/ipc/sem.c b/ipc/sem.c
index 94ffe72..d47bfad 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -321,7 +321,7 @@ static inline void sem_unlock(struct sem_array *sma, int locknum)
}
/*
- * sem_lock_(check_) routines are called in the paths where the rw_mutex
+ * sem_lock_(check_) routines are called in the paths where the rwsem
* is not held.
*
* The caller holds the RCU read lock.
@@ -425,7 +425,7 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
* @ns: namespace
* @params: ptr to the structure that contains key, semflg and nsems
*
- * Called with sem_ids.rw_mutex held (as a writer)
+ * Called with sem_ids.rwsem held (as a writer)
*/
static int newary(struct ipc_namespace *ns, struct ipc_params *params)
@@ -491,7 +491,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
{
@@ -502,7 +502,7 @@ static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
}
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -985,8 +985,8 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
return semzcnt;
}
-/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked
- * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex
+/* Free a semaphore set. freeary() is called with sem_ids.rwsem locked
+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rwsem
* remains locked on exit.
*/
static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
@@ -1092,7 +1092,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
seminfo.semmnu = SEMMNU;
seminfo.semmap = SEMMAP;
seminfo.semume = SEMUME;
- down_read(&sem_ids(ns).rw_mutex);
+ down_read(&sem_ids(ns).rwsem);
if (cmd == SEM_INFO) {
seminfo.semusz = sem_ids(ns).in_use;
seminfo.semaem = ns->used_sems;
@@ -1101,7 +1101,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
seminfo.semaem = SEMAEM;
}
max_id = ipc_get_maxid(&sem_ids(ns));
- up_read(&sem_ids(ns).rw_mutex);
+ up_read(&sem_ids(ns).rwsem);
if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
return -EFAULT;
return (max_id < 0) ? 0: max_id;
@@ -1407,9 +1407,9 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
}
/*
- * This function handles some semctl commands which require the rw_mutex
+ * This function handles some semctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int semctl_down(struct ipc_namespace *ns, int semid,
int cmd, int version, void __user *p)
@@ -1424,7 +1424,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
return -EFAULT;
}
- down_write(&sem_ids(ns).rw_mutex);
+ down_write(&sem_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd,
@@ -1463,7 +1463,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&sem_ids(ns).rw_mutex);
+ up_write(&sem_ids(ns).rwsem);
return err;
}
diff --git a/ipc/shm.c b/ipc/shm.c
index 2fe6170..763ef72 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -83,8 +83,8 @@ void shm_init_ns(struct ipc_namespace *ns)
}
/*
- * Called with shm_ids.rw_mutex (writer) and the shp structure locked.
- * Only shm_ids.rw_mutex remains locked on exit.
+ * Called with shm_ids.rwsem (writer) and the shp structure locked.
+ * Only shm_ids.rwsem remains locked on exit.
*/
static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -148,7 +148,7 @@ static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace
}
/*
- * shm_lock_(check_) routines are called in the paths where the rw_mutex
+ * shm_lock_(check_) routines are called in the paths where the rwsem
* is not necessarily held.
*/
static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
@@ -205,7 +205,7 @@ static void shm_open(struct vm_area_struct *vma)
* @ns: namespace
* @shp: struct to free
*
- * It has to be called with shp and shm_ids.rw_mutex (writer) locked,
+ * It has to be called with shp and shm_ids.rwsem (writer) locked,
* but returns with shp unlocked and freed.
*/
static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
@@ -253,7 +253,7 @@ static void shm_close(struct vm_area_struct *vma)
struct shmid_kernel *shp;
struct ipc_namespace *ns = sfd->ns;
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
/* remove from the list of attaches of the shm segment */
shp = shm_lock(ns, sfd->id);
BUG_ON(IS_ERR(shp));
@@ -264,10 +264,10 @@ static void shm_close(struct vm_area_struct *vma)
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_current(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -298,7 +298,7 @@ static int shm_try_destroy_current(int id, void *p, void *data)
return 0;
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_orphaned(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -309,7 +309,7 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
* We want to destroy segments without users and with already
* exit'ed originating process.
*
- * As shp->* are changed under rw_mutex, it's safe to skip shp locking.
+ * As shp->* are changed under rwsem, it's safe to skip shp locking.
*/
if (shp->shm_creator != NULL)
return 0;
@@ -323,10 +323,10 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
void shm_destroy_orphaned(struct ipc_namespace *ns)
{
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
@@ -338,10 +338,10 @@ void exit_shm(struct task_struct *task)
return;
/* Destroy all already created segments, but not mapped yet */
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -475,7 +475,7 @@ static const struct vm_operations_struct shm_vm_ops = {
* @ns: namespace
* @params: ptr to the structure that contains key, size and shmflg
*
- * Called with shm_ids.rw_mutex held as a writer.
+ * Called with shm_ids.rwsem held as a writer.
*/
static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
@@ -583,7 +583,7 @@ no_file:
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
{
@@ -594,7 +594,7 @@ static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -707,7 +707,7 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
/*
* Calculate and add used RSS and swap pages of a shm.
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_add_rss_swap(struct shmid_kernel *shp,
unsigned long *rss_add, unsigned long *swp_add)
@@ -734,7 +734,7 @@ static void shm_add_rss_swap(struct shmid_kernel *shp,
}
/*
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
unsigned long *swp)
@@ -763,9 +763,9 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
}
/*
- * This function handles some shmctl commands which require the rw_mutex
+ * This function handles some shmctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
struct shmid_ds __user *buf, int version)
@@ -780,7 +780,7 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
return -EFAULT;
}
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
@@ -819,7 +819,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
return err;
}
@@ -850,9 +850,9 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
if(copy_shminfo_to_user (buf, &shminfo, version))
return -EFAULT;
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if(err<0)
err = 0;
@@ -863,14 +863,14 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
struct shm_info shm_info;
memset(&shm_info, 0, sizeof(shm_info));
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
shm_info.used_ids = shm_ids(ns).in_use;
shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
shm_info.shm_tot = ns->shm_tot;
shm_info.swap_attempts = 0;
shm_info.swap_successes = 0;
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if (copy_to_user(buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
@@ -1169,7 +1169,7 @@ out_fput:
fput(file);
out_nattch:
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
shp = shm_lock(ns, shmid);
BUG_ON(IS_ERR(shp));
shp->shm_nattch--;
@@ -1177,7 +1177,7 @@ out_nattch:
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
return err;
out_unlock:
diff --git a/ipc/util.c b/ipc/util.c
index 1893667..8f12fe3 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -119,7 +119,7 @@ __initcall(ipc_init);
void ipc_init_ids(struct ipc_ids *ids)
{
- init_rwsem(&ids->rw_mutex);
+ init_rwsem(&ids->rwsem);
ids->in_use = 0;
ids->seq = 0;
@@ -174,7 +174,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
* @ids: Identifier set
* @key: The key to find
*
- * Requires ipc_ids.rw_mutex locked.
+ * Requires ipc_ids.rwsem locked.
* Returns the LOCKED pointer to the ipc structure if found or NULL
* if not.
* If key is found ipc points to the owning ipc structure
@@ -208,7 +208,7 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
* ipc_get_maxid - get the last assigned id
* @ids: IPC identifier set
*
- * Called with ipc_ids.rw_mutex held.
+ * Called with ipc_ids.rwsem held.
*/
int ipc_get_maxid(struct ipc_ids *ids)
@@ -246,7 +246,7 @@ int ipc_get_maxid(struct ipc_ids *ids)
* is returned. The 'new' entry is returned in a locked state on success.
* On failure the entry is not locked and a negative err-code is returned.
*
- * Called with writer ipc_ids.rw_mutex held.
+ * Called with writer ipc_ids.rwsem held.
*/
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
{
@@ -312,9 +312,9 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
{
int err;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
err = ops->getnew(ns, params);
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -331,7 +331,7 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
*
* On success, the IPC id is returned.
*
- * It is called with ipc_ids.rw_mutex and ipcp->lock held.
+ * It is called with ipc_ids.rwsem and ipcp->lock held.
*/
static int ipc_check_perms(struct ipc_namespace *ns,
struct kern_ipc_perm *ipcp,
@@ -376,7 +376,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
* Take the lock as a writer since we are potentially going to add
* a new entry + read locks are not "upgradable"
*/
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
ipcp = ipc_findkey(ids, params->key);
if (ipcp == NULL) {
/* key not used */
@@ -402,7 +402,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
}
ipc_unlock(ipcp);
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -413,7 +413,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
* @ids: IPC identifier set
* @ipcp: ipc perm structure containing the identifier to remove
*
- * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
+ * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
* before this function is called, and remain locked on the exit.
*/
@@ -621,7 +621,7 @@ struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id)
}
/**
- * ipc_lock - Lock an ipc structure without rw_mutex held
+ * ipc_lock - Lock an ipc structure without rwsem held
* @ids: IPC identifier set
* @id: ipc id to look for
*
@@ -748,7 +748,7 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
* - performs some audit and permission check, depending on the given cmd
* - returns a pointer to the ipc object or otherwise, the corresponding error.
*
- * Call holding the both the rw_mutex and the rcu read lock.
+ * Call holding the both the rwsem and the rcu read lock.
*/
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
@@ -867,7 +867,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
* Take the lock - this will be released by the corresponding
* call to stop().
*/
- down_read(&ids->rw_mutex);
+ down_read(&ids->rwsem);
/* pos < 0 is invalid */
if (*pos < 0)
@@ -894,7 +894,7 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it)
ids = &iter->ns->ids[iface->ids];
/* Release the lock we took in start() */
- up_read(&ids->rw_mutex);
+ up_read(&ids->rwsem);
}
static int sysvipc_proc_show(struct seq_file *s, void *it)
diff --git a/ipc/util.h b/ipc/util.h
index 41a6c4d..0a362ff 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -94,10 +94,10 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
#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->rwsem acquired for writing */
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
-/* must be called with ids->rw_mutex acquired for reading */
+/* must be called with ids->rwsem acquired for reading */
int ipc_get_maxid(struct ipc_ids *);
/* must be called with both locks acquired. */
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 10/11] ipc,msg: drop msg_unlock
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
` (8 preceding siblings ...)
2013-06-19 1:18 ` [PATCH 09/11] ipc: rename ids->rw_mutex Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 11/11] ipc: document general ipc locking scheme Davidlohr Bueso
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
There is only one user left, drop this function and just call
ipc_unlock_object() and rcu_read_unlock().
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/msg.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/ipc/msg.c b/ipc/msg.c
index 80d8aa7..091fa2b 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -70,8 +70,6 @@ struct msg_sender {
#define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS])
-#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
-
static void freeque(struct ipc_namespace *, struct kern_ipc_perm *);
static int newque(struct ipc_namespace *, struct ipc_params *);
#ifdef CONFIG_PROC_FS
@@ -270,7 +268,8 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
expunge_all(msq, -EIDRM);
ss_wakeup(&msq->q_senders, 1);
msg_rmid(ns, msq);
- msg_unlock(msq);
+ ipc_unlock_object(&msq->q_perm);
+ rcu_read_unlock();
list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) {
atomic_dec(&ns->msg_hdrs);
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 11/11] ipc: document general ipc locking scheme
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
` (9 preceding siblings ...)
2013-06-19 1:18 ` [PATCH 10/11] ipc,msg: drop msg_unlock Davidlohr Bueso
@ 2013-06-19 1:18 ` Davidlohr Bueso
10 siblings, 0 replies; 16+ messages in thread
From: Davidlohr Bueso @ 2013-06-19 1:18 UTC (permalink / raw)
To: akpm, riel, linux-kernel, linux-mm; +Cc: Davidlohr Bueso
As suggested by Andrew, add a generic initial locking scheme
used throughout all sysv ipc mechanisms. Documenting the ids
rwsem, how rcu can be enough to do the initial checks and when
to actually acquire the kern_ipc_perm.lock spinlock.
I found that adding it to util.c was generic enough.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
ipc/util.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/ipc/util.c b/ipc/util.c
index 8f12fe3..639bf38 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -15,6 +15,14 @@
* Jun 2006 - namespaces ssupport
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
+ *
+ * General sysv ipc locking scheme:
+ * when doing ipc id lookups, take the ids->rwsem
+ * rcu_read_lock()
+ * obtain the ipc object (kern_ipc_perm)
+ * perform security, capabilities, auditing and permission checks, etc.
+ * acquire the ipc lock (kern_ipc_perm.lock) throught ipc_lock_object()
+ * perform data updates (ie: SET, RMID, LOCK/UNLOCK commands)
*/
#include <linux/mm.h>
--
1.7.11.7
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 03/11] ipc: drop ipcctl_pre_down
2013-06-19 1:18 ` [PATCH 03/11] ipc: drop ipcctl_pre_down Davidlohr Bueso
@ 2013-07-16 22:49 ` Andrew Morton
0 siblings, 0 replies; 16+ messages in thread
From: Andrew Morton @ 2013-07-16 22:49 UTC (permalink / raw)
To: Davidlohr Bueso; +Cc: riel, linux-kernel, linux-mm
On Tue, 18 Jun 2013 18:18:28 -0700 Davidlohr Bueso <davidlohr.bueso@hp.com> wrote:
> Now that sem, msgque and shm, through *_down(), all use the lockless
> variant of ipcctl_pre_down(), go ahead and delete it.
Fixlets:
From: Andrew Morton <akpm@linux-foundation.org>
Subject: ipc-drop-ipcctl_pre_down-fix
fix function name in kerneldoc, cleanups
Cc: Davidlohr Bueso <davidlohr.bueso@hp.com>
Cc: Manfred Spraul <manfred@colorfullife.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Sedat Dilek <sedat.dilek@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
ipc/util.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff -puN ipc/util.c~ipc-drop-ipcctl_pre_down-fix ipc/util.c
--- a/ipc/util.c~ipc-drop-ipcctl_pre_down-fix
+++ a/ipc/util.c
@@ -733,7 +733,7 @@ int ipc_update_perm(struct ipc64_perm *i
}
/**
- * ipcctl_pre_down - retrieve an ipc and check permissions for some IPC_XXX cmd
+ * ipcctl_pre_down_nolock - retrieve an ipc and check permissions for some IPC_XXX cmd
* @ns: the ipc namespace
* @ids: the table of ids where to look for the ipc
* @id: the id of the ipc to retrieve
@@ -751,8 +751,8 @@ int ipc_update_perm(struct ipc64_perm *i
* Call holding the both the rw_mutex and the rcu read lock.
*/
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm)
+ struct ipc_ids *ids, int id, int cmd,
+ struct ipc64_perm *perm, int extra_perm)
{
kuid_t euid;
int err = -EPERM;
_
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 00/11] sysv ipc shared mem optimizations
2013-06-26 8:08 ` Sedat Dilek
@ 2013-06-28 10:10 ` Sedat Dilek
0 siblings, 0 replies; 16+ messages in thread
From: Sedat Dilek @ 2013-06-28 10:10 UTC (permalink / raw)
To: Davidlohr Bueso; +Cc: linux-mm, Andrew Morton, Rik van Riel, Manfred Spraul
[-- Attachment #1: Type: text/plain, Size: 2030 bytes --]
On Wed, Jun 26, 2013 at 10:08 AM, Sedat Dilek <sedat.dilek@gmail.com> wrote:
> On Wed, Jun 26, 2013 at 1:55 AM, Sedat Dilek <sedat.dilek@gmail.com> wrote:
>> Hi,
>>
>> I have tested the patchset "sysv ipc shared mem optimizations" on top
>> of next-20130618.
>>
>> My typical rebuild with fakeroot & 'make deb-pkg' was fine.
>>
>> Further tests done with LPT-full (20130503): IPC and SYSCALLS
>> test-cases ran successfully.
>>
>> I am attaching the tarball I have sent already to Davidlohr which contains:
>>
>> 35070 Jun 26 00:37 3.10.0-rc6-next20130618-1-iniza-small.patch
>> 114002 Jun 26 00:48 config-3.10.0-rc6-next20130618-1-iniza-small
>> 84489 Jun 26 00:55 dmesg_3.10.0-rc6-next20130618-1-iniza-small.txt
>> 38996 Jun 26 00:57 runltp-f-ipc_3.10.0-rc6-next20130618-1-iniza-small_dash.txt
>> 760276 Jun 26 01:12
>> runltp-f-syscalls_3.10.0-rc6-next20130618-1-iniza-small_dash.txt
>>
>> NOTES:
>> 1. 09/11 needed a small refresh as v2 (attached).
>> 2. [ PATCH] ipc,msq: fix race in msgrcv(2) (as v2) applied on top of
>> all (attached).
>>
>> Please feel free to add my Tested-by to the whole series.
>>
>
> I have re-tested this patchset also against next-20130624 (09/11
> original fits here, 08/11 needs to be cleanpatch-ed).
>
> ( In addition I still need the ipc-msg-next fix mentioned above which
> is now in akpm's mmots. )
>
Just curious:
Was there a decision taken if this will be in Linux-v3.12?
Is there a GIT tree?
Go through mmotm?
I have retested (again) against Friday's next-20130628.
Just as a note:
Linux Testing Project has now "runtest: Add new syscalls-ipc test-suite".
I can encourage the IPC folks to test with LTP:
# ./runltp -f ipc,syscalls-ipc <--- comma-separated list of IPC test-cases
See also my file-attachments.
- Sedat -
[1] https://github.com/linux-test-project/ltp/commit/e707624f7b7c749e76c2012e5822c05ff544e48c
> - Sedat -
>
> [1] http://ozlabs.org/~akpm/mmots/broken-out/ipcmsg-shorten-critical-region-in-msgrcv-fix-race-in-msgrcv2.patch
>
>> Regards,
>> - Sedat -
[-- Attachment #2: runltp-f-ipc-and-syscalls-ipc_3.10.0-rc7-next20130628-3-iniza-small.txt --]
[-- Type: text/plain, Size: 62402 bytes --]
INFO: creating /opt/ltp/results directory
Checking for required user/group ids
'nobody' user id and group found.
'bin' user id and group found.
'daemon' user id and group found.
Users group found.
Sys group found.
Required users/groups exist.
If some fields are empty or look unusual you may have an old version.
Compare to the current minimal requirements in Documentation/Changes.
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.04
DISTRIB_CODENAME=precise
DISTRIB_DESCRIPTION="Ubuntu 12.04.2 LTS"
NAME="Ubuntu"
VERSION="12.04.2 LTS, Precise Pangolin"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu precise (12.04.2 LTS)"
VERSION_ID="12.04"
Linux fambox 3.10.0-rc7-next20130628-3-iniza-small #1 SMP Fri Jun 28 11:52:37 CEST 2013 x86_64 x86_64 x86_64 GNU/Linux
Gnu C gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Gnu make 3.81
util-linux linux 2.20.1
mount linux 2.20.1 (with libblkid and selinux support)
modutils 6
e2fsprogs 1.42
PPP 2.4.5
Linux C Library > libc.2.15
Dynamic linker (ldd) 2.15
Procps 3.2.8
Net-tools 1.60
iproute2 iproute2-ss121211
Kbd 1.15.2
Sh-utils 8.13
Modules Loaded bnep rfcomm parport_pc ppdev snd_hda_codec_hdmi snd_hda_codec_realtek arc4 iwldvm mac80211 snd_hda_intel snd_hda_codec uvcvideo snd_hwdep snd_pcm videobuf2_vmalloc joydev videobuf2_memops snd_page_alloc videobuf2_core i915 snd_seq_midi videodev snd_seq_midi_event snd_rawmidi snd_seq iwlwifi snd_timer btusb psmouse snd_seq_device i2c_algo_bit bluetooth drm_kms_helper snd drm serio_raw samsung_laptop soundcore cfg80211 wmi lpc_ich video mac_hid lp parport hid_generic usbhid hid usb_storage r8169 mii
free reports:
total used free shared buffers cached
Mem: 3945224 2789348 1155876 0 1030676 1159864
-/+ buffers/cache: 598808 3346416
Swap: 262140 0 262140
/proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz
stepping : 7
microcode : 0x28
cpu MHz : 1984.000
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid
bogomips : 3192.57
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 1
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz
stepping : 7
microcode : 0x28
cpu MHz : 1984.000
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 0
cpu cores : 2
apicid : 1
initial apicid : 1
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid
bogomips : 3192.57
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 2
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz
stepping : 7
microcode : 0x28
cpu MHz : 1984.000
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 1
cpu cores : 2
apicid : 2
initial apicid : 2
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid
bogomips : 3192.57
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor : 3
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel(R) Core(TM) i5-2467M CPU @ 1.60GHz
stepping : 7
microcode : 0x28
cpu MHz : 2000.000
cache size : 3072 KB
physical id : 0
siblings : 4
core id : 1
cpu cores : 2
apicid : 3
initial apicid : 3
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid
bogomips : 3192.57
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
10240+0 records in
10240+0 records out
10240000 bytes (10 MB) copied, 0.0919147 s, 111 MB/s
mke2fs 1.42 (29-Nov-2011)
Discarding device blocks: 1024/10000\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\bdone
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
2512 inodes, 10000 blocks
500 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=10485760
2 block groups
8192 blocks per group, 8192 fragments per group
1256 inodes per group
Superblock backups stored on blocks:
8193
Allocating group tables: 0/2\b\b\b1/2\b\b\b \b\b\bdone
Writing inode tables: 0/2\b\b\b1/2\b\b\b \b\b\bdone
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: 0/2\b\b\b1/2\b\b\b \b\b\bdone
COMMAND: /opt/ltp/bin/ltp-pan -e -S -a 2612 -n 2612 -p -f /tmp/ltp-vxz0nrKSts/alltests -l /opt/ltp/results/LTP_RUN_ON-2013_Jun_28-11h_59m_54s.log -C /opt/ltp/output/LTP_RUN_ON-2013_Jun_28-11h_59m_54s.failed
-e LOG File: /opt/ltp/results/LTP_RUN_ON-2013_Jun_28-11h_59m_54s.log
-e FAILED COMMAND File: /opt/ltp/output/LTP_RUN_ON-2013_Jun_28-11h_59m_54s.failed
Running tests.......
<<<test_start>>>
tag=pipeio_1 stime=1372413595
cmdline="pipeio -T pipeio_1 -c 5 -s 4090 -i 100 -b -f x80"
contacts=""
analysis=exit
<<<test_output>>>
pipeio_1 1 TPASS : 1 PASS 501 pipe reads complete, read size = 4090, named pipe, blking,
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=pipeio_3 stime=1372413595
cmdline="pipeio -T pipeio_3 -c 5 -s 4090 -i 100 -u -b -f x80"
contacts=""
analysis=exit
<<<test_output>>>
pipeio_3 1 TPASS : 1 PASS 501 pipe reads complete, read size = 4090, sys pipe,
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=pipeio_4 stime=1372413595
cmdline="pipeio -T pipeio_4 -c 5 -s 4090 -i 100 -u -f x80"
contacts=""
analysis=exit
<<<test_output>>>
pipeio_4 1 TPASS : 1 PASS 501 pipe reads complete, read size = 4090, sys pipe,
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=pipeio_5 stime=1372413595
cmdline="pipeio -T pipeio_5 -c 5 -s 5000 -i 10 -b -f x80"
contacts=""
analysis=exit
<<<test_output>>>
pipeio_5 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_5 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_5 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_5 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_5 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_5 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_5 1 TPASS : 1 PASS 66 pipe reads complete, read size = 4096, named pipe, blking,
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=pipeio_6 stime=1372413595
cmdline="pipeio -T pipeio_6 -c 5 -s 5000 -i 10 -b -u -f x80"
contacts=""
analysis=exit
<<<test_output>>>
pipeio_6 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_6 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_6 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_6 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_6 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_6 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_6 1 TPASS : 1 PASS 66 pipe reads complete, read size = 4096, sys pipe,
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=pipeio_8 stime=1372413595
cmdline="pipeio -T pipeio_8 -c 5 -s 5000 -i 10 -u -f x80"
contacts=""
analysis=exit
<<<test_output>>>
pipeio_8 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_8 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_8 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_8 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_8 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_8 0 TINFO : adjusting i/o size to 4096, and # of writes to 13
pipeio_8 1 TPASS : 1 PASS 66 pipe reads complete, read size = 4096, sys pipe,
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=sem01 stime=1372413595
cmdline="sem01"
contacts=""
analysis=exit
<<<test_output>>>
PASS: error count is 0
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=sem02 stime=1372413595
cmdline="sem02"
contacts=""
analysis=exit
<<<test_output>>>
sem02 0 TINFO : Waiter, pid = 2783
sem02 0 TINFO : Poster, pid = 2783, posting
sem02 0 TINFO : Poster posted
sem02 0 TINFO : Poster exiting
sem02 0 TINFO : Waiter waiting, pid = 2783
sem02 0 TINFO : Waiter done waiting
sem02 1 TPASS : passed
<<<execution_status>>>
initiation_status="ok"
duration=20 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=message_queue_test_01 stime=1372413615
cmdline=" message_queue_test_01"
contacts=""
analysis=exit
<<<test_output>>>
message_queue_test_01: IPC Message Queue TestSuite program
Create message queue, id: 0x00000000
Child: received message queue id: 0
Child: sending message: "message queue transmission test...."
Parent: received message: "message queue transmission test...."
Remove the message queue
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=message_queue_test_02_get stime=1372413615
cmdline="message_queue_test_02_get"
contacts=""
analysis=exit
<<<test_output>>>
32768
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=message_queue_test_02_snd stime=1372413615
cmdline="message_queue_test_02_snd"
contacts=""
analysis=exit
<<<test_output>>>
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=message_queue_test_02_rcv stime=1372413615
cmdline="message_queue_test_02_rcv"
contacts=""
analysis=exit
<<<test_output>>>
<< Message Queue test default message >>
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=message_queue_test_02_ctl stime=1372413615
cmdline="message_queue_test_02_ctl -r"
contacts=""
analysis=exit
<<<test_output>>>
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=message_queue_test_04 stime=1372413615
cmdline=" message_queue_test_04"
contacts=""
analysis=exit
<<<test_output>>>
message_queue_test_04: IPC Message Queue TestSuite program
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=message_queue_test_05 stime=1372413615
cmdline=" message_queue_test_05"
contacts=""
analysis=exit
<<<test_output>>>
message_queue_test_05: IPC Message Queue TestSuite program
Creating 10 message queues ...
All message queues created successfully
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=pipe_test_01 stime=1372413615
cmdline=" pipe_test_01"
contacts=""
analysis=exit
<<<test_output>>>
cat: /etc/inittab: No such file or directory
0
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=pipe_test_02 stime=1372413615
cmdline=" pipe_test_02"
contacts=""
analysis=exit
<<<test_output>>>
pipe_test_02: IPC Pipe TestSuite program
Creating pipes...
Spawning 1 child processes ...
Child: pid [2817] received 1024 packets from parent
Parent: sending 1024 packets (40960 bytes) to child processes ...
Parent: done sending packets & waiting for children to complete!
Parent: children received all packets & exited successfully
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semaphore_test_01 stime=1372413615
cmdline=" run_semaphore_test_01.sh"
contacts=""
analysis=exit
<<<test_output>>>
semaphore_test_01 0 TINFO : Created semaphore ID: 262144
semaphore_test_01 1 TPASS : semaphore ID comparing passed.
semaphore_test_01 0 TINFO : CLOSE: exit.
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=2
<<<test_end>>>
<<<test_start>>>
tag=semaphore_test_02 stime=1372413615
cmdline=" semaphore_test_02"
contacts=""
analysis=exit
<<<test_output>>>
semaphore_test_02: IPC Semaphore TestSuite program
Testing semctl (IPC_SET) command operation
Testing semctl (IPC_SET) command operation
Testing semctl (IPC_STAT) command operation
Testing semctl (SETVAL) command operation
Testing semctl (GETVAL) command operation
Testing semop (signal and wait) operations
Testing semctl (GETPID) command operation
Testing semctl (GETNCNT) command operation
Testing semctl (GETZCNT) command operation
Testing semctl (SETALL) command operation
Testing semctl (GETALL) command operation
Testing semctl (IPC_RMID) command operation
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semaphore_test_03 stime=1372413615
cmdline=" semaphore_test_03"
contacts=""
analysis=exit
<<<test_output>>>
semaphore_test_03: IPC Semaphore TestSuite program
Creating 16 semaphores ...
Setting semaphore uid, gid and mode ... semid = 327680
Verifying semaphore info ...
Testing semop() with all Semaphore values, options and flags
Semval Semop Semflag Description
2 -1 0 Obtain resource
1 -1 0 Obtain resource
0 0 0 Semop function returns immediately
5 1 0 Return resource
6 -7 IPC_NOWAIT Semop function returns immediately
6 0 IPC_NOWAIT Semop function returns immediately
6 1 0 Return resource
7 -8 0 Sleep (until resource becomes available)
Creating 16 semaphores ...
Setting semaphore uid, gid and mode ... semid = 327680
Verifying semaphore info ...
Testing semop() with all Semaphore values, options and flags
Semval Semop Semflag Description
2 -1 0 Obtain resource
1 -1 0 Obtain resource
0 0 0 Semop function returns immediately
5 1 0 Return resource
6 -7 IPC_NOWAIT Semop function returns immediately
6 0 IPC_NOWAIT Semop function returns immediately
6 1 0 Return resource
7 -8 0 Sleep (until resource becomes available)
7 -8 0 Sleep (until signaled)
Creating 16 semaphores ...
Setting semaphore uid, gid and mode ... semid = 327680
Verifying semaphore info ...
Testing semop() with all Semaphore values, options and flags
Semval Semop Semflag Description
2 -1 0 Obtain resource
1 -1 0 Obtain resource
0 0 0 Semop function returns immediately
5 1 0 Return resource
6 -7 IPC_NOWAIT Semop function returns immediately
6 0 IPC_NOWAIT Semop function returns immediately
6 1 0 Return resource
7 -8 0 Sleep (until resource becomes available)
7 -8 0 Sleep (until signaled)
1 5 SEM_UNDO Sleep (until resource becomes available)
Creating 16 semaphores ...
Setting semaphore uid, gid and mode ... semid = 327680
Verifying semaphore info ...
Testing semop() with all Semaphore values, options and flags
Semval Semop Semflag Description
2 -1 0 Obtain resource
1 -1 0 Obtain resource
0 0 0 Semop function returns immediately
5 1 0 Return resource
6 -7 IPC_NOWAIT Semop function returns immediately
6 0 IPC_NOWAIT Semop function returns immediately
6 1 0 Return resource
7 -8 0 Sleep (until resource becomes available)
7 -8 0 Sleep (until signaled)
1 5 SEM_UNDO Sleep (until resource becomes available)
7 -8 0 Sleep (until semaphores are removed)
Creating 16 semaphores ...
Setting semaphore uid, gid and mode ... semid = 327680
Verifying semaphore info ...
Testing semop() with all Semaphore values, options and flags
Semval Semop Semflag Description
2 -1 0 Obtain resource
1 -1 0 Obtain resource
0 0 0 Semop function returns immediately
5 1 0 Return resource
6 -7 IPC_NOWAIT Semop function returns immediately
6 0 IPC_NOWAIT Semop function returns immediately
6 1 0 Return resource
7 -8 0 Sleep (until resource becomes available)
7 -8 0 Sleep (until signaled)
1 5 SEM_UNDO Sleep (until resource becomes available)
7 -8 0 Sleep (until semaphores are removed)
9 -1 SEM_UNDO Obtain resource
8 -8 SEM_UNDO Obtain resource
9 0 0 Sleep (until signaled)
Creating 16 semaphores ...
Setting semaphore uid, gid and mode ... semid = 327680
Verifying semaphore info ...
Testing semop() with all Semaphore values, options and flags
Semval Semop Semflag Description
2 -1 0 Obtain resource
1 -1 0 Obtain resource
0 0 0 Semop function returns immediately
5 1 0 Return resource
6 -7 IPC_NOWAIT Semop function returns immediately
6 0 IPC_NOWAIT Semop function returns immediately
6 1 0 Return resource
7 -8 0 Sleep (until resource becomes available)
7 -8 0 Sleep (until signaled)
1 5 SEM_UNDO Sleep (until resource becomes available)
7 -8 0 Sleep (until semaphores are removed)
9 -1 SEM_UNDO Obtain resource
8 -8 SEM_UNDO Obtain resource
9 0 0 Sleep (until signaled)
9 0 0 Sleep (until resource becomes available)
Creating 16 semaphores ...
Setting semaphore uid, gid and mode ... semid = 327680
Verifying semaphore info ...
Testing semop() with all Semaphore values, options and flags
Semval Semop Semflag Description
2 -1 0 Obtain resource
1 -1 0 Obtain resource
0 0 0 Semop function returns immediately
5 1 0 Return resource
6 -7 IPC_NOWAIT Semop function returns immediately
6 0 IPC_NOWAIT Semop function returns immediately
6 1 0 Return resource
7 -8 0 Sleep (until resource becomes available)
7 -8 0 Sleep (until signaled)
1 5 SEM_UNDO Sleep (until resource becomes available)
7 -8 0 Sleep (until semaphores are removed)
9 -1 SEM_UNDO Obtain resource
8 -8 SEM_UNDO Obtain resource
9 0 0 Sleep (until signaled)
9 0 0 Sleep (until resource becomes available)
4 0 0 Sleep (until semaphores are removed)
Creating 16 semaphores ...
Setting semaphore uid, gid and mode ... semid = 327680
Verifying semaphore info ...
Testing semop() with all Semaphore values, options and flags
Semval Semop Semflag Description
2 -1 0 Obtain resource
1 -1 0 Obtain resource
0 0 0 Semop function returns immediately
5 1 0 Return resource
6 -7 IPC_NOWAIT Semop function returns immediately
6 0 IPC_NOWAIT Semop function returns immediately
6 1 0 Return resource
7 -8 0 Sleep (until resource becomes available)
7 -8 0 Sleep (until signaled)
1 5 SEM_UNDO Sleep (until resource becomes available)
7 -8 0 Sleep (until semaphores are removed)
9 -1 SEM_UNDO Obtain resource
8 -8 SEM_UNDO Obtain resource
9 0 0 Sleep (until signaled)
9 0 0 Sleep (until resource becomes available)
4 0 0 Sleep (until semaphores are removed)
successful!
<<<execution_status>>>
initiation_status="ok"
duration=7 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmem_test_01 stime=1372413622
cmdline=" shmem_test_01"
contacts=""
analysis=exit
<<<test_output>>>
shmem_test_01: IPC Shared Memory TestSuite program
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Index through shared memory segment ...
Release shared memory
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmem_test_02 stime=1372413622
cmdline=" shmem_test_02"
contacts=""
analysis=exit
<<<test_output>>>
shmem_test_02: IPC Shared Memory TestSuite program
Get shared memory segment (100000 bytes)
Parent: calculate shared memory segment checksum
shared memory checksum 00c26eb0
Spawning 2 child processes ...
child (00): checksum 00c26eb0
shmem_test_02: IPC Shared Memory TestSuite program
Get shared memory segment (100000 bytes)
Parent: calculate shared memory segment checksum
shared memory checksum 00c26eb0
Spawning 2 child processes ...
child (01): checksum 00c26eb0
shmem_test_02: IPC Shared Memory TestSuite program
Get shared memory segment (100000 bytes)
Parent: calculate shared memory segment checksum
shared memory checksum 00c26eb0
Spawning 2 child processes ...
Parent: children calculated segment successfully
successful!
<<<execution_status>>>
initiation_status="ok"
duration=1 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=shmem_test_03 stime=1372413623
cmdline=" shmem_test_03"
contacts=""
analysis=exit
<<<test_output>>>
shmem_test_03: IPC Shared Memory TestSuite program
Get shared memory segment (100000 bytes)
Spawning 2 child processes ...
child (00): checksum 00c26eb0
shmem_test_03: IPC Shared Memory TestSuite program
Get shared memory segment (100000 bytes)
Spawning 2 child processes ...
child (01): checksum 00c26eb0
shmem_test_03: IPC Shared Memory TestSuite program
Get shared memory segment (100000 bytes)
Spawning 2 child processes ...
Parent: calculate shared memory segment checksum
shared memory checksum 00c26eb0
Parent: children calculated segment successfully
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmem_test_04 stime=1372413623
cmdline=" shmem_test_04"
contacts=""
analysis=exit
<<<test_output>>>
shmem_test_04: IPC Shared Memory TestSuite program
Object type to map = Anonymous memory
Number of loops = 1
Number of procs = 1
Bytes per process = 16777216 (16MB)
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=2 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=shmem_test_05 stime=1372413623
cmdline=" shmem_test_05"
contacts=""
analysis=exit
<<<test_output>>>
shmem_test_05: IPC Shared Memory TestSuite program
mykey to uniquely identify the shared memory segment 0x33050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30000000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x34050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30200000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x35050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30400000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x36050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30600000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x37050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30800000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x38050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30a00000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x39050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30c00000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x41050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30d00000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x42050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x30f00000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x43050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x31000000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x45050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
offset of the shared memory segment 0x32000000
Index through shared memory segment ...
Detach from the segment using the shmdt subroutine
Release shared memory
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=shmem_test_06 stime=1372413623
cmdline=" shmem_test_06"
contacts=""
analysis=exit
<<<test_output>>>
shmem_test_06: IPC Shared Memory TestSuite program
mykey to uniquely identify the shared memory segment 0x33050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b73349000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x34050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72b68000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x35050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72a68000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x36050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72968000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x37050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72868000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x38050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72768000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x39050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72668000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x41050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72568000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x42050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72468000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x43050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72368000
Index through shared memory segment ...
mykey to uniquely identify the shared memory segment 0x45050405
Get shared memory segment (1048576 bytes)
Attach shared memory segment to process
Shared memory segment address : 0x7f4b72268000
Index through shared memory segment ...
Detach from the segment using the shmdt subroutine
Release shared memory
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=2 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=shmem_test_07 stime=1372413623
cmdline=" shmem_test_07"
contacts=""
analysis=exit
<<<test_output>>>
shmem_test_07: IPC Shared Memory TestSuite program
Number of writers = 2
Number of readers = 2
Bytes per writer = 200000
writer (000): shared memory checksum 01850160
writer (001): shared memory checksum 018501a0
reader (000) of writer (001): checksum 018501a0
reader (000) of writer (000): checksum 01850160
reader (001) of writer (000): checksum 01850160
reader (001) of writer (001): checksum 018501a0
Main: readers calculated segment successfully
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=signal_test_01 stime=1372413623
cmdline=" signal_test_01"
contacts=""
analysis=exit
<<<test_output>>>
signal_test_01: IPC Signals TestSuite program
Send SIGILL, SIGALRM, SIGIOT signals to process
received signal: (SIGILL)
received signal: (SIGALRM)
received signal: (SIGIOT/SIGABRT)
Block SIGILL, SIGALRM, SIGIOT signals, and resend signals + others
received signal: (SIGFPE)
received signal: (SIGTERM)
received signal: (SIGINT)
Block rest of signals
Change signal mask & wait until signal interrupts process
received signal: (SIGINT)
successful!
<<<execution_status>>>
initiation_status="ok"
duration=2 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=signal_test_02 stime=1372413625
cmdline=" signal_test_02"
contacts=""
analysis=exit
<<<test_output>>>
signal_test_02: IPC TestSuite program
Send SIGILL, SIGALRM, SIGIOT signals to process
received signal: (SIGILL)
received signal: (SIGALRM)
received signal: (SIGIOT/SIGABRT)
Block SIGILL, SIGALRM, SIGIOT signals, and resend signals + others
received signal: (SIGFPE)
received signal: (SIGTERM)
received signal: (SIGINT)
Block rest of signals
Change signal mask & wait until signal interrupts process
received signal: (SIGINT)
successful!
<<<execution_status>>>
initiation_status="ok"
duration=2 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=signal_test_03 stime=1372413627
cmdline=" signal_test_03"
contacts=""
analysis=exit
<<<test_output>>>
signal_test_03: IPC Signals TestSuite program
(BEGIN) Critial section
(END) Critial section
received signal: (SIGILL)
successful!
<<<execution_status>>>
initiation_status="ok"
duration=1 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=signal_test_04 stime=1372413628
cmdline=" signal_test_04"
contacts=""
analysis=exit
<<<test_output>>>
signal_test_04: IPC TestSuite program
Wait for SIGUSR1 signal from child process
Received SIGUSR1 (30)
Stop the child process
Wait for SIGCHLD signal from stopped child process
Received SIGCHLD (20)
Resume child process & wait for it to send SIGUSR1 signal
Received SIGUSR1 (20)
Now kill the child process with SIGUSR2 signal
Wait for SIGCHLD signal from killed child process
Received SIGCHLD (30)
successful!
<<<execution_status>>>
initiation_status="ok"
duration=4 termination_type=exited termination_id=0 corefile=no
cutime=397 cstime=3
<<<test_end>>>
<<<test_start>>>
tag=signal_test_05 stime=1372413632
cmdline=" signal_test_05"
contacts=""
analysis=exit
<<<test_output>>>
signal_test_05: IPC TestSuite program
Spawning child process
Child: sending ALL signals to parent!
Sending (1)
Sending (2)
Sending (3)
Sending (4)
Sending (5)
Sending (6)
Sending (7)
Sending (8)
Sending (10)
Sending (11)
Sending (12)
Sending (13)
Sending (14)
Sending (15)
Sending (16)
Sending (18)
Sending (20)
Sending (21)
Sending (22)
Sending (23)
Sending (24)
Sending (25)
Sending (26)
Sending (27)
Sending (28)
Sending (29)
Sending (30)
Sending (31)
Sending (35)
Sending (36)
Sending (37)
Sending (38)
Sending (39)
Sending (40)
Sending (41)
Sending (42)
Sending (43)
Sending (44)
Sending (45)
Sending (46)
Sending (47)
Sending (48)
Sending (49)
Sending (50)
Sending (51)
Sending (52)
Sending (53)
Sending (54)
Sending (55)
Sending (56)
Sending (57)
Sending (58)
Sending (59)
Sending (60)
Sending (61)
Sending (62)
Sending (63)
Sending (64)
signal_test_05: IPC TestSuite program
Spawning child process
caught SIGCHLD(17) signal
Child process exited successfully
successful!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=signal_test_06 stime=1372413632
cmdline=" signal_test_06"
contacts=""
analysis=exit
<<<test_output>>>
signal_test_06: IPC TestSuite program
Block all signals from interrupting the process
Send MAX (1048576) SIGUSR1 signals to the process...
Ensure at least one SIGUSR1 signal is pending
Change signal mask & wait for SIGUSR1 signal
caught SIGUSR1 (10) signal
successful!
<<<execution_status>>>
initiation_status="ok"
duration=3 termination_type=exited termination_id=0 corefile=no
cutime=45 cstime=43
<<<test_end>>>
<<<test_start>>>
tag=signal_test_07 stime=1372413635
cmdline=" signal_test_07"
contacts=""
analysis=exit
<<<test_output>>>
signal_test_07: IPC TestSuite program
Send MAX (1048576) signals to the process...
Received EVERY signal!
successful!
<<<execution_status>>>
initiation_status="ok"
duration=3 termination_type=exited termination_id=0 corefile=no
cutime=115 cstime=231
<<<test_end>>>
<<<test_start>>>
tag=msgctl01 stime=1372413638
cmdline="msgctl01"
contacts=""
analysis=exit
<<<test_output>>>
msgctl01 1 TPASS : qs_buf.msg_qbytes is a positive value
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgctl02 stime=1372413638
cmdline="msgctl02"
contacts=""
analysis=exit
<<<test_output>>>
msgctl02 1 TPASS : qs_buf.msg_qbytes is the new value - 16383
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgctl03 stime=1372413638
cmdline="msgctl03"
contacts=""
analysis=exit
<<<test_output>>>
msgctl03 1 TPASS : The queue is gone
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=msgctl04 stime=1372413638
cmdline="msgctl04"
contacts=""
analysis=exit
<<<test_output>>>
msgctl04 1 TPASS : expected failure: TEST_ERRNO=EACCES(13): Permission denied
msgctl04 2 TPASS : expected failure: TEST_ERRNO=EFAULT(14): Bad address
msgctl04 3 TPASS : expected failure: TEST_ERRNO=EFAULT(14): Bad address
msgctl04 4 TPASS : expected failure: TEST_ERRNO=EINVAL(22): Invalid argument
msgctl04 5 TPASS : expected failure: TEST_ERRNO=EINVAL(22): Invalid argument
msgctl04 6 TPASS : expected failure: TEST_ERRNO=EINVAL(22): Invalid argument
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgctl05 stime=1372413638
cmdline="msgctl05"
contacts=""
analysis=exit
<<<test_output>>>
msgctl05 1 TPASS : expected error = 1 : Operation not permitted
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgctl06 stime=1372413638
cmdline="msgctl06"
contacts=""
analysis=exit
<<<test_output>>>
msgctl06 1 TPASS : msgctl06 ran successfully!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgctl07 stime=1372413638
cmdline="msgctl07"
contacts=""
analysis=exit
<<<test_output>>>
msgctl07 1 TPASS : msgctl07 ran successfully!
<<<execution_status>>>
initiation_status="ok"
duration=20 termination_type=exited termination_id=0 corefile=no
cutime=1987 cstime=11
<<<test_end>>>
<<<test_start>>>
tag=msgctl08 stime=1372413658
cmdline="msgctl08"
contacts=""
analysis=exit
<<<test_output>>>
msgctl08 1 TPASS : msgctl08 ran successfully!
<<<execution_status>>>
initiation_status="ok"
duration=3 termination_type=exited termination_id=0 corefile=no
cutime=268 cstime=619
<<<test_end>>>
<<<test_start>>>
tag=msgctl09 stime=1372413661
cmdline="msgctl09"
contacts=""
analysis=exit
<<<test_output>>>
msgctl09 1 TPASS : msgctl09 ran successfully!
<<<execution_status>>>
initiation_status="ok"
duration=1 termination_type=exited termination_id=0 corefile=no
cutime=24 cstime=74
<<<test_end>>>
<<<test_start>>>
tag=msgctl10 stime=1372413662
cmdline="msgctl10"
contacts=""
analysis=exit
<<<test_output>>>
msgctl10 1 TPASS : msgctl10 ran successfully!
<<<execution_status>>>
initiation_status="ok"
duration=108 termination_type=exited termination_id=0 corefile=no
cutime=10715 cstime=20238
<<<test_end>>>
<<<test_start>>>
tag=msgctl11 stime=1372413770
cmdline="msgctl11"
contacts=""
analysis=exit
<<<test_output>>>
msgctl11 0 TINFO : Using upto 16186 pids
msgctl11 1 TPASS : msgctl11 ran successfully!
<<<execution_status>>>
initiation_status="ok"
duration=13 termination_type=exited termination_id=0 corefile=no
cutime=1190 cstime=2559
<<<test_end>>>
<<<test_start>>>
tag=msgget01 stime=1372413783
cmdline="msgget01"
contacts=""
analysis=exit
<<<test_output>>>
msgget01 1 TPASS : message received = message sent
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgget02 stime=1372413783
cmdline="msgget02"
contacts=""
analysis=exit
<<<test_output>>>
msgget02 1 TPASS : expected failure - errno = 17 : File exists
msgget02 2 TPASS : expected failure - errno = 2 : No such file or directory
msgget02 3 TPASS : expected failure - errno = 2 : No such file or directory
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgget03 stime=1372413783
cmdline="msgget03"
contacts=""
analysis=exit
<<<test_output>>>
msgget03 1 TPASS : expected failure - errno = 0 : Success
<<<execution_status>>>
initiation_status="ok"
duration=1 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=49
<<<test_end>>>
<<<test_start>>>
tag=msgget04 stime=1372413784
cmdline="msgget04"
contacts=""
analysis=exit
<<<test_output>>>
msgget04 1 TPASS : expected failure - errno = 13 : Permission denied
msgget04 2 TPASS : expected failure - errno = 13 : Permission denied
msgget04 3 TPASS : expected failure - errno = 13 : Permission denied
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgrcv01 stime=1372413784
cmdline="msgrcv01"
contacts=""
analysis=exit
<<<test_output>>>
msgrcv01 1 TPASS : message received = message sent
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgrcv02 stime=1372413784
cmdline="msgrcv02"
contacts=""
analysis=exit
<<<test_output>>>
msgrcv02 1 TPASS : expected failure - errno = 13 : Permission denied
msgrcv02 2 TPASS : expected failure - errno = 14 : Bad address
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgrcv03 stime=1372413784
cmdline="msgrcv03"
contacts=""
analysis=exit
<<<test_output>>>
msgrcv03 1 TPASS : expected failure - errno = 22 : Invalid argument
msgrcv03 2 TPASS : expected failure - errno = 22 : Invalid argument
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgrcv04 stime=1372413784
cmdline="msgrcv04"
contacts=""
analysis=exit
<<<test_output>>>
msgrcv04 1 TPASS : expected failure - errno = 7 : Argument list too long
msgrcv04 2 TPASS : expected failure - errno = 42 : No message of desired type
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgrcv05 stime=1372413784
cmdline="msgrcv05"
contacts=""
analysis=exit
<<<test_output>>>
msgrcv05 1 TPASS : got EINTR as expected
<<<execution_status>>>
initiation_status="ok"
duration=1 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=msgrcv06 stime=1372413785
cmdline="msgrcv06"
contacts=""
analysis=exit
<<<test_output>>>
msgrcv06 1 TPASS : expected failure - errno = 43 : Identifier removed
<<<execution_status>>>
initiation_status="ok"
duration=1 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgsnd01 stime=1372413786
cmdline="msgsnd01"
contacts=""
analysis=exit
<<<test_output>>>
msgsnd01 1 TPASS : queue bytes = MSGSIZE and queue messages = 1
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgsnd02 stime=1372413786
cmdline="msgsnd02"
contacts=""
analysis=exit
<<<test_output>>>
msgsnd02 1 TPASS : expected failure - errno = 13 : Permission denied
msgsnd02 2 TPASS : expected failure - errno = 14 : Bad address
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgsnd03 stime=1372413786
cmdline="msgsnd03"
contacts=""
analysis=exit
<<<test_output>>>
msgsnd03 1 TPASS : expected failure - errno = 22 : Invalid argument
msgsnd03 2 TPASS : expected failure - errno = 22 : Invalid argument
msgsnd03 3 TPASS : expected failure - errno = 22 : Invalid argument
msgsnd03 4 TPASS : expected failure - errno = 22 : Invalid argument
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgsnd04 stime=1372413786
cmdline="msgsnd04"
contacts=""
analysis=exit
<<<test_output>>>
msgsnd04 1 TPASS : expected failure - errno = 11 : Resource temporarily unavailable
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=msgsnd05 stime=1372413786
cmdline="msgsnd05"
contacts=""
analysis=exit
<<<test_output>>>
msgsnd05 1 TPASS : expected failure - errno = 4 : Interrupted system call
<<<execution_status>>>
initiation_status="ok"
duration=2 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=msgsnd06 stime=1372413788
cmdline="msgsnd06"
contacts=""
analysis=exit
<<<test_output>>>
msgsnd06 1 TPASS : expected failure - errno = 43 : Identifier removed
<<<execution_status>>>
initiation_status="ok"
duration=2 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semctl01 stime=1372413790
cmdline="semctl01"
contacts=""
analysis=exit
<<<test_output>>>
semctl01 1 TPASS : buf.sem_nsems and buf.sem_perm.mode are correct
semctl01 2 TPASS : buf.sem_perm.mode is correct
semctl01 3 TPASS : semaphores have expected values
semctl01 4 TPASS : number of sleeping processes is correct
semctl01 1 TPASS : buf.sem_nsems and buf.sem_perm.mode are correct
semctl01 2 TPASS : buf.sem_perm.mode is correct
semctl01 3 TPASS : semaphores have expected values
semctl01 4 TPASS : number of sleeping processes is correct
semctl01 5 TPASS : last pid value is correct
semctl01 6 TPASS : semaphore value is correct
semctl01 7 TPASS : number of sleeping processes is correct
semctl01 8 TPASS : semaphore values are correct
semctl01 9 TPASS : semaphore value is correct
semctl01 10 TPASS : semaphore appears to be removed
<<<execution_status>>>
initiation_status="ok"
duration=3 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semctl02 stime=1372413793
cmdline="semctl02"
contacts=""
analysis=exit
<<<test_output>>>
semctl02 1 TPASS : expected failure - errno = 13 : Permission denied
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semctl03 stime=1372413793
cmdline="semctl03"
contacts=""
analysis=exit
<<<test_output>>>
semctl03 1 TPASS : expected failure - errno = 22 : Invalid argument
semctl03 2 TPASS : expected failure - errno = 22 : Invalid argument
semctl03 3 TPASS : expected failure - errno = 14 : Bad address
semctl03 4 TPASS : expected failure - errno = 14 : Bad address
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semctl04 stime=1372413793
cmdline="semctl04"
contacts=""
analysis=exit
<<<test_output>>>
semctl04 1 TPASS : expected failure - errno = 1 : Operation not permitted
semctl04 2 TPASS : expected failure - errno = 1 : Operation not permitted
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=semctl05 stime=1372413793
cmdline="semctl05"
contacts=""
analysis=exit
<<<test_output>>>
semctl05 1 TPASS : expected failure - errno = 34 : Numerical result out of range
semctl05 2 TPASS : expected failure - errno = 34 : Numerical result out of range
semctl05 3 TPASS : expected failure - errno = 34 : Numerical result out of range
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semctl06 stime=1372413793
cmdline="semctl06"
contacts=""
analysis=exit
<<<test_output>>>
semctl06 1 TPASS : semctl06 ran successfully!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=2
<<<test_end>>>
<<<test_start>>>
tag=semctl07 stime=1372413793
cmdline="semctl07"
contacts=""
analysis=exit
<<<test_output>>>
semctl07 1 TPASS : semctl07 ran successfully!
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semget01 stime=1372413793
cmdline="semget01"
contacts=""
analysis=exit
<<<test_output>>>
semget01 1 TPASS : basic semaphore values are okay
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semget02 stime=1372413793
cmdline="semget02"
contacts=""
analysis=exit
<<<test_output>>>
semget02 1 TPASS : expected failure - errno = 13 : Permission denied
semget02 2 TPASS : expected failure - errno = 17 : File exists
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semget03 stime=1372413793
cmdline="semget03"
contacts=""
analysis=exit
<<<test_output>>>
semget03 1 TPASS : expected failure - errno = 2 : No such file or directory
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semget05 stime=1372413793
cmdline="semget05"
contacts=""
analysis=exit
<<<test_output>>>
semget05 1 TPASS : expected failure - errno = 28 : No space left on device
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semget06 stime=1372413793
cmdline="semget06"
contacts=""
analysis=exit
<<<test_output>>>
semget06 1 TPASS : expected failure - errno = 22 : Invalid argument
semget06 2 TPASS : expected failure - errno = 22 : Invalid argument
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=semop01 stime=1372413793
cmdline="semop01"
contacts=""
analysis=exit
<<<test_output>>>
semop01 1 TPASS : semaphore values are correct
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semop02 stime=1372413793
cmdline="semop02"
contacts=""
analysis=exit
<<<test_output>>>
semop02 1 TPASS : expected failure - errno = 7 : Argument list too long
semop02 2 TPASS : expected failure - errno = 13 : Permission denied
semop02 3 TPASS : expected failure - errno = 14 : Bad address
semop02 4 TPASS : expected failure - errno = 22 : Invalid argument
semop02 5 TPASS : expected failure - errno = 22 : Invalid argument
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semop03 stime=1372413793
cmdline="semop03"
contacts=""
analysis=exit
<<<test_output>>>
semop03 1 TPASS : expected failure - errno = 27 : File too large
semop03 2 TPASS : expected failure - errno = 27 : File too large
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semop04 stime=1372413793
cmdline="semop04"
contacts=""
analysis=exit
<<<test_output>>>
semop04 1 TPASS : expected failure - errno = 11 : Resource temporarily unavailable
semop04 2 TPASS : expected failure - errno = 11 : Resource temporarily unavailable
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=semop05 stime=1372413793
cmdline="semop05"
contacts=""
analysis=exit
<<<test_output>>>
semop05 1 TPASS : expected failure - errno = 43 : Identifier removed
semop05 1 TPASS : expected failure - errno = 43 : Identifier removed
semop05 1 TPASS : expected failure - errno = 4 : Interrupted system call
semop05 1 TPASS : expected failure - errno = 4 : Interrupted system call
<<<execution_status>>>
initiation_status="ok"
duration=4 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmat01 stime=1372413797
cmdline="shmat01"
contacts=""
analysis=exit
<<<test_output>>>
shmat01 1 TPASS : conditions and functionality are correct
shmat01 2 TPASS : conditions and functionality are correct
shmat01 3 TPASS : conditions and functionality are correct
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=shmat02 stime=1372413797
cmdline="shmat02"
contacts=""
analysis=exit
<<<test_output>>>
shmat02 1 TPASS : shmat failed as expected: errno=EINVAL(22): Invalid argument
shmat02 2 TPASS : shmat failed as expected: errno=EINVAL(22): Invalid argument
shmat02 3 TPASS : shmat failed as expected: errno=EACCES(13): Permission denied
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmat03 stime=1372413797
cmdline="shmat03"
contacts=""
analysis=exit
<<<test_output>>>
shmat03 1 TPASS : expected failure: TEST_ERRNO=EACCES(13): Permission denied
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmctl01 stime=1372413797
cmdline="shmctl01"
contacts=""
analysis=exit
<<<test_output>>>
shmctl01 1 TPASS : pid, size, # of attaches and mode are correct - pass #1
shmctl01 2 TPASS : pid, size, # of attaches and mode are correct - pass #2
shmctl01 3 TPASS : new mode and change time are correct
shmctl01 4 TPASS : shared memory appears to be removed
<<<execution_status>>>
initiation_status="ok"
duration=3 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmctl02 stime=1372413800
cmdline="shmctl02"
contacts=""
analysis=exit
<<<test_output>>>
shmctl02 1 TPASS : expected failure - errno = 13 : Permission denied
shmctl02 2 TPASS : expected failure - errno = 14 : Bad address
shmctl02 3 TPASS : expected failure - errno = 14 : Bad address
shmctl02 4 TPASS : expected failure - errno = 22 : Invalid argument
shmctl02 5 TPASS : expected failure - errno = 22 : Invalid argument
shmctl02 6 TCONF : shmctl() did not fail for non-root user.This may be okay for your distribution.
shmctl02 7 TPASS : expected failure - errno = 1 : Operation not permitted
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
<<<test_start>>>
tag=shmctl03 stime=1372413800
cmdline="shmctl03"
contacts=""
analysis=exit
<<<test_output>>>
shmctl03 1 TPASS : expected failure - errno = 13 : Permission denied
shmctl03 2 TPASS : expected failure - errno = 1 : Operation not permitted
shmctl03 3 TPASS : expected failure - errno = 1 : Operation not permitted
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmctl04 stime=1372413800
cmdline="shmctl04"
contacts=""
analysis=exit
<<<test_output>>>
shmctl04 1 TPASS : SHM_INFO call succeeded
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmdt01 stime=1372413800
cmdline="shmdt01"
contacts=""
analysis=exit
<<<test_output>>>
shmdt01 1 TPASS : shared memory detached correctly
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmdt02 stime=1372413800
cmdline="shmdt02"
contacts=""
analysis=exit
<<<test_output>>>
shmdt02 1 TPASS : expected failure - errno = 22 : Invalid argument
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmget01 stime=1372413800
cmdline="shmget01"
contacts=""
analysis=exit
<<<test_output>>>
shmget01 1 TPASS : size, pid & mode are correct
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmget02 stime=1372413800
cmdline="shmget02"
contacts=""
analysis=exit
<<<test_output>>>
shmget02 1 TPASS : expected failure - errno = 22 : Invalid argument
shmget02 2 TPASS : expected failure - errno = 22 : Invalid argument
shmget02 3 TPASS : expected failure - errno = 17 : File exists
shmget02 4 TPASS : expected failure - errno = 2 : No such file or directory
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmget03 stime=1372413800
cmdline="shmget03"
contacts=""
analysis=exit
<<<test_output>>>
shmget03 1 TPASS : expected failure - errno = 28 : No space left on device
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=1 cstime=5
<<<test_end>>>
<<<test_start>>>
tag=shmget04 stime=1372413800
cmdline="shmget04"
contacts=""
analysis=exit
<<<test_output>>>
shmget04 1 TPASS : expected failure - errno = 13 : Permission denied
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=0
<<<test_end>>>
<<<test_start>>>
tag=shmget05 stime=1372413800
cmdline="shmget05"
contacts=""
analysis=exit
<<<test_output>>>
shmget05 1 TPASS : expected failure - errno = 13 : Permission denied
incrementing stop
<<<execution_status>>>
initiation_status="ok"
duration=0 termination_type=exited termination_id=0 corefile=no
cutime=0 cstime=1
<<<test_end>>>
INFO: ltp-pan reported all tests PASS
LTP Version: 20130503
###############################################################
Done executing testcases.
LTP Version: 20130503
###############################################################
[-- Attachment #3: 3.10.0-rc7-next20130628-3-iniza-small.patch --]
[-- Type: application/octet-stream, Size: 37055 bytes --]
Dave Airlie (1):
drm/omap: drop the !FB_OMAP2 dep
Davidlohr Bueso (11):
ipc,shm: introduce lockless functions to obtain the ipc object
ipc,shm: shorten critical region in shmctl_down
ipc: drop ipcctl_pre_down
ipc,shm: introduce shmctl_nolock
ipc,shm: make shmctl_nolock lockless
ipc,shm: shorten critical region for shmctl
ipc,shm: cleanup do_shmat pasta
ipc,shm: shorten critical region for shmat
ipc: rename ids->rw_mutex
ipc,msg: drop msg_unlock
ipc: document general ipc locking scheme
Sedat Dilek (9):
kbuild: deb-pkg: Try to determine distribution
kbuild: deb-pkg: Bump year in debian/copyright file
kbuild: deb-pkg: Update git repository URL in debian/copyright file
Merge tag 'next-20130628' of git://git.kernel.org/.../next/linux-next into Linux-Next-v20130628
Merge branch 'deb-pkg-3.10-fixes' into 3.10.0-rc7-next20130628-1-iniza-small
Merge branch 'drm-next-fixes' into 3.10.0-rc7-next20130628-1-iniza-small
Revert "drm: kms_helper: don't lose hotplug event"
Merge branch 'drm-next-fixes' into 3.10.0-rc7-next20130628-2-iniza-small
Merge branch 'sysv-ipc-shm-optimizations-next-testing' into 3.10.0-rc7-next20130628-3-iniza-small
drivers/gpu/drm/drm_crtc_helper.c | 32 +----
drivers/gpu/drm/omapdrm/Kconfig | 2 +-
include/drm/drm_crtc.h | 1 -
include/linux/ipc_namespace.h | 2 +-
ipc/msg.c | 25 ++--
ipc/namespace.c | 4 +-
ipc/sem.c | 24 ++--
ipc/shm.c | 239 +++++++++++++++++++++++---------------
ipc/util.c | 57 ++++-----
ipc/util.h | 7 +-
scripts/package/builddeb | 19 ++-
11 files changed, 217 insertions(+), 195 deletions(-)
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index f6829ba..738a429 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -122,7 +122,6 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
int count = 0;
int mode_flags = 0;
bool verbose_prune = true;
- enum drm_connector_status old_status;
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
drm_get_connector_name(connector));
@@ -138,32 +137,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
if (connector->funcs->force)
connector->funcs->force(connector);
} else {
- old_status = connector->status;
-
connector->status = connector->funcs->detect(connector, true);
-
- /*
- * Normally either the driver's hpd code or the poll loop should
- * pick up any changes and fire the hotplug event. But if
- * userspace sneaks in a probe, we might miss a change. Hence
- * check here, and if anything changed start the hotplug code.
- */
- if (old_status != connector->status) {
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
- connector->base.id,
- drm_get_connector_name(connector),
- old_status, connector->status);
-
- /*
- * The hotplug event code might call into the fb
- * helpers, and so expects that we do not hold any
- * locks. Fire up the poll struct instead, it will
- * disable itself again.
- */
- dev->mode_config.delayed_event = true;
- schedule_delayed_work(&dev->mode_config.output_poll_work,
- 0);
- }
}
/* Re-enable polling in case the global poll config changed. */
@@ -1011,11 +985,7 @@ static void output_poll_execute(struct work_struct *work)
struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
struct drm_connector *connector;
enum drm_connector_status old_status;
- bool repoll = false, changed;
-
- /* Pick up any changes detected by the probe functions. */
- changed = dev->mode_config.delayed_event;
- dev->mode_config.delayed_event = false;
+ bool repoll = false, changed = false;
if (!drm_kms_helper_poll)
return;
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 45875a0..20c41e7 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -1,7 +1,7 @@
config DRM_OMAP
tristate "OMAP DRM"
- depends on DRM && !FB_OMAP2
+ depends on DRM
depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
depends on OMAP2_DSS
select DRM_KMS_HELPER
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 663c3ab..fa12a2f 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -811,7 +811,6 @@ struct drm_mode_config {
/* output poll support */
bool poll_enabled;
bool poll_running;
- bool delayed_event;
struct delayed_work output_poll_work;
/* pointers to standard properties */
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index c4d870b..19c19a5 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -22,7 +22,7 @@ struct ipc_ids {
int in_use;
unsigned short seq;
unsigned short seq_max;
- struct rw_semaphore rw_mutex;
+ struct rw_semaphore rwsem;
struct idr ipcs_idr;
int next_id;
};
diff --git a/ipc/msg.c b/ipc/msg.c
index bd60d7e..14d64f8 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -70,8 +70,6 @@ struct msg_sender {
#define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS])
-#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
-
static void freeque(struct ipc_namespace *, struct kern_ipc_perm *);
static int newque(struct ipc_namespace *, struct ipc_params *);
#ifdef CONFIG_PROC_FS
@@ -172,7 +170,7 @@ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
* @ns: namespace
* @params: ptr to the structure that contains the key and msgflg
*
- * Called with msg_ids.rw_mutex held (writer)
+ * Called with msg_ids.rwsem held (writer)
*/
static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{
@@ -259,8 +257,8 @@ static void expunge_all(struct msg_queue *msq, int res)
* removes the message queue from message queue ID IDR, and cleans up all the
* messages associated with this queue.
*
- * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
- * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
+ * msg_ids.rwsem (writer) and the spinlock for this message queue are held
+ * before freeque() is called. msg_ids.rwsem remains locked on exit.
*/
static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -270,7 +268,8 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
expunge_all(msq, -EIDRM);
ss_wakeup(&msq->q_senders, 1);
msg_rmid(ns, msq);
- msg_unlock(msq);
+ ipc_unlock_object(&msq->q_perm);
+ rcu_read_unlock();
list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) {
atomic_dec(&ns->msg_hdrs);
@@ -282,7 +281,7 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
}
/*
- * Called with msg_ids.rw_mutex and ipcp locked.
+ * Called with msg_ids.rwsem and ipcp locked.
*/
static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
{
@@ -386,9 +385,9 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
}
/*
- * This function handles some msgctl commands which require the rw_mutex
+ * This function handles some msgctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
struct msqid_ds __user *buf, int version)
@@ -403,7 +402,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
return -EFAULT;
}
- down_write(&msg_ids(ns).rw_mutex);
+ down_write(&msg_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
@@ -459,7 +458,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&msg_ids(ns).rw_mutex);
+ up_write(&msg_ids(ns).rwsem);
return err;
}
@@ -494,7 +493,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
msginfo.msgmnb = ns->msg_ctlmnb;
msginfo.msgssz = MSGSSZ;
msginfo.msgseg = MSGSEG;
- down_read(&msg_ids(ns).rw_mutex);
+ down_read(&msg_ids(ns).rwsem);
if (cmd == MSG_INFO) {
msginfo.msgpool = msg_ids(ns).in_use;
msginfo.msgmap = atomic_read(&ns->msg_hdrs);
@@ -505,7 +504,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
msginfo.msgtql = MSGTQL;
}
max_id = ipc_get_maxid(&msg_ids(ns));
- up_read(&msg_ids(ns).rw_mutex);
+ up_read(&msg_ids(ns).rwsem);
if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
return -EFAULT;
return (max_id < 0) ? 0 : max_id;
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 7ee61bf..67dc744 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -81,7 +81,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
int next_id;
int total, in_use;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
in_use = ids->in_use;
@@ -93,7 +93,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
free(ns, perm);
total++;
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
}
static void free_ipc_ns(struct ipc_namespace *ns)
diff --git a/ipc/sem.c b/ipc/sem.c
index 4108889..69b6a21 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -322,7 +322,7 @@ static inline void sem_unlock(struct sem_array *sma, int locknum)
}
/*
- * sem_lock_(check_) routines are called in the paths where the rw_mutex
+ * sem_lock_(check_) routines are called in the paths where the rwsem
* is not held.
*
* The caller holds the RCU read lock.
@@ -426,7 +426,7 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
* @ns: namespace
* @params: ptr to the structure that contains key, semflg and nsems
*
- * Called with sem_ids.rw_mutex held (as a writer)
+ * Called with sem_ids.rwsem held (as a writer)
*/
static int newary(struct ipc_namespace *ns, struct ipc_params *params)
@@ -492,7 +492,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
{
@@ -503,7 +503,7 @@ static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
}
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -994,8 +994,8 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
return semzcnt;
}
-/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked
- * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex
+/* Free a semaphore set. freeary() is called with sem_ids.rwsem locked
+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rwsem
* remains locked on exit.
*/
static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
@@ -1116,7 +1116,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
seminfo.semmnu = SEMMNU;
seminfo.semmap = SEMMAP;
seminfo.semume = SEMUME;
- down_read(&sem_ids(ns).rw_mutex);
+ down_read(&sem_ids(ns).rwsem);
if (cmd == SEM_INFO) {
seminfo.semusz = sem_ids(ns).in_use;
seminfo.semaem = ns->used_sems;
@@ -1125,7 +1125,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
seminfo.semaem = SEMAEM;
}
max_id = ipc_get_maxid(&sem_ids(ns));
- up_read(&sem_ids(ns).rw_mutex);
+ up_read(&sem_ids(ns).rwsem);
if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
return -EFAULT;
return (max_id < 0) ? 0: max_id;
@@ -1431,9 +1431,9 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
}
/*
- * This function handles some semctl commands which require the rw_mutex
+ * This function handles some semctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int semctl_down(struct ipc_namespace *ns, int semid,
int cmd, int version, void __user *p)
@@ -1448,7 +1448,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
return -EFAULT;
}
- down_write(&sem_ids(ns).rw_mutex);
+ down_write(&sem_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd,
@@ -1487,7 +1487,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&sem_ids(ns).rw_mutex);
+ up_write(&sem_ids(ns).rwsem);
return err;
}
diff --git a/ipc/shm.c b/ipc/shm.c
index c6b4ad5..9017786 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -19,6 +19,9 @@
* namespaces support
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
+ *
+ * Better ipc lock (kern_ipc_perm.lock) handling
+ * Davidlohr Bueso <davidlohr.bueso@hp.com>, June 2013.
*/
#include <linux/slab.h>
@@ -80,8 +83,8 @@ void shm_init_ns(struct ipc_namespace *ns)
}
/*
- * Called with shm_ids.rw_mutex (writer) and the shp structure locked.
- * Only shm_ids.rw_mutex remains locked on exit.
+ * Called with shm_ids.rwsem (writer) and the shp structure locked.
+ * Only shm_ids.rwsem remains locked on exit.
*/
static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -124,8 +127,28 @@ void __init shm_init (void)
IPC_SHM_IDS, sysvipc_shm_proc_show);
}
+static inline struct shmid_kernel *shm_obtain_object(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_obtain_object(&shm_ids(ns), id);
+
+ if (IS_ERR(ipcp))
+ return ERR_CAST(ipcp);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&shm_ids(ns), id);
+
+ if (IS_ERR(ipcp))
+ return ERR_CAST(ipcp);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
/*
- * shm_lock_(check_) routines are called in the paths where the rw_mutex
+ * shm_lock_(check_) routines are called in the paths where the rwsem
* is not necessarily held.
*/
static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
@@ -182,7 +205,7 @@ static void shm_open(struct vm_area_struct *vma)
* @ns: namespace
* @shp: struct to free
*
- * It has to be called with shp and shm_ids.rw_mutex (writer) locked,
+ * It has to be called with shp and shm_ids.rwsem (writer) locked,
* but returns with shp unlocked and freed.
*/
static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
@@ -230,7 +253,7 @@ static void shm_close(struct vm_area_struct *vma)
struct shmid_kernel *shp;
struct ipc_namespace *ns = sfd->ns;
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
/* remove from the list of attaches of the shm segment */
shp = shm_lock(ns, sfd->id);
BUG_ON(IS_ERR(shp));
@@ -241,10 +264,10 @@ static void shm_close(struct vm_area_struct *vma)
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_current(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -275,7 +298,7 @@ static int shm_try_destroy_current(int id, void *p, void *data)
return 0;
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_orphaned(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -286,7 +309,7 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
* We want to destroy segments without users and with already
* exit'ed originating process.
*
- * As shp->* are changed under rw_mutex, it's safe to skip shp locking.
+ * As shp->* are changed under rwsem, it's safe to skip shp locking.
*/
if (shp->shm_creator != NULL)
return 0;
@@ -300,10 +323,10 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
void shm_destroy_orphaned(struct ipc_namespace *ns)
{
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
@@ -315,10 +338,10 @@ void exit_shm(struct task_struct *task)
return;
/* Destroy all already created segments, but not mapped yet */
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -452,7 +475,7 @@ static const struct vm_operations_struct shm_vm_ops = {
* @ns: namespace
* @params: ptr to the structure that contains key, size and shmflg
*
- * Called with shm_ids.rw_mutex held as a writer.
+ * Called with shm_ids.rwsem held as a writer.
*/
static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
@@ -560,7 +583,7 @@ no_file:
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
{
@@ -571,7 +594,7 @@ static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -684,7 +707,7 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
/*
* Calculate and add used RSS and swap pages of a shm.
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_add_rss_swap(struct shmid_kernel *shp,
unsigned long *rss_add, unsigned long *swp_add)
@@ -711,7 +734,7 @@ static void shm_add_rss_swap(struct shmid_kernel *shp,
}
/*
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
unsigned long *swp)
@@ -740,9 +763,9 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
}
/*
- * This function handles some shmctl commands which require the rw_mutex
+ * This function handles some shmctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
struct shmid_ds __user *buf, int version)
@@ -757,14 +780,13 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
return -EFAULT;
}
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
rcu_read_lock();
- ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd,
- &shmid64.shm_perm, 0);
+ ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
+ &shmid64.shm_perm, 0);
if (IS_ERR(ipcp)) {
err = PTR_ERR(ipcp);
- /* the ipc lock is not held upon failure */
goto out_unlock1;
}
@@ -772,14 +794,16 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
err = security_shm_shmctl(shp, cmd);
if (err)
- goto out_unlock0;
+ goto out_unlock1;
switch (cmd) {
case IPC_RMID:
+ ipc_lock_object(&shp->shm_perm);
/* do_shm_rmid unlocks the ipc object and rcu */
do_shm_rmid(ns, ipcp);
goto out_up;
case IPC_SET:
+ ipc_lock_object(&shp->shm_perm);
err = ipc_update_perm(&shmid64.shm_perm, ipcp);
if (err)
goto out_unlock0;
@@ -787,6 +811,7 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
break;
default:
err = -EINVAL;
+ goto out_unlock1;
}
out_unlock0:
@@ -794,33 +819,28 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
return err;
}
-SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
+ int cmd, int version, void __user *buf)
{
+ int err;
struct shmid_kernel *shp;
- int err, version;
- struct ipc_namespace *ns;
- if (cmd < 0 || shmid < 0) {
- err = -EINVAL;
- goto out;
+ /* preliminary security checks for *_INFO */
+ if (cmd == IPC_INFO || cmd == SHM_INFO) {
+ err = security_shm_shmctl(NULL, cmd);
+ if (err)
+ return err;
}
- version = ipc_parse_version(&cmd);
- ns = current->nsproxy->ipc_ns;
-
- switch (cmd) { /* replace with proc interface ? */
+ switch (cmd) {
case IPC_INFO:
{
struct shminfo64 shminfo;
- err = security_shm_shmctl(NULL, cmd);
- if (err)
- return err;
-
memset(&shminfo, 0, sizeof(shminfo));
shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
shminfo.shmmax = ns->shm_ctlmax;
@@ -830,9 +850,9 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
if(copy_shminfo_to_user (buf, &shminfo, version))
return -EFAULT;
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if(err<0)
err = 0;
@@ -842,19 +862,15 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
{
struct shm_info shm_info;
- err = security_shm_shmctl(NULL, cmd);
- if (err)
- return err;
-
memset(&shm_info, 0, sizeof(shm_info));
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
shm_info.used_ids = shm_ids(ns).in_use;
shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
shm_info.shm_tot = ns->shm_tot;
shm_info.swap_attempts = 0;
shm_info.swap_successes = 0;
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if (copy_to_user(buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
@@ -869,27 +885,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
struct shmid64_ds tbuf;
int result;
+ rcu_read_lock();
if (cmd == SHM_STAT) {
- shp = shm_lock(ns, shmid);
+ shp = shm_obtain_object(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
result = shp->shm_perm.id;
} else {
- shp = shm_lock_check(ns, shmid);
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
result = 0;
}
+
err = -EACCES;
if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
goto out_unlock;
+
err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock;
+
memset(&tbuf, 0, sizeof(tbuf));
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
tbuf.shm_segsz = shp->shm_segsz;
@@ -899,43 +919,76 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
tbuf.shm_cpid = shp->shm_cprid;
tbuf.shm_lpid = shp->shm_lprid;
tbuf.shm_nattch = shp->shm_nattch;
- shm_unlock(shp);
- if(copy_shmid_to_user (buf, &tbuf, version))
+ rcu_read_unlock();
+
+ if (copy_shmid_to_user (buf, &tbuf, version))
err = -EFAULT;
else
err = result;
goto out;
}
+ default:
+ return -EINVAL;
+ }
+
+out_unlock:
+ rcu_read_unlock();
+out:
+ return err;
+}
+
+SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+{
+ struct shmid_kernel *shp;
+ int err, version;
+ struct ipc_namespace *ns;
+
+ if (cmd < 0 || shmid < 0)
+ return -EINVAL;
+
+ version = ipc_parse_version(&cmd);
+ ns = current->nsproxy->ipc_ns;
+
+ switch (cmd) {
+ case IPC_INFO:
+ case SHM_INFO:
+ case SHM_STAT:
+ case IPC_STAT:
+ return shmctl_nolock(ns, shmid, cmd, version, buf);
+ case IPC_RMID:
+ case IPC_SET:
+ return shmctl_down(ns, shmid, cmd, buf, version);
case SHM_LOCK:
case SHM_UNLOCK:
{
struct file *shm_file;
- shp = shm_lock_check(ns, shmid);
+ rcu_read_lock();
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock1;
}
audit_ipc_obj(&(shp->shm_perm));
+ err = security_shm_shmctl(shp, cmd);
+ if (err)
+ goto out_unlock1;
+ ipc_lock_object(&shp->shm_perm);
if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) {
kuid_t euid = current_euid();
err = -EPERM;
if (!uid_eq(euid, shp->shm_perm.uid) &&
!uid_eq(euid, shp->shm_perm.cuid))
- goto out_unlock;
+ goto out_unlock0;
if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK))
- goto out_unlock;
+ goto out_unlock0;
}
- err = security_shm_shmctl(shp, cmd);
- if (err)
- goto out_unlock;
-
shm_file = shp->shm_file;
if (is_file_hugepages(shm_file))
- goto out_unlock;
+ goto out_unlock0;
if (cmd == SHM_LOCK) {
struct user_struct *user = current_user();
@@ -944,32 +997,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
shp->shm_perm.mode |= SHM_LOCKED;
shp->mlock_user = user;
}
- goto out_unlock;
+ goto out_unlock0;
}
/* SHM_UNLOCK */
if (!(shp->shm_perm.mode & SHM_LOCKED))
- goto out_unlock;
+ goto out_unlock0;
shmem_lock(shm_file, 0, shp->mlock_user);
shp->shm_perm.mode &= ~SHM_LOCKED;
shp->mlock_user = NULL;
get_file(shm_file);
- shm_unlock(shp);
+ ipc_unlock_object(&shp->shm_perm);
+ rcu_read_unlock();
shmem_unlock_mapping(shm_file->f_mapping);
+
fput(shm_file);
- goto out;
- }
- case IPC_RMID:
- case IPC_SET:
- err = shmctl_down(ns, shmid, cmd, buf, version);
return err;
+ }
default:
return -EINVAL;
}
-out_unlock:
- shm_unlock(shp);
-out:
+out_unlock0:
+ ipc_unlock_object(&shp->shm_perm);
+out_unlock1:
+ rcu_read_unlock();
return err;
}
@@ -1037,7 +1089,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
* additional creator id...
*/
ns = current->nsproxy->ipc_ns;
- shp = shm_lock_check(ns, shmid);
+ rcu_read_lock();
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
goto out;
@@ -1051,24 +1104,31 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
if (err)
goto out_unlock;
+ ipc_lock_object(&shp->shm_perm);
path = shp->shm_file->f_path;
path_get(&path);
shp->shm_nattch++;
size = i_size_read(path.dentry->d_inode);
- shm_unlock(shp);
+ ipc_unlock_object(&shp->shm_perm);
+ rcu_read_unlock();
err = -ENOMEM;
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
- if (!sfd)
- goto out_put_dentry;
+ if (!sfd) {
+ path_put(&path);
+ goto out_nattch;
+ }
file = alloc_file(&path, f_mode,
is_file_hugepages(shp->shm_file) ?
&shm_file_operations_huge :
&shm_file_operations);
err = PTR_ERR(file);
- if (IS_ERR(file))
- goto out_free;
+ if (IS_ERR(file)) {
+ kfree(sfd);
+ path_put(&path);
+ goto out_nattch;
+ }
file->private_data = sfd;
file->f_mapping = shp->shm_file->f_mapping;
@@ -1094,7 +1154,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
addr > current->mm->start_stack - size - PAGE_SIZE * 5)
goto invalid;
}
-
+
addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate);
*raddr = addr;
err = 0;
@@ -1109,7 +1169,7 @@ out_fput:
fput(file);
out_nattch:
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
shp = shm_lock(ns, shmid);
BUG_ON(IS_ERR(shp));
shp->shm_nattch--;
@@ -1117,20 +1177,13 @@ out_nattch:
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
-
-out:
+ up_write(&shm_ids(ns).rwsem);
return err;
out_unlock:
- shm_unlock(shp);
- goto out;
-
-out_free:
- kfree(sfd);
-out_put_dentry:
- path_put(&path);
- goto out_nattch;
+ rcu_read_unlock();
+out:
+ return err;
}
SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
diff --git a/ipc/util.c b/ipc/util.c
index 4704223..69ee3c1 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -15,6 +15,14 @@
* Jun 2006 - namespaces ssupport
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
+ *
+ * General sysv ipc locking scheme:
+ * when doing ipc id lookups, take the ids->rwsem
+ * rcu_read_lock()
+ * obtain the ipc object (kern_ipc_perm)
+ * perform security, capabilities, auditing and permission checks, etc.
+ * acquire the ipc lock (kern_ipc_perm.lock) throught ipc_lock_object()
+ * perform data updates (ie: SET, RMID, LOCK/UNLOCK commands)
*/
#include <linux/mm.h>
@@ -119,7 +127,7 @@ __initcall(ipc_init);
void ipc_init_ids(struct ipc_ids *ids)
{
- init_rwsem(&ids->rw_mutex);
+ init_rwsem(&ids->rwsem);
ids->in_use = 0;
ids->seq = 0;
@@ -174,7 +182,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
* @ids: Identifier set
* @key: The key to find
*
- * Requires ipc_ids.rw_mutex locked.
+ * Requires ipc_ids.rwsem locked.
* Returns the LOCKED pointer to the ipc structure if found or NULL
* if not.
* If key is found ipc points to the owning ipc structure
@@ -208,7 +216,7 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
* ipc_get_maxid - get the last assigned id
* @ids: IPC identifier set
*
- * Called with ipc_ids.rw_mutex held.
+ * Called with ipc_ids.rwsem held.
*/
int ipc_get_maxid(struct ipc_ids *ids)
@@ -246,7 +254,7 @@ int ipc_get_maxid(struct ipc_ids *ids)
* is returned. The 'new' entry is returned in a locked state on success.
* On failure the entry is not locked and a negative err-code is returned.
*
- * Called with writer ipc_ids.rw_mutex held.
+ * Called with writer ipc_ids.rwsem held.
*/
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
{
@@ -312,9 +320,9 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
{
int err;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
err = ops->getnew(ns, params);
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -331,7 +339,7 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
*
* On success, the IPC id is returned.
*
- * It is called with ipc_ids.rw_mutex and ipcp->lock held.
+ * It is called with ipc_ids.rwsem and ipcp->lock held.
*/
static int ipc_check_perms(struct ipc_namespace *ns,
struct kern_ipc_perm *ipcp,
@@ -376,7 +384,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
* Take the lock as a writer since we are potentially going to add
* a new entry + read locks are not "upgradable"
*/
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
ipcp = ipc_findkey(ids, params->key);
if (ipcp == NULL) {
/* key not used */
@@ -402,7 +410,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
}
ipc_unlock(ipcp);
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -413,7 +421,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
* @ids: IPC identifier set
* @ipcp: ipc perm structure containing the identifier to remove
*
- * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
+ * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
* before this function is called, and remain locked on the exit.
*/
@@ -621,7 +629,7 @@ struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id)
}
/**
- * ipc_lock - Lock an ipc structure without rw_mutex held
+ * ipc_lock - Lock an ipc structure without rwsem held
* @ids: IPC identifier set
* @id: ipc id to look for
*
@@ -746,26 +754,10 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
* It must be called without any lock held and
* - retrieves the ipc with the given id in the given table.
* - performs some audit and permission check, depending on the given cmd
- * - returns the ipc with the ipc lock held in case of success
- * or an err-code without any lock held otherwise.
+ * - returns a pointer to the ipc object or otherwise, the corresponding error.
*
- * Call holding the both the rw_mutex and the rcu read lock.
+ * Call holding the both the rwsem and the rcu read lock.
*/
-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm)
-{
- struct kern_ipc_perm *ipcp;
-
- ipcp = ipcctl_pre_down_nolock(ns, ids, id, cmd, perm, extra_perm);
- if (IS_ERR(ipcp))
- goto out;
-
- spin_lock(&ipcp->lock);
-out:
- return ipcp;
-}
-
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
struct ipc64_perm *perm, int extra_perm)
@@ -782,8 +774,7 @@ struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
audit_ipc_obj(ipcp);
if (cmd == IPC_SET)
- audit_ipc_set_perm(extra_perm, perm->uid,
- perm->gid, perm->mode);
+ audit_ipc_set_perm(extra_perm, perm->uid, perm->gid, perm->mode);
euid = current_euid();
if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) ||
@@ -884,7 +875,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
* Take the lock - this will be released by the corresponding
* call to stop().
*/
- down_read(&ids->rw_mutex);
+ down_read(&ids->rwsem);
/* pos < 0 is invalid */
if (*pos < 0)
@@ -911,7 +902,7 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it)
ids = &iter->ns->ids[iface->ids];
/* Release the lock we took in start() */
- up_read(&ids->rw_mutex);
+ up_read(&ids->rwsem);
}
static int sysvipc_proc_show(struct seq_file *s, void *it)
diff --git a/ipc/util.h b/ipc/util.h
index b6a6a88..0a362ff 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -94,10 +94,10 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
#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->rwsem acquired for writing */
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
-/* must be called with ids->rw_mutex acquired for reading */
+/* must be called with ids->rwsem acquired for reading */
int ipc_get_maxid(struct ipc_ids *);
/* must be called with both locks acquired. */
@@ -131,9 +131,6 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out);
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
struct ipc64_perm *perm, int extra_perm);
-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm);
#ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
/* On IA-64, we always use the "64-bit version" of the IPC structures. */
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index acb8650..7d7c9d8 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -172,9 +172,22 @@ else
fi
maintainer="$name <$email>"
+# Try to determine distribution
+if [ -e $(which lsb_release) ]; then
+ codename=$(lsb_release --codename --short)
+ if [ "$codename" != "" ]; then
+ distribution=$codename
+ else
+ distribution="UNRELEASED"
+ echo "WARNING: The distribution could NOT be determined!"
+ fi
+else
+ echo "HINT: Install lsb_release binary, this helps to identify your distribution!"
+fi
+
# Generate a simple changelog template
cat <<EOF > debian/changelog
-linux-upstream ($packageversion) unstable; urgency=low
+linux-upstream ($packageversion) $distribution; urgency=low
* Custom built Linux kernel.
@@ -188,10 +201,10 @@ This is a packacked upstream version of the Linux kernel.
The sources may be found at most Linux ftp sites, including:
ftp://ftp.kernel.org/pub/linux/kernel
-Copyright: 1991 - 2009 Linus Torvalds and others.
+Copyright: 1991 - 2013 Linus Torvalds and others.
The git repository for mainline kernel development is at:
-git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
[-- Attachment #4: LTP_RUN_ON-2013_Jun_28-11h_59m_54s.log --]
[-- Type: application/octet-stream, Size: 4790 bytes --]
Test Start Time: Fri Jun 28 11:59:55 2013
-----------------------------------------
Testcase Result Exit Value
-------- ------ ----------
pipeio_1 PASS 0
pipeio_3 PASS 0
pipeio_4 PASS 0
pipeio_5 PASS 0
pipeio_6 PASS 0
pipeio_8 PASS 0
sem01 PASS 0
sem02 PASS 0
message_queue_test_01 PASS 0
message_queue_test_02_get PASS 0
message_queue_test_02_snd PASS 0
message_queue_test_02_rcv PASS 0
message_queue_test_02_ctl PASS 0
message_queue_test_04 PASS 0
message_queue_test_05 PASS 0
pipe_test_01 PASS 0
pipe_test_02 PASS 0
semaphore_test_01 PASS 0
semaphore_test_02 PASS 0
semaphore_test_03 PASS 0
shmem_test_01 PASS 0
shmem_test_02 PASS 0
shmem_test_03 PASS 0
shmem_test_04 PASS 0
shmem_test_05 PASS 0
shmem_test_06 PASS 0
shmem_test_07 PASS 0
signal_test_01 PASS 0
signal_test_02 PASS 0
signal_test_03 PASS 0
signal_test_04 PASS 0
signal_test_05 PASS 0
signal_test_06 PASS 0
signal_test_07 PASS 0
msgctl01 PASS 0
msgctl02 PASS 0
msgctl03 PASS 0
msgctl04 PASS 0
msgctl05 PASS 0
msgctl06 PASS 0
msgctl07 PASS 0
msgctl08 PASS 0
msgctl09 PASS 0
msgctl10 PASS 0
msgctl11 PASS 0
msgget01 PASS 0
msgget02 PASS 0
msgget03 PASS 0
msgget04 PASS 0
msgrcv01 PASS 0
msgrcv02 PASS 0
msgrcv03 PASS 0
msgrcv04 PASS 0
msgrcv05 PASS 0
msgrcv06 PASS 0
msgsnd01 PASS 0
msgsnd02 PASS 0
msgsnd03 PASS 0
msgsnd04 PASS 0
msgsnd05 PASS 0
msgsnd06 PASS 0
semctl01 PASS 0
semctl02 PASS 0
semctl03 PASS 0
semctl04 PASS 0
semctl05 PASS 0
semctl06 PASS 0
semctl07 PASS 0
semget01 PASS 0
semget02 PASS 0
semget03 PASS 0
semget05 PASS 0
semget06 PASS 0
semop01 PASS 0
semop02 PASS 0
semop03 PASS 0
semop04 PASS 0
semop05 PASS 0
shmat01 PASS 0
shmat02 PASS 0
shmat03 PASS 0
shmctl01 PASS 0
shmctl02 PASS 0
shmctl03 PASS 0
shmctl04 PASS 0
shmdt01 PASS 0
shmdt02 PASS 0
shmget01 PASS 0
shmget02 PASS 0
shmget03 PASS 0
shmget04 PASS 0
shmget05 PASS 0
-----------------------------------------------
Total Tests: 92
Total Failures: 0
Kernel Version: 3.10.0-rc7-next20130628-3-iniza-small
Machine Architecture: x86_64
Hostname: fambox
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 00/11] sysv ipc shared mem optimizations
2013-06-25 23:55 ` [PATCH 00/11] sysv ipc shared mem optimizations Sedat Dilek
@ 2013-06-26 8:08 ` Sedat Dilek
2013-06-28 10:10 ` Sedat Dilek
0 siblings, 1 reply; 16+ messages in thread
From: Sedat Dilek @ 2013-06-26 8:08 UTC (permalink / raw)
To: Davidlohr Bueso; +Cc: linux-mm, Andrew Morton, Rik van Riel, Manfred Spraul
[-- Attachment #1: Type: text/plain, Size: 1379 bytes --]
On Wed, Jun 26, 2013 at 1:55 AM, Sedat Dilek <sedat.dilek@gmail.com> wrote:
> Hi,
>
> I have tested the patchset "sysv ipc shared mem optimizations" on top
> of next-20130618.
>
> My typical rebuild with fakeroot & 'make deb-pkg' was fine.
>
> Further tests done with LPT-full (20130503): IPC and SYSCALLS
> test-cases ran successfully.
>
> I am attaching the tarball I have sent already to Davidlohr which contains:
>
> 35070 Jun 26 00:37 3.10.0-rc6-next20130618-1-iniza-small.patch
> 114002 Jun 26 00:48 config-3.10.0-rc6-next20130618-1-iniza-small
> 84489 Jun 26 00:55 dmesg_3.10.0-rc6-next20130618-1-iniza-small.txt
> 38996 Jun 26 00:57 runltp-f-ipc_3.10.0-rc6-next20130618-1-iniza-small_dash.txt
> 760276 Jun 26 01:12
> runltp-f-syscalls_3.10.0-rc6-next20130618-1-iniza-small_dash.txt
>
> NOTES:
> 1. 09/11 needed a small refresh as v2 (attached).
> 2. [ PATCH] ipc,msq: fix race in msgrcv(2) (as v2) applied on top of
> all (attached).
>
> Please feel free to add my Tested-by to the whole series.
>
I have re-tested this patchset also against next-20130624 (09/11
original fits here, 08/11 needs to be cleanpatch-ed).
( In addition I still need the ipc-msg-next fix mentioned above which
is now in akpm's mmots. )
- Sedat -
[1] http://ozlabs.org/~akpm/mmots/broken-out/ipcmsg-shorten-critical-region-in-msgrcv-fix-race-in-msgrcv2.patch
> Regards,
> - Sedat -
[-- Attachment #2: 3.10.0-rc7-next20130624-4-iniza-small.patch --]
[-- Type: application/octet-stream, Size: 35558 bytes --]
Davidlohr Bueso (12):
ipc,msq: fix race in msgrcv(2)
ipc,shm: introduce lockless functions to obtain the ipc object
ipc,shm: shorten critical region in shmctl_down
ipc: drop ipcctl_pre_down
ipc,shm: introduce shmctl_nolock
ipc,shm: make shmctl_nolock lockless
ipc,shm: shorten critical region for shmctl
ipc,shm: cleanup do_shmat pasta
ipc,shm: shorten critical region for shmat
ipc: rename ids->rw_mutex
ipc,msg: drop msg_unlock
ipc: document general ipc locking scheme
Sedat Dilek (7):
kbuild: deb-pkg: Try to determine distribution
kbuild: deb-pkg: Bump year in debian/copyright file
kbuild: deb-pkg: Update git repository URL in debian/copyright file
Merge tag 'next-20130624' of git://git.kernel.org/.../next/linux-next into Linux-Next-v20130624
Merge branch 'deb-pkg-3.10-fixes' into 3.10.0-rc7-next20130624-1-iniza-small
Merge branch 'ipc-msg-next-fixes-from-akpm-mmots' into 3.10.0-rc7-next20130624-4-iniza-small
Merge branch 'sysv-ipc-shm-optimizations-next20130624-testing' into 3.10.0-rc7-next20130624-4-iniza-small
include/linux/ipc_namespace.h | 2 +-
ipc/msg.c | 36 +++----
ipc/namespace.c | 4 +-
ipc/sem.c | 24 ++---
ipc/shm.c | 239 ++++++++++++++++++++++++++----------------
ipc/util.c | 57 +++++-----
ipc/util.h | 7 +-
scripts/package/builddeb | 19 +++-
8 files changed, 220 insertions(+), 168 deletions(-)
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index c4d870b..19c19a5 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -22,7 +22,7 @@ struct ipc_ids {
int in_use;
unsigned short seq;
unsigned short seq_max;
- struct rw_semaphore rw_mutex;
+ struct rw_semaphore rwsem;
struct idr ipcs_idr;
int next_id;
};
diff --git a/ipc/msg.c b/ipc/msg.c
index a1cf70e..14d64f8 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -70,8 +70,6 @@ struct msg_sender {
#define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS])
-#define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
-
static void freeque(struct ipc_namespace *, struct kern_ipc_perm *);
static int newque(struct ipc_namespace *, struct ipc_params *);
#ifdef CONFIG_PROC_FS
@@ -172,7 +170,7 @@ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
* @ns: namespace
* @params: ptr to the structure that contains the key and msgflg
*
- * Called with msg_ids.rw_mutex held (writer)
+ * Called with msg_ids.rwsem held (writer)
*/
static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{
@@ -259,8 +257,8 @@ static void expunge_all(struct msg_queue *msq, int res)
* removes the message queue from message queue ID IDR, and cleans up all the
* messages associated with this queue.
*
- * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
- * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
+ * msg_ids.rwsem (writer) and the spinlock for this message queue are held
+ * before freeque() is called. msg_ids.rwsem remains locked on exit.
*/
static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -270,7 +268,8 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
expunge_all(msq, -EIDRM);
ss_wakeup(&msq->q_senders, 1);
msg_rmid(ns, msq);
- msg_unlock(msq);
+ ipc_unlock_object(&msq->q_perm);
+ rcu_read_unlock();
list_for_each_entry_safe(msg, t, &msq->q_messages, m_list) {
atomic_dec(&ns->msg_hdrs);
@@ -282,7 +281,7 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
}
/*
- * Called with msg_ids.rw_mutex and ipcp locked.
+ * Called with msg_ids.rwsem and ipcp locked.
*/
static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
{
@@ -386,9 +385,9 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
}
/*
- * This function handles some msgctl commands which require the rw_mutex
+ * This function handles some msgctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
struct msqid_ds __user *buf, int version)
@@ -403,7 +402,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
return -EFAULT;
}
- down_write(&msg_ids(ns).rw_mutex);
+ down_write(&msg_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
@@ -459,7 +458,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&msg_ids(ns).rw_mutex);
+ up_write(&msg_ids(ns).rwsem);
return err;
}
@@ -494,7 +493,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
msginfo.msgmnb = ns->msg_ctlmnb;
msginfo.msgssz = MSGSSZ;
msginfo.msgseg = MSGSEG;
- down_read(&msg_ids(ns).rw_mutex);
+ down_read(&msg_ids(ns).rwsem);
if (cmd == MSG_INFO) {
msginfo.msgpool = msg_ids(ns).in_use;
msginfo.msgmap = atomic_read(&ns->msg_hdrs);
@@ -505,7 +504,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
msginfo.msgtql = MSGTQL;
}
max_id = ipc_get_maxid(&msg_ids(ns));
- up_read(&msg_ids(ns).rw_mutex);
+ up_read(&msg_ids(ns).rwsem);
if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
return -EFAULT;
return (max_id < 0) ? 0 : max_id;
@@ -895,6 +894,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
if (ipcperms(ns, &msq->q_perm, S_IRUGO))
goto out_unlock1;
+ ipc_lock_object(&msq->q_perm);
msg = find_msg(msq, &msgtyp, mode);
if (!IS_ERR(msg)) {
/*
@@ -903,7 +903,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
*/
if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
msg = ERR_PTR(-E2BIG);
- goto out_unlock1;
+ goto out_unlock0;
}
/*
* If we are copying, then do not unlink message and do
@@ -911,10 +911,9 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
*/
if (msgflg & MSG_COPY) {
msg = copy_msg(msg, copy);
- goto out_unlock1;
+ goto out_unlock0;
}
- ipc_lock_object(&msq->q_perm);
list_del(&msg->m_list);
msq->q_qnum--;
msq->q_rtime = get_seconds();
@@ -930,10 +929,9 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
/* No message waiting. Wait for a message */
if (msgflg & IPC_NOWAIT) {
msg = ERR_PTR(-ENOMSG);
- goto out_unlock1;
+ goto out_unlock0;
}
- ipc_lock_object(&msq->q_perm);
list_add_tail(&msr_d.r_list, &msq->q_receivers);
msr_d.r_tsk = current;
msr_d.r_msgtype = msgtyp;
@@ -957,7 +955,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
* Prior to destruction, expunge_all(-EIRDM) changes r_msg.
* Thus if r_msg is -EAGAIN, then the queue not yet destroyed.
* rcu_read_lock() prevents preemption between reading r_msg
- * and the spin_lock() inside ipc_lock_by_ptr().
+ * and acquiring the q_perm.lock in ipc_lock_object().
*/
rcu_read_lock();
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 7ee61bf..67dc744 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -81,7 +81,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
int next_id;
int total, in_use;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
in_use = ids->in_use;
@@ -93,7 +93,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
free(ns, perm);
total++;
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
}
static void free_ipc_ns(struct ipc_namespace *ns)
diff --git a/ipc/sem.c b/ipc/sem.c
index 4108889..69b6a21 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -322,7 +322,7 @@ static inline void sem_unlock(struct sem_array *sma, int locknum)
}
/*
- * sem_lock_(check_) routines are called in the paths where the rw_mutex
+ * sem_lock_(check_) routines are called in the paths where the rwsem
* is not held.
*
* The caller holds the RCU read lock.
@@ -426,7 +426,7 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
* @ns: namespace
* @params: ptr to the structure that contains key, semflg and nsems
*
- * Called with sem_ids.rw_mutex held (as a writer)
+ * Called with sem_ids.rwsem held (as a writer)
*/
static int newary(struct ipc_namespace *ns, struct ipc_params *params)
@@ -492,7 +492,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
{
@@ -503,7 +503,7 @@ static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
}
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -994,8 +994,8 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
return semzcnt;
}
-/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked
- * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex
+/* Free a semaphore set. freeary() is called with sem_ids.rwsem locked
+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rwsem
* remains locked on exit.
*/
static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
@@ -1116,7 +1116,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
seminfo.semmnu = SEMMNU;
seminfo.semmap = SEMMAP;
seminfo.semume = SEMUME;
- down_read(&sem_ids(ns).rw_mutex);
+ down_read(&sem_ids(ns).rwsem);
if (cmd == SEM_INFO) {
seminfo.semusz = sem_ids(ns).in_use;
seminfo.semaem = ns->used_sems;
@@ -1125,7 +1125,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
seminfo.semaem = SEMAEM;
}
max_id = ipc_get_maxid(&sem_ids(ns));
- up_read(&sem_ids(ns).rw_mutex);
+ up_read(&sem_ids(ns).rwsem);
if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
return -EFAULT;
return (max_id < 0) ? 0: max_id;
@@ -1431,9 +1431,9 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
}
/*
- * This function handles some semctl commands which require the rw_mutex
+ * This function handles some semctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int semctl_down(struct ipc_namespace *ns, int semid,
int cmd, int version, void __user *p)
@@ -1448,7 +1448,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
return -EFAULT;
}
- down_write(&sem_ids(ns).rw_mutex);
+ down_write(&sem_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd,
@@ -1487,7 +1487,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&sem_ids(ns).rw_mutex);
+ up_write(&sem_ids(ns).rwsem);
return err;
}
diff --git a/ipc/shm.c b/ipc/shm.c
index c6b4ad5..9017786 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -19,6 +19,9 @@
* namespaces support
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
+ *
+ * Better ipc lock (kern_ipc_perm.lock) handling
+ * Davidlohr Bueso <davidlohr.bueso@hp.com>, June 2013.
*/
#include <linux/slab.h>
@@ -80,8 +83,8 @@ void shm_init_ns(struct ipc_namespace *ns)
}
/*
- * Called with shm_ids.rw_mutex (writer) and the shp structure locked.
- * Only shm_ids.rw_mutex remains locked on exit.
+ * Called with shm_ids.rwsem (writer) and the shp structure locked.
+ * Only shm_ids.rwsem remains locked on exit.
*/
static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -124,8 +127,28 @@ void __init shm_init (void)
IPC_SHM_IDS, sysvipc_shm_proc_show);
}
+static inline struct shmid_kernel *shm_obtain_object(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_obtain_object(&shm_ids(ns), id);
+
+ if (IS_ERR(ipcp))
+ return ERR_CAST(ipcp);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
+static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace *ns, int id)
+{
+ struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&shm_ids(ns), id);
+
+ if (IS_ERR(ipcp))
+ return ERR_CAST(ipcp);
+
+ return container_of(ipcp, struct shmid_kernel, shm_perm);
+}
+
/*
- * shm_lock_(check_) routines are called in the paths where the rw_mutex
+ * shm_lock_(check_) routines are called in the paths where the rwsem
* is not necessarily held.
*/
static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
@@ -182,7 +205,7 @@ static void shm_open(struct vm_area_struct *vma)
* @ns: namespace
* @shp: struct to free
*
- * It has to be called with shp and shm_ids.rw_mutex (writer) locked,
+ * It has to be called with shp and shm_ids.rwsem (writer) locked,
* but returns with shp unlocked and freed.
*/
static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
@@ -230,7 +253,7 @@ static void shm_close(struct vm_area_struct *vma)
struct shmid_kernel *shp;
struct ipc_namespace *ns = sfd->ns;
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
/* remove from the list of attaches of the shm segment */
shp = shm_lock(ns, sfd->id);
BUG_ON(IS_ERR(shp));
@@ -241,10 +264,10 @@ static void shm_close(struct vm_area_struct *vma)
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_current(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -275,7 +298,7 @@ static int shm_try_destroy_current(int id, void *p, void *data)
return 0;
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_orphaned(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -286,7 +309,7 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
* We want to destroy segments without users and with already
* exit'ed originating process.
*
- * As shp->* are changed under rw_mutex, it's safe to skip shp locking.
+ * As shp->* are changed under rwsem, it's safe to skip shp locking.
*/
if (shp->shm_creator != NULL)
return 0;
@@ -300,10 +323,10 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
void shm_destroy_orphaned(struct ipc_namespace *ns)
{
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
@@ -315,10 +338,10 @@ void exit_shm(struct task_struct *task)
return;
/* Destroy all already created segments, but not mapped yet */
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -452,7 +475,7 @@ static const struct vm_operations_struct shm_vm_ops = {
* @ns: namespace
* @params: ptr to the structure that contains key, size and shmflg
*
- * Called with shm_ids.rw_mutex held as a writer.
+ * Called with shm_ids.rwsem held as a writer.
*/
static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
@@ -560,7 +583,7 @@ no_file:
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
{
@@ -571,7 +594,7 @@ static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -684,7 +707,7 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
/*
* Calculate and add used RSS and swap pages of a shm.
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_add_rss_swap(struct shmid_kernel *shp,
unsigned long *rss_add, unsigned long *swp_add)
@@ -711,7 +734,7 @@ static void shm_add_rss_swap(struct shmid_kernel *shp,
}
/*
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
unsigned long *swp)
@@ -740,9 +763,9 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
}
/*
- * This function handles some shmctl commands which require the rw_mutex
+ * This function handles some shmctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
struct shmid_ds __user *buf, int version)
@@ -757,14 +780,13 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
return -EFAULT;
}
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
rcu_read_lock();
- ipcp = ipcctl_pre_down(ns, &shm_ids(ns), shmid, cmd,
- &shmid64.shm_perm, 0);
+ ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
+ &shmid64.shm_perm, 0);
if (IS_ERR(ipcp)) {
err = PTR_ERR(ipcp);
- /* the ipc lock is not held upon failure */
goto out_unlock1;
}
@@ -772,14 +794,16 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
err = security_shm_shmctl(shp, cmd);
if (err)
- goto out_unlock0;
+ goto out_unlock1;
switch (cmd) {
case IPC_RMID:
+ ipc_lock_object(&shp->shm_perm);
/* do_shm_rmid unlocks the ipc object and rcu */
do_shm_rmid(ns, ipcp);
goto out_up;
case IPC_SET:
+ ipc_lock_object(&shp->shm_perm);
err = ipc_update_perm(&shmid64.shm_perm, ipcp);
if (err)
goto out_unlock0;
@@ -787,6 +811,7 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
break;
default:
err = -EINVAL;
+ goto out_unlock1;
}
out_unlock0:
@@ -794,33 +819,28 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
return err;
}
-SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
+ int cmd, int version, void __user *buf)
{
+ int err;
struct shmid_kernel *shp;
- int err, version;
- struct ipc_namespace *ns;
- if (cmd < 0 || shmid < 0) {
- err = -EINVAL;
- goto out;
+ /* preliminary security checks for *_INFO */
+ if (cmd == IPC_INFO || cmd == SHM_INFO) {
+ err = security_shm_shmctl(NULL, cmd);
+ if (err)
+ return err;
}
- version = ipc_parse_version(&cmd);
- ns = current->nsproxy->ipc_ns;
-
- switch (cmd) { /* replace with proc interface ? */
+ switch (cmd) {
case IPC_INFO:
{
struct shminfo64 shminfo;
- err = security_shm_shmctl(NULL, cmd);
- if (err)
- return err;
-
memset(&shminfo, 0, sizeof(shminfo));
shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
shminfo.shmmax = ns->shm_ctlmax;
@@ -830,9 +850,9 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
if(copy_shminfo_to_user (buf, &shminfo, version))
return -EFAULT;
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if(err<0)
err = 0;
@@ -842,19 +862,15 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
{
struct shm_info shm_info;
- err = security_shm_shmctl(NULL, cmd);
- if (err)
- return err;
-
memset(&shm_info, 0, sizeof(shm_info));
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
shm_info.used_ids = shm_ids(ns).in_use;
shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
shm_info.shm_tot = ns->shm_tot;
shm_info.swap_attempts = 0;
shm_info.swap_successes = 0;
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if (copy_to_user(buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
@@ -869,27 +885,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
struct shmid64_ds tbuf;
int result;
+ rcu_read_lock();
if (cmd == SHM_STAT) {
- shp = shm_lock(ns, shmid);
+ shp = shm_obtain_object(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
result = shp->shm_perm.id;
} else {
- shp = shm_lock_check(ns, shmid);
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock;
}
result = 0;
}
+
err = -EACCES;
if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
goto out_unlock;
+
err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock;
+
memset(&tbuf, 0, sizeof(tbuf));
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
tbuf.shm_segsz = shp->shm_segsz;
@@ -899,43 +919,76 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
tbuf.shm_cpid = shp->shm_cprid;
tbuf.shm_lpid = shp->shm_lprid;
tbuf.shm_nattch = shp->shm_nattch;
- shm_unlock(shp);
- if(copy_shmid_to_user (buf, &tbuf, version))
+ rcu_read_unlock();
+
+ if (copy_shmid_to_user (buf, &tbuf, version))
err = -EFAULT;
else
err = result;
goto out;
}
+ default:
+ return -EINVAL;
+ }
+
+out_unlock:
+ rcu_read_unlock();
+out:
+ return err;
+}
+
+SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
+{
+ struct shmid_kernel *shp;
+ int err, version;
+ struct ipc_namespace *ns;
+
+ if (cmd < 0 || shmid < 0)
+ return -EINVAL;
+
+ version = ipc_parse_version(&cmd);
+ ns = current->nsproxy->ipc_ns;
+
+ switch (cmd) {
+ case IPC_INFO:
+ case SHM_INFO:
+ case SHM_STAT:
+ case IPC_STAT:
+ return shmctl_nolock(ns, shmid, cmd, version, buf);
+ case IPC_RMID:
+ case IPC_SET:
+ return shmctl_down(ns, shmid, cmd, buf, version);
case SHM_LOCK:
case SHM_UNLOCK:
{
struct file *shm_file;
- shp = shm_lock_check(ns, shmid);
+ rcu_read_lock();
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
- goto out;
+ goto out_unlock1;
}
audit_ipc_obj(&(shp->shm_perm));
+ err = security_shm_shmctl(shp, cmd);
+ if (err)
+ goto out_unlock1;
+ ipc_lock_object(&shp->shm_perm);
if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) {
kuid_t euid = current_euid();
err = -EPERM;
if (!uid_eq(euid, shp->shm_perm.uid) &&
!uid_eq(euid, shp->shm_perm.cuid))
- goto out_unlock;
+ goto out_unlock0;
if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK))
- goto out_unlock;
+ goto out_unlock0;
}
- err = security_shm_shmctl(shp, cmd);
- if (err)
- goto out_unlock;
-
shm_file = shp->shm_file;
if (is_file_hugepages(shm_file))
- goto out_unlock;
+ goto out_unlock0;
if (cmd == SHM_LOCK) {
struct user_struct *user = current_user();
@@ -944,32 +997,31 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
shp->shm_perm.mode |= SHM_LOCKED;
shp->mlock_user = user;
}
- goto out_unlock;
+ goto out_unlock0;
}
/* SHM_UNLOCK */
if (!(shp->shm_perm.mode & SHM_LOCKED))
- goto out_unlock;
+ goto out_unlock0;
shmem_lock(shm_file, 0, shp->mlock_user);
shp->shm_perm.mode &= ~SHM_LOCKED;
shp->mlock_user = NULL;
get_file(shm_file);
- shm_unlock(shp);
+ ipc_unlock_object(&shp->shm_perm);
+ rcu_read_unlock();
shmem_unlock_mapping(shm_file->f_mapping);
+
fput(shm_file);
- goto out;
- }
- case IPC_RMID:
- case IPC_SET:
- err = shmctl_down(ns, shmid, cmd, buf, version);
return err;
+ }
default:
return -EINVAL;
}
-out_unlock:
- shm_unlock(shp);
-out:
+out_unlock0:
+ ipc_unlock_object(&shp->shm_perm);
+out_unlock1:
+ rcu_read_unlock();
return err;
}
@@ -1037,7 +1089,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
* additional creator id...
*/
ns = current->nsproxy->ipc_ns;
- shp = shm_lock_check(ns, shmid);
+ rcu_read_lock();
+ shp = shm_obtain_object_check(ns, shmid);
if (IS_ERR(shp)) {
err = PTR_ERR(shp);
goto out;
@@ -1051,24 +1104,31 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
if (err)
goto out_unlock;
+ ipc_lock_object(&shp->shm_perm);
path = shp->shm_file->f_path;
path_get(&path);
shp->shm_nattch++;
size = i_size_read(path.dentry->d_inode);
- shm_unlock(shp);
+ ipc_unlock_object(&shp->shm_perm);
+ rcu_read_unlock();
err = -ENOMEM;
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
- if (!sfd)
- goto out_put_dentry;
+ if (!sfd) {
+ path_put(&path);
+ goto out_nattch;
+ }
file = alloc_file(&path, f_mode,
is_file_hugepages(shp->shm_file) ?
&shm_file_operations_huge :
&shm_file_operations);
err = PTR_ERR(file);
- if (IS_ERR(file))
- goto out_free;
+ if (IS_ERR(file)) {
+ kfree(sfd);
+ path_put(&path);
+ goto out_nattch;
+ }
file->private_data = sfd;
file->f_mapping = shp->shm_file->f_mapping;
@@ -1094,7 +1154,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr,
addr > current->mm->start_stack - size - PAGE_SIZE * 5)
goto invalid;
}
-
+
addr = do_mmap_pgoff(file, addr, size, prot, flags, 0, &populate);
*raddr = addr;
err = 0;
@@ -1109,7 +1169,7 @@ out_fput:
fput(file);
out_nattch:
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
shp = shm_lock(ns, shmid);
BUG_ON(IS_ERR(shp));
shp->shm_nattch--;
@@ -1117,20 +1177,13 @@ out_nattch:
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
-
-out:
+ up_write(&shm_ids(ns).rwsem);
return err;
out_unlock:
- shm_unlock(shp);
- goto out;
-
-out_free:
- kfree(sfd);
-out_put_dentry:
- path_put(&path);
- goto out_nattch;
+ rcu_read_unlock();
+out:
+ return err;
}
SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
diff --git a/ipc/util.c b/ipc/util.c
index 4704223..69ee3c1 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -15,6 +15,14 @@
* Jun 2006 - namespaces ssupport
* OpenVZ, SWsoft Inc.
* Pavel Emelianov <xemul@openvz.org>
+ *
+ * General sysv ipc locking scheme:
+ * when doing ipc id lookups, take the ids->rwsem
+ * rcu_read_lock()
+ * obtain the ipc object (kern_ipc_perm)
+ * perform security, capabilities, auditing and permission checks, etc.
+ * acquire the ipc lock (kern_ipc_perm.lock) throught ipc_lock_object()
+ * perform data updates (ie: SET, RMID, LOCK/UNLOCK commands)
*/
#include <linux/mm.h>
@@ -119,7 +127,7 @@ __initcall(ipc_init);
void ipc_init_ids(struct ipc_ids *ids)
{
- init_rwsem(&ids->rw_mutex);
+ init_rwsem(&ids->rwsem);
ids->in_use = 0;
ids->seq = 0;
@@ -174,7 +182,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
* @ids: Identifier set
* @key: The key to find
*
- * Requires ipc_ids.rw_mutex locked.
+ * Requires ipc_ids.rwsem locked.
* Returns the LOCKED pointer to the ipc structure if found or NULL
* if not.
* If key is found ipc points to the owning ipc structure
@@ -208,7 +216,7 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
* ipc_get_maxid - get the last assigned id
* @ids: IPC identifier set
*
- * Called with ipc_ids.rw_mutex held.
+ * Called with ipc_ids.rwsem held.
*/
int ipc_get_maxid(struct ipc_ids *ids)
@@ -246,7 +254,7 @@ int ipc_get_maxid(struct ipc_ids *ids)
* is returned. The 'new' entry is returned in a locked state on success.
* On failure the entry is not locked and a negative err-code is returned.
*
- * Called with writer ipc_ids.rw_mutex held.
+ * Called with writer ipc_ids.rwsem held.
*/
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
{
@@ -312,9 +320,9 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
{
int err;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
err = ops->getnew(ns, params);
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -331,7 +339,7 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
*
* On success, the IPC id is returned.
*
- * It is called with ipc_ids.rw_mutex and ipcp->lock held.
+ * It is called with ipc_ids.rwsem and ipcp->lock held.
*/
static int ipc_check_perms(struct ipc_namespace *ns,
struct kern_ipc_perm *ipcp,
@@ -376,7 +384,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
* Take the lock as a writer since we are potentially going to add
* a new entry + read locks are not "upgradable"
*/
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
ipcp = ipc_findkey(ids, params->key);
if (ipcp == NULL) {
/* key not used */
@@ -402,7 +410,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
}
ipc_unlock(ipcp);
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -413,7 +421,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
* @ids: IPC identifier set
* @ipcp: ipc perm structure containing the identifier to remove
*
- * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
+ * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
* before this function is called, and remain locked on the exit.
*/
@@ -621,7 +629,7 @@ struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id)
}
/**
- * ipc_lock - Lock an ipc structure without rw_mutex held
+ * ipc_lock - Lock an ipc structure without rwsem held
* @ids: IPC identifier set
* @id: ipc id to look for
*
@@ -746,26 +754,10 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
* It must be called without any lock held and
* - retrieves the ipc with the given id in the given table.
* - performs some audit and permission check, depending on the given cmd
- * - returns the ipc with the ipc lock held in case of success
- * or an err-code without any lock held otherwise.
+ * - returns a pointer to the ipc object or otherwise, the corresponding error.
*
- * Call holding the both the rw_mutex and the rcu read lock.
+ * Call holding the both the rwsem and the rcu read lock.
*/
-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm)
-{
- struct kern_ipc_perm *ipcp;
-
- ipcp = ipcctl_pre_down_nolock(ns, ids, id, cmd, perm, extra_perm);
- if (IS_ERR(ipcp))
- goto out;
-
- spin_lock(&ipcp->lock);
-out:
- return ipcp;
-}
-
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
struct ipc64_perm *perm, int extra_perm)
@@ -782,8 +774,7 @@ struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
audit_ipc_obj(ipcp);
if (cmd == IPC_SET)
- audit_ipc_set_perm(extra_perm, perm->uid,
- perm->gid, perm->mode);
+ audit_ipc_set_perm(extra_perm, perm->uid, perm->gid, perm->mode);
euid = current_euid();
if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) ||
@@ -884,7 +875,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
* Take the lock - this will be released by the corresponding
* call to stop().
*/
- down_read(&ids->rw_mutex);
+ down_read(&ids->rwsem);
/* pos < 0 is invalid */
if (*pos < 0)
@@ -911,7 +902,7 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it)
ids = &iter->ns->ids[iface->ids];
/* Release the lock we took in start() */
- up_read(&ids->rw_mutex);
+ up_read(&ids->rwsem);
}
static int sysvipc_proc_show(struct seq_file *s, void *it)
diff --git a/ipc/util.h b/ipc/util.h
index b6a6a88..0a362ff 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -94,10 +94,10 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
#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->rwsem acquired for writing */
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
-/* must be called with ids->rw_mutex acquired for reading */
+/* must be called with ids->rwsem acquired for reading */
int ipc_get_maxid(struct ipc_ids *);
/* must be called with both locks acquired. */
@@ -131,9 +131,6 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out);
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
struct ipc64_perm *perm, int extra_perm);
-struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
- struct ipc_ids *ids, int id, int cmd,
- struct ipc64_perm *perm, int extra_perm);
#ifndef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
/* On IA-64, we always use the "64-bit version" of the IPC structures. */
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index acb8650..7d7c9d8 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -172,9 +172,22 @@ else
fi
maintainer="$name <$email>"
+# Try to determine distribution
+if [ -e $(which lsb_release) ]; then
+ codename=$(lsb_release --codename --short)
+ if [ "$codename" != "" ]; then
+ distribution=$codename
+ else
+ distribution="UNRELEASED"
+ echo "WARNING: The distribution could NOT be determined!"
+ fi
+else
+ echo "HINT: Install lsb_release binary, this helps to identify your distribution!"
+fi
+
# Generate a simple changelog template
cat <<EOF > debian/changelog
-linux-upstream ($packageversion) unstable; urgency=low
+linux-upstream ($packageversion) $distribution; urgency=low
* Custom built Linux kernel.
@@ -188,10 +201,10 @@ This is a packacked upstream version of the Linux kernel.
The sources may be found at most Linux ftp sites, including:
ftp://ftp.kernel.org/pub/linux/kernel
-Copyright: 1991 - 2009 Linus Torvalds and others.
+Copyright: 1991 - 2013 Linus Torvalds and others.
The git repository for mainline kernel development is at:
-git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
+git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 00/11] sysv ipc shared mem optimizations
[not found] <1372197144-13729-1-git-send-email-davidlohr.bueso@hp.com>
@ 2013-06-25 23:55 ` Sedat Dilek
2013-06-26 8:08 ` Sedat Dilek
0 siblings, 1 reply; 16+ messages in thread
From: Sedat Dilek @ 2013-06-25 23:55 UTC (permalink / raw)
To: Davidlohr Bueso; +Cc: linux-mm, Andrew Morton, Rik van Riel, Manfred Spraul
[-- Attachment #1: Type: text/plain, Size: 913 bytes --]
Hi,
I have tested the patchset "sysv ipc shared mem optimizations" on top
of next-20130618.
My typical rebuild with fakeroot & 'make deb-pkg' was fine.
Further tests done with LPT-full (20130503): IPC and SYSCALLS
test-cases ran successfully.
I am attaching the tarball I have sent already to Davidlohr which contains:
35070 Jun 26 00:37 3.10.0-rc6-next20130618-1-iniza-small.patch
114002 Jun 26 00:48 config-3.10.0-rc6-next20130618-1-iniza-small
84489 Jun 26 00:55 dmesg_3.10.0-rc6-next20130618-1-iniza-small.txt
38996 Jun 26 00:57 runltp-f-ipc_3.10.0-rc6-next20130618-1-iniza-small_dash.txt
760276 Jun 26 01:12
runltp-f-syscalls_3.10.0-rc6-next20130618-1-iniza-small_dash.txt
NOTES:
1. 09/11 needed a small refresh as v2 (attached).
2. [ PATCH] ipc,msq: fix race in msgrcv(2) (as v2) applied on top of
all (attached).
Please feel free to add my Tested-by to the whole series.
Regards,
- Sedat -
[-- Attachment #2: 0001-ipc-msq-fix-race-in-msgrcv-2-v2.patch --]
[-- Type: application/octet-stream, Size: 4077 bytes --]
From 2dee39f930ec13857567f16fd6316278928b4b3d Mon Sep 17 00:00:00 2001
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
Date: Wed, 26 Jun 2013 01:36:10 +0200
Subject: [PATCH next-20130624] ipc,msq: fix race in msgrcv(2)
Sedat reported the following issue when building the latest linux-next:
Building via 'make deb-pkg' with fakeroot fails here like this:
make: *** [deb-pkg] Terminated
/usr/bin/fakeroot: line 181: 5156 Terminated FAKEROOTKEY=$FAKEROOTKEY LD_LIBRARY_PATH="$PATHS" LD_PRELOAD="$LIB" "$@"
semop(1): encountered an error: Identifier removed
semop(2): encountered an error: Invalid argument
semop(1): encountered an error: Identifier removed
semop(1): encountered an error: Identifier removed
semop(1): encountered an error: Invalid argument
semop(1): encountered an error: Invalid argument
semop(1): encountered an error: Invalid argument
The issue was caused by a race in find_msg(), so acquire the q_perm.lock
before calling the function. This also broke some LTP test cases:
<<<test_start>>>
tag=msgctl08 stime=1372174954
cmdline="msgctl08"
contacts=""
analysis=exit
<<<test_output>>>
msgctl08 0 TWARN : Verify error in child 0, *buf = 28, val = 27, size = 8
msgctl08 1 TFAIL : in child 0 read # = 73,key = 127
msgctl08 0 TWARN : Verify error in child 3, *buf = ffffff8a, val = ffffff89, size = 52
msgctl08 1 TFAIL : in child 3 read # = 157,key = 189
msgctl08 0 TWARN : Verify error in child 2, *buf = ffffff87, val = ffffff86, size = 71
msgctl08 1 TFAIL : in child 2 read # = 15954,key = 3e86
msgctl08 0 TWARN : Verify error in child 12, *buf = ffffffa9, val = ffffffa8, size = 22
msgctl08 1 TFAIL : in child 12 read # = 12904,key = 32a8
msgctl08 0 TWARN : Verify error in child 13, *buf = 36, val = 35, size = 27
...
Also update a comment referring to ipc_lock_by_ptr(), which has already been deleted
and no longer applies to this context.
Reported-and-tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
---
[ dileks: v2: Fix truncated outputs of 'make deb-pkg' and msgctl08. ]
ipc/msg.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/ipc/msg.c b/ipc/msg.c
index a1cf70e..bd60d7e 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -895,6 +895,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
if (ipcperms(ns, &msq->q_perm, S_IRUGO))
goto out_unlock1;
+ ipc_lock_object(&msq->q_perm);
msg = find_msg(msq, &msgtyp, mode);
if (!IS_ERR(msg)) {
/*
@@ -903,7 +904,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
*/
if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
msg = ERR_PTR(-E2BIG);
- goto out_unlock1;
+ goto out_unlock0;
}
/*
* If we are copying, then do not unlink message and do
@@ -911,10 +912,9 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
*/
if (msgflg & MSG_COPY) {
msg = copy_msg(msg, copy);
- goto out_unlock1;
+ goto out_unlock0;
}
- ipc_lock_object(&msq->q_perm);
list_del(&msg->m_list);
msq->q_qnum--;
msq->q_rtime = get_seconds();
@@ -930,10 +930,9 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
/* No message waiting. Wait for a message */
if (msgflg & IPC_NOWAIT) {
msg = ERR_PTR(-ENOMSG);
- goto out_unlock1;
+ goto out_unlock0;
}
- ipc_lock_object(&msq->q_perm);
list_add_tail(&msr_d.r_list, &msq->q_receivers);
msr_d.r_tsk = current;
msr_d.r_msgtype = msgtyp;
@@ -957,7 +956,7 @@ long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgfl
* Prior to destruction, expunge_all(-EIRDM) changes r_msg.
* Thus if r_msg is -EAGAIN, then the queue not yet destroyed.
* rcu_read_lock() prevents preemption between reading r_msg
- * and the spin_lock() inside ipc_lock_by_ptr().
+ * and acquiring the q_perm.lock in ipc_lock_object().
*/
rcu_read_lock();
--
1.8.3.1
[-- Attachment #3: 0009-ipc-rename-ids-rw_mutex-v2.patch --]
[-- Type: application/octet-stream, Size: 20732 bytes --]
From d09a6cd63453cc2509961d96bf89e8d866b08f3b Mon Sep 17 00:00:00 2001
From: Sedat Dilek <sedat.dilek@gmail.com>
Date: Wed, 26 Jun 2013 00:20:07 +0200
Subject: [PATCH next-20130618] ipc: rename ids->rw_mutex
From: Davidlohr Bueso <davidlohr.bueso@hp.com>
Since in some situations the lock can be shared for readers,
we shouldn't be calling it a mutex, rename it to rwsem.
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
[ dileks: v2: Refreshed against next-20130618 ]
Signed-off-by: Sedat Dilek <sedat.dilek@gmail.com>
---
include/linux/ipc_namespace.h | 2 +-
ipc/msg.c | 20 ++++++++--------
ipc/namespace.c | 4 ++--
ipc/sem.c | 24 +++++++++----------
ipc/shm.c | 56 +++++++++++++++++++++----------------------
ipc/util.c | 28 +++++++++++-----------
ipc/util.h | 4 ++--
7 files changed, 69 insertions(+), 69 deletions(-)
diff --git a/include/linux/ipc_namespace.h b/include/linux/ipc_namespace.h
index c4d870b..19c19a5 100644
--- a/include/linux/ipc_namespace.h
+++ b/include/linux/ipc_namespace.h
@@ -22,7 +22,7 @@ struct ipc_ids {
int in_use;
unsigned short seq;
unsigned short seq_max;
- struct rw_semaphore rw_mutex;
+ struct rw_semaphore rwsem;
struct idr ipcs_idr;
int next_id;
};
diff --git a/ipc/msg.c b/ipc/msg.c
index 3b7b4b5..3be89c1 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -172,7 +172,7 @@ static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s)
* @ns: namespace
* @params: ptr to the structure that contains the key and msgflg
*
- * Called with msg_ids.rw_mutex held (writer)
+ * Called with msg_ids.rwsem held (writer)
*/
static int newque(struct ipc_namespace *ns, struct ipc_params *params)
{
@@ -261,8 +261,8 @@ static void expunge_all(struct msg_queue *msq, int res)
* removes the message queue from message queue ID IDR, and cleans up all the
* messages associated with this queue.
*
- * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held
- * before freeque() is called. msg_ids.rw_mutex remains locked on exit.
+ * msg_ids.rwsem (writer) and the spinlock for this message queue are held
+ * before freeque() is called. msg_ids.rwsem remains locked on exit.
*/
static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -284,7 +284,7 @@ static void freeque(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
}
/*
- * Called with msg_ids.rw_mutex and ipcp locked.
+ * Called with msg_ids.rwsem and ipcp locked.
*/
static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg)
{
@@ -388,9 +388,9 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
}
/*
- * This function handles some msgctl commands which require the rw_mutex
+ * This function handles some msgctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
struct msqid_ds __user *buf, int version)
@@ -405,7 +405,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
return -EFAULT;
}
- down_write(&msg_ids(ns).rw_mutex);
+ down_write(&msg_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
@@ -461,7 +461,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&msg_ids(ns).rw_mutex);
+ up_write(&msg_ids(ns).rwsem);
return err;
}
@@ -496,7 +496,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
msginfo.msgmnb = ns->msg_ctlmnb;
msginfo.msgssz = MSGSSZ;
msginfo.msgseg = MSGSEG;
- down_read(&msg_ids(ns).rw_mutex);
+ down_read(&msg_ids(ns).rwsem);
if (cmd == MSG_INFO) {
msginfo.msgpool = msg_ids(ns).in_use;
msginfo.msgmap = atomic_read(&ns->msg_hdrs);
@@ -507,7 +507,7 @@ static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
msginfo.msgtql = MSGTQL;
}
max_id = ipc_get_maxid(&msg_ids(ns));
- up_read(&msg_ids(ns).rw_mutex);
+ up_read(&msg_ids(ns).rwsem);
if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
return -EFAULT;
return (max_id < 0) ? 0 : max_id;
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 7ee61bf..67dc744 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -81,7 +81,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
int next_id;
int total, in_use;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
in_use = ids->in_use;
@@ -93,7 +93,7 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
free(ns, perm);
total++;
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
}
static void free_ipc_ns(struct ipc_namespace *ns)
diff --git a/ipc/sem.c b/ipc/sem.c
index fad2da5..c88e17c 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -321,7 +321,7 @@ static inline void sem_unlock(struct sem_array *sma, int locknum)
}
/*
- * sem_lock_(check_) routines are called in the paths where the rw_mutex
+ * sem_lock_(check_) routines are called in the paths where the rwsem
* is not held.
*
* The caller holds the RCU read lock.
@@ -425,7 +425,7 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
* @ns: namespace
* @params: ptr to the structure that contains key, semflg and nsems
*
- * Called with sem_ids.rw_mutex held (as a writer)
+ * Called with sem_ids.rwsem held (as a writer)
*/
static int newary(struct ipc_namespace *ns, struct ipc_params *params)
@@ -493,7 +493,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
{
@@ -504,7 +504,7 @@ static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
}
/*
- * Called with sem_ids.rw_mutex and ipcp locked.
+ * Called with sem_ids.rwsem and ipcp locked.
*/
static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -987,8 +987,8 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum)
return semzcnt;
}
-/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked
- * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex
+/* Free a semaphore set. freeary() is called with sem_ids.rwsem locked
+ * as a writer and the spinlock for this semaphore set hold. sem_ids.rwsem
* remains locked on exit.
*/
static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
@@ -1094,7 +1094,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
seminfo.semmnu = SEMMNU;
seminfo.semmap = SEMMAP;
seminfo.semume = SEMUME;
- down_read(&sem_ids(ns).rw_mutex);
+ down_read(&sem_ids(ns).rwsem);
if (cmd == SEM_INFO) {
seminfo.semusz = sem_ids(ns).in_use;
seminfo.semaem = ns->used_sems;
@@ -1103,7 +1103,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid,
seminfo.semaem = SEMAEM;
}
max_id = ipc_get_maxid(&sem_ids(ns));
- up_read(&sem_ids(ns).rw_mutex);
+ up_read(&sem_ids(ns).rwsem);
if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
return -EFAULT;
return (max_id < 0) ? 0: max_id;
@@ -1409,9 +1409,9 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
}
/*
- * This function handles some semctl commands which require the rw_mutex
+ * This function handles some semctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int semctl_down(struct ipc_namespace *ns, int semid,
int cmd, int version, void __user *p)
@@ -1426,7 +1426,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
return -EFAULT;
}
- down_write(&sem_ids(ns).rw_mutex);
+ down_write(&sem_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd,
@@ -1465,7 +1465,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&sem_ids(ns).rw_mutex);
+ up_write(&sem_ids(ns).rwsem);
return err;
}
diff --git a/ipc/shm.c b/ipc/shm.c
index 5571b87..d9e6c71 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -83,8 +83,8 @@ void shm_init_ns(struct ipc_namespace *ns)
}
/*
- * Called with shm_ids.rw_mutex (writer) and the shp structure locked.
- * Only shm_ids.rw_mutex remains locked on exit.
+ * Called with shm_ids.rwsem (writer) and the shp structure locked.
+ * Only shm_ids.rwsem remains locked on exit.
*/
static void do_shm_rmid(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
{
@@ -148,7 +148,7 @@ static inline struct shmid_kernel *shm_obtain_object_check(struct ipc_namespace
}
/*
- * shm_lock_(check_) routines are called in the paths where the rw_mutex
+ * shm_lock_(check_) routines are called in the paths where the rwsem
* is not necessarily held.
*/
static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
@@ -205,7 +205,7 @@ static void shm_open(struct vm_area_struct *vma)
* @ns: namespace
* @shp: struct to free
*
- * It has to be called with shp and shm_ids.rw_mutex (writer) locked,
+ * It has to be called with shp and shm_ids.rwsem (writer) locked,
* but returns with shp unlocked and freed.
*/
static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp)
@@ -253,7 +253,7 @@ static void shm_close(struct vm_area_struct *vma)
struct shmid_kernel *shp;
struct ipc_namespace *ns = sfd->ns;
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
/* remove from the list of attaches of the shm segment */
shp = shm_lock(ns, sfd->id);
BUG_ON(IS_ERR(shp));
@@ -264,10 +264,10 @@ static void shm_close(struct vm_area_struct *vma)
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_current(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -298,7 +298,7 @@ static int shm_try_destroy_current(int id, void *p, void *data)
return 0;
}
-/* Called with ns->shm_ids(ns).rw_mutex locked */
+/* Called with ns->shm_ids(ns).rwsem locked */
static int shm_try_destroy_orphaned(int id, void *p, void *data)
{
struct ipc_namespace *ns = data;
@@ -309,7 +309,7 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
* We want to destroy segments without users and with already
* exit'ed originating process.
*
- * As shp->* are changed under rw_mutex, it's safe to skip shp locking.
+ * As shp->* are changed under rwsem, it's safe to skip shp locking.
*/
if (shp->shm_creator != NULL)
return 0;
@@ -323,10 +323,10 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data)
void shm_destroy_orphaned(struct ipc_namespace *ns)
{
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
@@ -338,10 +338,10 @@ void exit_shm(struct task_struct *task)
return;
/* Destroy all already created segments, but not mapped yet */
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
if (shm_ids(ns).in_use)
idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
}
static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -475,7 +475,7 @@ static const struct vm_operations_struct shm_vm_ops = {
* @ns: namespace
* @params: ptr to the structure that contains key, size and shmflg
*
- * Called with shm_ids.rw_mutex held as a writer.
+ * Called with shm_ids.rwsem held as a writer.
*/
static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
@@ -585,7 +585,7 @@ no_file:
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
{
@@ -596,7 +596,7 @@ static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg)
}
/*
- * Called with shm_ids.rw_mutex and ipcp locked.
+ * Called with shm_ids.rwsem and ipcp locked.
*/
static inline int shm_more_checks(struct kern_ipc_perm *ipcp,
struct ipc_params *params)
@@ -709,7 +709,7 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf
/*
* Calculate and add used RSS and swap pages of a shm.
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_add_rss_swap(struct shmid_kernel *shp,
unsigned long *rss_add, unsigned long *swp_add)
@@ -736,7 +736,7 @@ static void shm_add_rss_swap(struct shmid_kernel *shp,
}
/*
- * Called with shm_ids.rw_mutex held as a reader
+ * Called with shm_ids.rwsem held as a reader
*/
static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
unsigned long *swp)
@@ -765,9 +765,9 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
}
/*
- * This function handles some shmctl commands which require the rw_mutex
+ * This function handles some shmctl commands which require the rwsem
* to be held in write mode.
- * NOTE: no locks must be held, the rw_mutex is taken inside this function.
+ * NOTE: no locks must be held, the rwsem is taken inside this function.
*/
static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
struct shmid_ds __user *buf, int version)
@@ -782,7 +782,7 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
return -EFAULT;
}
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
rcu_read_lock();
ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
@@ -821,7 +821,7 @@ out_unlock0:
out_unlock1:
rcu_read_unlock();
out_up:
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
return err;
}
@@ -852,9 +852,9 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
if(copy_shminfo_to_user (buf, &shminfo, version))
return -EFAULT;
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if(err<0)
err = 0;
@@ -865,14 +865,14 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
struct shm_info shm_info;
memset(&shm_info, 0, sizeof(shm_info));
- down_read(&shm_ids(ns).rw_mutex);
+ down_read(&shm_ids(ns).rwsem);
shm_info.used_ids = shm_ids(ns).in_use;
shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp);
shm_info.shm_tot = ns->shm_tot;
shm_info.swap_attempts = 0;
shm_info.swap_successes = 0;
err = ipc_get_maxid(&shm_ids(ns));
- up_read(&shm_ids(ns).rw_mutex);
+ up_read(&shm_ids(ns).rwsem);
if (copy_to_user(buf, &shm_info, sizeof(shm_info))) {
err = -EFAULT;
goto out;
@@ -1171,7 +1171,7 @@ out_fput:
fput(file);
out_nattch:
- down_write(&shm_ids(ns).rw_mutex);
+ down_write(&shm_ids(ns).rwsem);
shp = shm_lock(ns, shmid);
BUG_ON(IS_ERR(shp));
shp->shm_nattch--;
@@ -1179,7 +1179,7 @@ out_nattch:
shm_destroy(ns, shp);
else
shm_unlock(shp);
- up_write(&shm_ids(ns).rw_mutex);
+ up_write(&shm_ids(ns).rwsem);
return err;
out_unlock:
diff --git a/ipc/util.c b/ipc/util.c
index 87adecc..48cb120 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -119,7 +119,7 @@ __initcall(ipc_init);
void ipc_init_ids(struct ipc_ids *ids)
{
- init_rwsem(&ids->rw_mutex);
+ init_rwsem(&ids->rwsem);
ids->in_use = 0;
ids->seq = 0;
@@ -174,7 +174,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
* @ids: Identifier set
* @key: The key to find
*
- * Requires ipc_ids.rw_mutex locked.
+ * Requires ipc_ids.rwsem locked.
* Returns the LOCKED pointer to the ipc structure if found or NULL
* if not.
* If key is found ipc points to the owning ipc structure
@@ -208,7 +208,7 @@ static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key)
* ipc_get_maxid - get the last assigned id
* @ids: IPC identifier set
*
- * Called with ipc_ids.rw_mutex held.
+ * Called with ipc_ids.rwsem held.
*/
int ipc_get_maxid(struct ipc_ids *ids)
@@ -246,7 +246,7 @@ int ipc_get_maxid(struct ipc_ids *ids)
* is returned. The 'new' entry is returned in a locked state on success.
* On failure the entry is not locked and a negative err-code is returned.
*
- * Called with RCU read lock and writer ipc_ids.rw_mutex held.
+ * Called with RCU read lock and writer ipc_ids.rwsem held.
*/
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
{
@@ -311,9 +311,9 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
{
int err;
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
err = ops->getnew(ns, params);
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -330,7 +330,7 @@ static int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids,
*
* On success, the IPC id is returned.
*
- * It is called with ipc_ids.rw_mutex and ipcp->lock held.
+ * It is called with ipc_ids.rwsem and ipcp->lock held.
*/
static int ipc_check_perms(struct ipc_namespace *ns,
struct kern_ipc_perm *ipcp,
@@ -375,7 +375,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
* Take the lock as a writer since we are potentially going to add
* a new entry + read locks are not "upgradable"
*/
- down_write(&ids->rw_mutex);
+ down_write(&ids->rwsem);
ipcp = ipc_findkey(ids, params->key);
if (ipcp == NULL) {
/* key not used */
@@ -401,7 +401,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
}
ipc_unlock(ipcp);
}
- up_write(&ids->rw_mutex);
+ up_write(&ids->rwsem);
return err;
}
@@ -412,7 +412,7 @@ static int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids,
* @ids: IPC identifier set
* @ipcp: ipc perm structure containing the identifier to remove
*
- * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held
+ * ipc_ids.rwsem (as a writer) and the spinlock for this ID are held
* before this function is called, and remain locked on the exit.
*/
@@ -620,7 +620,7 @@ struct kern_ipc_perm *ipc_obtain_object(struct ipc_ids *ids, int id)
}
/**
- * ipc_lock - Lock an ipc structure without rw_mutex held
+ * ipc_lock - Lock an ipc structure without rwsem held
* @ids: IPC identifier set
* @id: ipc id to look for
*
@@ -747,7 +747,7 @@ int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
* - performs some audit and permission check, depending on the given cmd
* - returns a pointer to the ipc object or otherwise, the corresponding error.
*
- * Call holding the both the rw_mutex and the rcu read lock.
+ * Call holding the both the rwsem and the rcu read lock.
*/
struct kern_ipc_perm *ipcctl_pre_down_nolock(struct ipc_namespace *ns,
struct ipc_ids *ids, int id, int cmd,
@@ -866,7 +866,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos)
* Take the lock - this will be released by the corresponding
* call to stop().
*/
- down_read(&ids->rw_mutex);
+ down_read(&ids->rwsem);
/* pos < 0 is invalid */
if (*pos < 0)
@@ -893,7 +893,7 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it)
ids = &iter->ns->ids[iface->ids];
/* Release the lock we took in start() */
- up_read(&ids->rw_mutex);
+ up_read(&ids->rwsem);
}
static int sysvipc_proc_show(struct seq_file *s, void *it)
diff --git a/ipc/util.h b/ipc/util.h
index 41a6c4d..0a362ff 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -94,10 +94,10 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
#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->rwsem acquired for writing */
int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int);
-/* must be called with ids->rw_mutex acquired for reading */
+/* must be called with ids->rwsem acquired for reading */
int ipc_get_maxid(struct ipc_ids *);
/* must be called with both locks acquired. */
--
1.8.3.1
[-- Attachment #4: for-davidlohr-2.tar.xz --]
[-- Type: application/octet-stream, Size: 89564 bytes --]
[-- Attachment #5: for-davidlohr-2.tar.xz.sha256sum --]
[-- Type: application/octet-stream, Size: 89 bytes --]
ff4b6fb166ac9058899801ada767d901d02270bc76bdca3c66c05715f60e3e45 for-davidlohr-2.tar.xz
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2013-07-16 22:49 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-19 1:18 [PATCH 00/11] sysv ipc shared mem optimizations Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 01/11] ipc,shm: introduce lockless functions to obtain the ipc object Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 02/11] ipc,shm: shorten critical region in shmctl_down Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 03/11] ipc: drop ipcctl_pre_down Davidlohr Bueso
2013-07-16 22:49 ` Andrew Morton
2013-06-19 1:18 ` [PATCH 04/11] ipc,shm: introduce shmctl_nolock Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 05/11] ipc,shm: make shmctl_nolock lockless Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 06/11] ipc,shm: shorten critical region for shmctl Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 07/11] ipc,shm: cleanup do_shmat pasta Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 08/11] ipc,shm: shorten critical region for shmat Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 09/11] ipc: rename ids->rw_mutex Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 10/11] ipc,msg: drop msg_unlock Davidlohr Bueso
2013-06-19 1:18 ` [PATCH 11/11] ipc: document general ipc locking scheme Davidlohr Bueso
[not found] <1372197144-13729-1-git-send-email-davidlohr.bueso@hp.com>
2013-06-25 23:55 ` [PATCH 00/11] sysv ipc shared mem optimizations Sedat Dilek
2013-06-26 8:08 ` Sedat Dilek
2013-06-28 10:10 ` Sedat Dilek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox