From: "Paul E. McKenney" <paulmck@us.ibm.com>
To: Oleg Nesterov <oleg@tv-sign.ru>
Cc: linux-kernel@vger.kernel.org, Hugh Dickins <hugh@veritas.com>,
Dipankar Sarma <dipankar@in.ibm.com>,
Andrew Morton <akpm@osdl.org>
Subject: Re: [PATCH] convert sighand_cache to use SLAB_DESTROY_BY_RCU
Date: Fri, 17 Feb 2006 18:04:21 -0800 [thread overview]
Message-ID: <20060218020421.GG1291@us.ibm.com> (raw)
In-Reply-To: <43F62B96.C54704D1@tv-sign.ru>
On Fri, Feb 17, 2006 at 11:01:26PM +0300, Oleg Nesterov wrote:
> This patch borrows a clever Hugh's 'struct anon_vma' trick.
>
> Without tasklist_lock held we can't trust task->sighand until we
> locked it and re-checked that it is still the same.
>
> But this means we don't need to defer 'kmem_cache_free(sighand)'.
> We can return the memory to slab immediately, all we need is to
> be sure that sighand->siglock can't dissapear inside rcu protected
> section.
>
> To do so we need to initialize ->siglock inside ctor function,
> SLAB_DESTROY_BY_RCU does the rest.
Looks good to me by inspection, firing off some steamroller tests on it.
Thanx, Paul
> include/linux/sched.h | 8 --------
> kernel/fork.c | 21 +++++++++++----------
> kernel/signal.c | 2 +-
> fs/exec.c | 3 +--
> 4 files changed, 13 insertions(+), 21 deletions(-)
>
> Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
>
> --- 2.6.16-rc3/include/linux/sched.h~1_DBR 2006-02-16 22:04:46.000000000 +0300
> +++ 2.6.16-rc3/include/linux/sched.h 2006-02-18 00:05:20.000000000 +0300
> @@ -353,16 +353,8 @@ struct sighand_struct {
> atomic_t count;
> struct k_sigaction action[_NSIG];
> spinlock_t siglock;
> - struct rcu_head rcu;
> };
>
> -extern void sighand_free_cb(struct rcu_head *rhp);
> -
> -static inline void sighand_free(struct sighand_struct *sp)
> -{
> - call_rcu(&sp->rcu, sighand_free_cb);
> -}
> -
> /*
> * NOTE! "signal_struct" does not have it's own
> * locking, because a shared signal_struct always
> --- 2.6.16-rc3/kernel/fork.c~1_DBR 2006-02-16 23:15:23.000000000 +0300
> +++ 2.6.16-rc3/kernel/fork.c 2006-02-18 01:11:59.000000000 +0300
> @@ -784,14 +784,6 @@ int unshare_files(void)
>
> EXPORT_SYMBOL(unshare_files);
>
> -void sighand_free_cb(struct rcu_head *rhp)
> -{
> - struct sighand_struct *sp;
> -
> - sp = container_of(rhp, struct sighand_struct, rcu);
> - kmem_cache_free(sighand_cachep, sp);
> -}
> -
> static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
> {
> struct sighand_struct *sig;
> @@ -804,7 +796,6 @@ static inline int copy_sighand(unsigned
> rcu_assign_pointer(tsk->sighand, sig);
> if (!sig)
> return -ENOMEM;
> - spin_lock_init(&sig->siglock);
> atomic_set(&sig->count, 1);
> memcpy(sig->action, current->sighand->action, sizeof(sig->action));
> return 0;
> @@ -1345,11 +1336,21 @@ long do_fork(unsigned long clone_flags,
> #define ARCH_MIN_MMSTRUCT_ALIGN 0
> #endif
>
> +static void sighand_ctor(void *data, kmem_cache_t *cachep, unsigned long flags)
> +{
> + struct sighand_struct *sighand = data;
> +
> + if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
> + SLAB_CTOR_CONSTRUCTOR)
> + spin_lock_init(&sighand->siglock);
> +}
> +
> void __init proc_caches_init(void)
> {
> sighand_cachep = kmem_cache_create("sighand_cache",
> sizeof(struct sighand_struct), 0,
> - SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
> + SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU,
> + sighand_ctor, NULL);
> signal_cachep = kmem_cache_create("signal_cache",
> sizeof(struct signal_struct), 0,
> SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
> --- 2.6.16-rc3/kernel/signal.c~1_DBR 2006-02-13 21:47:19.000000000 +0300
> +++ 2.6.16-rc3/kernel/signal.c 2006-02-18 00:07:37.000000000 +0300
> @@ -330,7 +330,7 @@ void __exit_sighand(struct task_struct *
> /* Ok, we're done with the signal handlers */
> tsk->sighand = NULL;
> if (atomic_dec_and_test(&sighand->count))
> - sighand_free(sighand);
> + kmem_cache_free(sighand_cachep, sighand);
> }
>
> void exit_sighand(struct task_struct *tsk)
> --- 2.6.16-rc3/fs/exec.c~1_DBR 2006-02-16 22:34:59.000000000 +0300
> +++ 2.6.16-rc3/fs/exec.c 2006-02-18 01:12:36.000000000 +0300
> @@ -751,7 +751,6 @@ no_thread_group:
> /*
> * Move our state over to newsighand and switch it in.
> */
> - spin_lock_init(&newsighand->siglock);
> atomic_set(&newsighand->count, 1);
> memcpy(newsighand->action, oldsighand->action,
> sizeof(newsighand->action));
> @@ -768,7 +767,7 @@ no_thread_group:
> write_unlock_irq(&tasklist_lock);
>
> if (atomic_dec_and_test(&oldsighand->count))
> - sighand_free(oldsighand);
> + kmem_cache_free(sighand_cachep, oldsighand);
> }
>
> BUG_ON(!thread_group_leader(current));
>
prev parent reply other threads:[~2006-02-18 2:03 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-17 20:01 [PATCH] convert sighand_cache to use SLAB_DESTROY_BY_RCU Oleg Nesterov
2006-02-17 19:27 ` Hugh Dickins
2006-02-18 2:04 ` Paul E. McKenney [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060218020421.GG1291@us.ibm.com \
--to=paulmck@us.ibm.com \
--cc=akpm@osdl.org \
--cc=dipankar@in.ibm.com \
--cc=hugh@veritas.com \
--cc=linux-kernel@vger.kernel.org \
--cc=oleg@tv-sign.ru \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.