* [PATCH] shm: fix wrong tests
2011-08-03 18:24 ` Vasiliy Kulikov
@ 2011-08-03 18:26 ` Vasiliy Kulikov
2011-08-03 18:28 ` [PATCH] shm: optimize exit_shm() Vasiliy Kulikov
2011-08-03 19:18 ` + shm-fix-a-race-between-shm_exit-and-shm_init.patch added to -mm tree Oleg Nesterov
2 siblings, 0 replies; 13+ messages in thread
From: Vasiliy Kulikov @ 2011-08-03 18:26 UTC (permalink / raw)
To: Linus Torvalds
Cc: Andrew Morton, Oleg Nesterov, Manuel Lauss, Richard Weinberger,
Serge E. Hallyn, Marc Zyngier, linux-kernel
The patch 4c677e2eefdba9c5bfc4474e2e9 introduced a copy-paste bug.
Due to the bug cycle optimizations were disabled.
Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
---
ipc/shm.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index bf46636..4e3c883 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -294,7 +294,7 @@ 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);
- if (&shm_ids(ns).in_use)
+ 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);
}
@@ -306,7 +306,7 @@ void exit_shm(struct task_struct *task)
/* Destroy all already created segments, but not mapped yet */
down_write(&shm_ids(ns).rw_mutex);
- if (&shm_ids(ns).in_use)
+ 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);
}
--
1.7.0.4
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH] shm: optimize exit_shm()
2011-08-03 18:24 ` Vasiliy Kulikov
2011-08-03 18:26 ` [PATCH] shm: fix wrong tests Vasiliy Kulikov
@ 2011-08-03 18:28 ` Vasiliy Kulikov
2011-08-03 19:08 ` Manuel Lauss
2011-08-03 19:21 ` Oleg Nesterov
2011-08-03 19:18 ` + shm-fix-a-race-between-shm_exit-and-shm_init.patch added to -mm tree Oleg Nesterov
2 siblings, 2 replies; 13+ messages in thread
From: Vasiliy Kulikov @ 2011-08-03 18:28 UTC (permalink / raw)
To: Linus Torvalds
Cc: Andrew Morton, Manuel Lauss, Oleg Nesterov, Richard Weinberger,
Marc Zyngier, linux-kernel
We may check .in_use == 0 without holding the rw_mutex as .in_use is int
and reads of ints are atomic. As .in_use may be changed to zero while current
process was sleeping in down_write(), we should check .in_use once again after
down_write().
Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
---
ipc/shm.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/ipc/shm.c b/ipc/shm.c
index 4e3c883..855ddc0 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -304,6 +304,9 @@ void exit_shm(struct task_struct *task)
{
struct ipc_namespace *ns = task->nsproxy->ipc_ns;
+ if (shm_ids(ns).in_use == 0)
+ return;
+
/* Destroy all already created segments, but not mapped yet */
down_write(&shm_ids(ns).rw_mutex);
if (shm_ids(ns).in_use)
--
1.7.0.4
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH] shm: optimize exit_shm()
2011-08-03 18:28 ` [PATCH] shm: optimize exit_shm() Vasiliy Kulikov
@ 2011-08-03 19:08 ` Manuel Lauss
2011-08-03 19:16 ` Vasiliy Kulikov
2011-08-03 19:21 ` Oleg Nesterov
1 sibling, 1 reply; 13+ messages in thread
From: Manuel Lauss @ 2011-08-03 19:08 UTC (permalink / raw)
To: Vasiliy Kulikov
Cc: Linus Torvalds, Andrew Morton, Oleg Nesterov, Richard Weinberger,
Marc Zyngier, linux-kernel
Hello,
On Wed, Aug 3, 2011 at 8:28 PM, Vasiliy Kulikov <segoon@openwall.com> wrote:
> We may check .in_use == 0 without holding the rw_mutex as .in_use is int
> and reads of ints are atomic. As .in_use may be changed to zero while current
> process was sleeping in down_write(), we should check .in_use once again after
> down_write().
>
> Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
> ---
> ipc/shm.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/ipc/shm.c b/ipc/shm.c
> index 4e3c883..855ddc0 100644
> --- a/ipc/shm.c
> +++ b/ipc/shm.c
> @@ -304,6 +304,9 @@ void exit_shm(struct task_struct *task)
> {
> struct ipc_namespace *ns = task->nsproxy->ipc_ns;
>
> + if (shm_ids(ns).in_use == 0)
> + return;
> +
> /* Destroy all already created segments, but not mapped yet */
> down_write(&shm_ids(ns).rw_mutex);
> if (shm_ids(ns).in_use)
This check here is now unnecessary, yes?
And this also fixes the oops.
Manuel
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH] shm: optimize exit_shm()
2011-08-03 19:08 ` Manuel Lauss
@ 2011-08-03 19:16 ` Vasiliy Kulikov
2011-08-03 19:29 ` Oleg Nesterov
0 siblings, 1 reply; 13+ messages in thread
From: Vasiliy Kulikov @ 2011-08-03 19:16 UTC (permalink / raw)
To: Manuel Lauss
Cc: Linus Torvalds, Andrew Morton, Oleg Nesterov, Richard Weinberger,
Marc Zyngier, linux-kernel
Hi Manuel,
On Wed, Aug 03, 2011 at 21:08 +0200, Manuel Lauss wrote:
> On Wed, Aug 3, 2011 at 8:28 PM, Vasiliy Kulikov <segoon@openwall.com> wrote:
> > We may check .in_use == 0 without holding the rw_mutex as .in_use is int
> > and reads of ints are atomic. As .in_use may be changed to zero while current
> > process was sleeping in down_write(), we should check .in_use once again after
> > down_write().
[...]
> > + if (shm_ids(ns).in_use == 0)
> > + return;
> > +
> > /* Destroy all already created segments, but not mapped yet */
> > down_write(&shm_ids(ns).rw_mutex);
> > if (shm_ids(ns).in_use)
>
> This check here is now unnecessary, yes?
No, as I said in the comment above, other task may be holding the mutex and
deleting the last shm segment. So, current task will see in_use == 1
before down_write(), but == 0 after it.
> And this also fixes the oops.
Yes, but it only hides the real problem - tasks' dependency on initialized
init_*_ns.
Thanks,
--
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] shm: optimize exit_shm()
2011-08-03 19:16 ` Vasiliy Kulikov
@ 2011-08-03 19:29 ` Oleg Nesterov
2011-08-03 19:41 ` Vasiliy Kulikov
0 siblings, 1 reply; 13+ messages in thread
From: Oleg Nesterov @ 2011-08-03 19:29 UTC (permalink / raw)
To: Vasiliy Kulikov
Cc: Manuel Lauss, Linus Torvalds, Andrew Morton, Richard Weinberger,
Marc Zyngier, linux-kernel
On 08/03, Vasiliy Kulikov wrote:
>
> On Wed, Aug 03, 2011 at 21:08 +0200, Manuel Lauss wrote:
> > > +
> > > /* Destroy all already created segments, but not mapped yet */
> > > down_write(&shm_ids(ns).rw_mutex);
> > > if (shm_ids(ns).in_use)
> >
> > This check here is now unnecessary, yes?
>
> No, as I said in the comment above, other task may be holding the mutex and
> deleting the last shm segment. So, current task will see in_use == 1
> before down_write(), but == 0 after it.
And? Why we can not do idr_for_each() in this (unikely) case?
> > And this also fixes the oops.
>
> Yes, but it only hides the real problem - tasks' dependency on initialized
> init_*_ns.
This is true, but your patch has the same dependency, but pretends
it doesn't ;) and it complicates the code.
Oleg.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] shm: optimize exit_shm()
2011-08-03 19:29 ` Oleg Nesterov
@ 2011-08-03 19:41 ` Vasiliy Kulikov
2011-08-03 19:43 ` Oleg Nesterov
0 siblings, 1 reply; 13+ messages in thread
From: Vasiliy Kulikov @ 2011-08-03 19:41 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Manuel Lauss, Linus Torvalds, Andrew Morton, Richard Weinberger,
Marc Zyngier, linux-kernel
On Wed, Aug 03, 2011 at 21:29 +0200, Oleg Nesterov wrote:
> On 08/03, Vasiliy Kulikov wrote:
> >
> > On Wed, Aug 03, 2011 at 21:08 +0200, Manuel Lauss wrote:
> > > > +
> > > > /* Destroy all already created segments, but not mapped yet */
> > > > down_write(&shm_ids(ns).rw_mutex);
> > > > if (shm_ids(ns).in_use)
> > >
> > > This check here is now unnecessary, yes?
> >
> > No, as I said in the comment above, other task may be holding the mutex and
> > deleting the last shm segment. So, current task will see in_use == 1
> > before down_write(), but == 0 after it.
>
> And? Why we can not do idr_for_each() in this (unikely) case?
Because it's pointless. idr_for_each() would not find any used segment.
> > > And this also fixes the oops.
> >
> > Yes, but it only hides the real problem - tasks' dependency on initialized
> > init_*_ns.
>
> This is true, but your patch has the same dependency, but pretends
> it doesn't ;) and it complicates the code.
I didn't say that .in_use check fixes the oops. The description says
nothing about it. It does an optimization, which is said in the
description.
--
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] shm: optimize exit_shm()
2011-08-03 19:41 ` Vasiliy Kulikov
@ 2011-08-03 19:43 ` Oleg Nesterov
0 siblings, 0 replies; 13+ messages in thread
From: Oleg Nesterov @ 2011-08-03 19:43 UTC (permalink / raw)
To: Vasiliy Kulikov
Cc: Manuel Lauss, Linus Torvalds, Andrew Morton, Richard Weinberger,
Marc Zyngier, linux-kernel
On 08/03, Vasiliy Kulikov wrote:
>
> On Wed, Aug 03, 2011 at 21:29 +0200, Oleg Nesterov wrote:
> > On 08/03, Vasiliy Kulikov wrote:
> > >
> > > On Wed, Aug 03, 2011 at 21:08 +0200, Manuel Lauss wrote:
> > > > > +
> > > > > /* Destroy all already created segments, but not mapped yet */
> > > > > down_write(&shm_ids(ns).rw_mutex);
> > > > > if (shm_ids(ns).in_use)
> > > >
> > > > This check here is now unnecessary, yes?
> > >
> > > No, as I said in the comment above, other task may be holding the mutex and
> > > deleting the last shm segment. So, current task will see in_use == 1
> > > before down_write(), but == 0 after it.
> >
> > And? Why we can not do idr_for_each() in this (unikely) case?
>
> Because it's pointless. idr_for_each() would not find any used segment.
This is clear. But it seems that me + Manuel were equally confused
by the changelog.
> > > > And this also fixes the oops.
> > >
> > > Yes, but it only hides the real problem - tasks' dependency on initialized
> > > init_*_ns.
> >
> > This is true, but your patch has the same dependency, but pretends
> > it doesn't ;) and it complicates the code.
>
> I didn't say that .in_use check fixes the oops.
I meant your shm-fix-a-race-between-shm_exit-and-shm_init.patch
which should be dropped imho ;)
Oleg.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] shm: optimize exit_shm()
2011-08-03 18:28 ` [PATCH] shm: optimize exit_shm() Vasiliy Kulikov
2011-08-03 19:08 ` Manuel Lauss
@ 2011-08-03 19:21 ` Oleg Nesterov
2011-08-03 19:34 ` Vasiliy Kulikov
1 sibling, 1 reply; 13+ messages in thread
From: Oleg Nesterov @ 2011-08-03 19:21 UTC (permalink / raw)
To: Vasiliy Kulikov
Cc: Linus Torvalds, Andrew Morton, Manuel Lauss, Richard Weinberger,
Marc Zyngier, linux-kernel
On 08/03, Vasiliy Kulikov wrote:
>
> As .in_use may be changed to zero while current
> process was sleeping in down_write(),
Yes,
> we should check .in_use once again after
> down_write().
Why?
It doesn't hurt to recheck and I think the patch is correct.
But the changelog looks confusing.
Oleg.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] shm: optimize exit_shm()
2011-08-03 19:21 ` Oleg Nesterov
@ 2011-08-03 19:34 ` Vasiliy Kulikov
2011-08-03 19:39 ` Oleg Nesterov
0 siblings, 1 reply; 13+ messages in thread
From: Vasiliy Kulikov @ 2011-08-03 19:34 UTC (permalink / raw)
To: Oleg Nesterov
Cc: Linus Torvalds, Andrew Morton, Manuel Lauss, Richard Weinberger,
Marc Zyngier, linux-kernel
On Wed, Aug 03, 2011 at 21:21 +0200, Oleg Nesterov wrote:
> > we should check .in_use once again after
> > down_write().
>
> Why?
https://lkml.org/lkml/2011/8/3/277
"No, as I said in the comment above, other task may be holding the mutex and
deleting the last shm segment. So, current task will see in_use == 1
before down_write(), but == 0 after it."
"Should" == additional check might speed the things, so it worth checking.
--
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] shm: optimize exit_shm()
2011-08-03 19:34 ` Vasiliy Kulikov
@ 2011-08-03 19:39 ` Oleg Nesterov
0 siblings, 0 replies; 13+ messages in thread
From: Oleg Nesterov @ 2011-08-03 19:39 UTC (permalink / raw)
To: Vasiliy Kulikov
Cc: Linus Torvalds, Andrew Morton, Manuel Lauss, Richard Weinberger,
Marc Zyngier, linux-kernel
On 08/03, Vasiliy Kulikov wrote:
>
> On Wed, Aug 03, 2011 at 21:21 +0200, Oleg Nesterov wrote:
> > > we should check .in_use once again after
> > > down_write().
> >
> > Why?
>
> https://lkml.org/lkml/2011/8/3/277
>
> "No, as I said in the comment above, other task may be holding the mutex and
> deleting the last shm segment.
This is obvious,
> "Should" == additional check might speed the things, so it worth checking.
and this is not.
I was confused, the changelog looks as if we _have to_ recheck
or something bad can happen.
But as I said, the patch looks correct anyway. I am not
sure the 2nd optimization really makes sense (this is very
unlikely case) but it doesn't hurt.
Oleg.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: + shm-fix-a-race-between-shm_exit-and-shm_init.patch added to -mm tree
2011-08-03 18:24 ` Vasiliy Kulikov
2011-08-03 18:26 ` [PATCH] shm: fix wrong tests Vasiliy Kulikov
2011-08-03 18:28 ` [PATCH] shm: optimize exit_shm() Vasiliy Kulikov
@ 2011-08-03 19:18 ` Oleg Nesterov
2 siblings, 0 replies; 13+ messages in thread
From: Oleg Nesterov @ 2011-08-03 19:18 UTC (permalink / raw)
To: Vasiliy Kulikov
Cc: Andrew Morton, Manuel Lauss, Richard Weinberger, Linus Torvalds,
Marc Zyngier, linux-kernel
On 08/03, Vasiliy Kulikov wrote:
>
> On Wed, Aug 03, 2011 at 16:04 +0200, Oleg Nesterov wrote:
> >
> > And since we rely on .in_use == 0, why we can't move this check
> > outside of down_write/up_right to a) optimize the code and b)
> > fix the problem?
>
> Agreed. But I second Linus that partial initialization only hides the
> real problem. And some initcall chain movement is still needed.
I agree. But, until then, we can make a much more simple fix.
Especially because this patch (imho) mostly hides the problem too.
Oleg.
^ permalink raw reply [flat|nested] 13+ messages in thread