On Sat, 10 Mar 2007, Oleg Nesterov wrote: > Davide Libenzi wrote: > > > > +int signalfd_deliver(struct sighand_struct *sighand, int sig, > > + struct siginfo *info) > > +{ > > + int nsig = 0; > > + struct list_head *pos; > > + struct signalfd_ctx *ctx; > > + > > + list_for_each(pos, &sighand->sfdlist) { > > + ctx = list_entry(pos, struct signalfd_ctx, lnk); > > list_for_each_entry()
Will do, thx! > > + /* > > + * We use a negative signal value as a way to broadcast that the > > + * sighand has been orphaned, so that we can notify all the > > + * listeners about this. Remeber the ctx->sigmask is inverted, > > + * so if the user is interested in a signal, that corresponding > > + * bit will be zero. > > + */ > > + if (sig < 0 || !sigismember(&ctx->sigmask, sig)) { > > + __wake_up_locked(&ctx->wqh, > > + TASK_UNINTERRUPTIBLE | > > TASK_INTERRUPTIBLE); > > wake_up_locked(&ctx->wqh) Yeah, will do. > > + ctx->sighand = current->sighand; > > + atomic_inc(&ctx->sighand->count); > > I personally don't like this. de_thread() was/is the source of numerous > problems, and this patch adds yet another subtle dependency. The usage of > "private" __cleanup_sighand() is not good per se, imho. This we agree ... > Also, this is not so flexible, we can't take S_ISUID into account. It seems > logical to preserve ctx after a "normal" exec. This, not really. I'm not sure we want to leak this out of an exec. > > + spin_lock_irq(&ctx->sighand->siglock); > > + ctx->sigmask = sigmask; > > + spin_unlock_irq(&ctx->sighand->siglock); > > + wake_up(&ctx->wqh); > > Race with signalfd_read()->__add_wait_queue(). Ack. > > + if (sighand != ctx->tsk->sighand || ctx->tsk->signal == NULL || > > We don't need "ctx->tsk->signal == NULL". tsk->signal == NULL (when checked > under ->siglock) implies tsk->sighand == NULL. This is covered by the first > "sighand != ctx->tsk->sighand" check. Extra check, due to rely less on the exit_signal code. > > + __remove_wait_queue(&ctx->wqh, &wait); > > + set_current_state(TASK_RUNNING); > > We don't need mb() here. Ack. > > +void signal_fill_info(struct siginfo *dinfo, int sig, struct siginfo > > *sinfo) > > +{ > > + switch ((unsigned long) sinfo) { > > + case (unsigned long) SEND_SIG_NOINFO: > > + dinfo->si_signo = sig; > > + dinfo->si_errno = 0; > > + dinfo->si_code = SI_USER; > > + dinfo->si_pid = current->pid; > > + dinfo->si_uid = current->uid; > > + break; > > + case (unsigned long) SEND_SIG_PRIV: > > + dinfo->si_signo = sig; > > + dinfo->si_errno = 0; > > + dinfo->si_code = SI_KERNEL; > > + dinfo->si_pid = 0; > > + dinfo->si_uid = 0; > > + break; > > + default: > > + copy_siginfo(dinfo, sinfo); > > + } > > +} > > This change seems unneeded? Yes, it leaked out from the version of signalfd that had its own queue. > I'd suggest to remove signalfd_ctx->sighand. de_thread()/exit_signal() call > > signalfd_exit_task(struct sighand_struct *sighand) > { > list_for_each_entry_safe(ctx, sighand->sfdlist) > if (ctx->tsk == current) { > wake_up_locked(ctx->wqh); > list_del_init(ctx->lnk); > } > } > > signalfd_read()/signalfd_poll use > > static struct sighand_struct *ctx_try_to_lock(struct signalfd_ctx *ctx, > flags) > { > struct sighand_struct *ret; > > rcu_read_lock(); > ret = lock_task_sighand(ctx->task); > rcu_read_unlock(); > > if (ret && list_empty(ctx->lnk)) { > unlock_task_sighand(ctx->task); > ret = NULL; > } > > return ret; > } > > instead of "spin_lock_irq(ctx->sighand)" + "if (ctx->sighand != > ctx->tsk->sighand)". > > Possible? > > Note that signalfd_exit_task() is generic, could be used in another context, > de_thread() can avoid the call if !suid. I think it looks good to me. Will give it a spin today. > How about CONFIG_SIGNALFD, btw? Yes, I was already planning it. > Davide, could you please cc me? I am not subscribed to lkml, noticed the new > version by accident. Will do, thx! - Davide - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/