On 03/03, Sebastian Andrzej Siewior wrote: > > +static struct sigqueue *sigqueue_from_cache(struct task_struct *t) > +{ > + struct sigqueue *q = t->sigqueue_cache; > + > + if (q && cmpxchg(&t->sigqueue_cache, q, NULL) == q) > + return q; > + return NULL; > +} > + > +static bool sigqueue_add_cache(struct task_struct *t, struct sigqueue *q) > +{ > + if (!t->sigqueue_cache && cmpxchg(&t->sigqueue_cache, NULL, q) == NULL) > + return true; > + return false; > +}
Do we really need cmpxchg? It seems they are always called with spinlock held. > static struct sigqueue * > -__sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int > override_rlimit) > +__sigqueue_do_alloc(int sig, struct task_struct *t, gfp_t flags, > + int override_rlimit, bool fromslab) > { > struct sigqueue *q = NULL; > struct user_struct *user; > @@ -432,7 +450,10 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t > flags, int override_rlimi > rcu_read_unlock(); > > if (override_rlimit || likely(sigpending <= task_rlimit(t, > RLIMIT_SIGPENDING))) { > - q = kmem_cache_alloc(sigqueue_cachep, flags); > + if (!fromslab) > + q = sigqueue_from_cache(t); > + if (!q) > + q = kmem_cache_alloc(sigqueue_cachep, flags); I won't insist but afaics you can avoid the new arg/function and simplify this patch. __sigqueue_alloc() can simply check "sig > 0" or valid_signal(sig) rather than "!fromslab". > +static void __sigqueue_cache_or_free(struct sigqueue *q) > +{ > + struct user_struct *up; > + > + if (q->flags & SIGQUEUE_PREALLOC) > + return; > + > + up = q->user; > + if (atomic_dec_and_test(&up->sigpending)) > + free_uid(up); > + if (!task_is_realtime(current) || !sigqueue_add_cache(current, q)) > + kmem_cache_free(sigqueue_cachep, q); > +} Well, this duplicates __sigqueue_free... Do we really need the new helper? What if we simply change __sigqueue_free() to do sigqueue_add_cache() if task_is_realtime() && !PF_EXITING ? This too can simplify the patch... Oleg.