On Fri, Apr 20, 2007 at 10:02:08PM +0400, Oleg Nesterov wrote: > On 04/19, Rafael J. Wysocki wrote: > > > > On Thursday, 19 April 2007 14:02, Gautham R Shenoy wrote: > > > This patch fixes the race pointed out by Oleg Nesterov. > > > > > > * Freezer marks a thread as freezeable. > > > * The thread now marks itself PF_NOFREEZE causing it to > > > freeze on calling try_to_freeze(). Thus the task is frozen, even though > > > it doesn't want to. > > > * Subsequent thaw_processes() will also fail to thaw the task since it is > > > marked PF_NOFREEZE. > > > > > > Avoid this problem by checking the current task's PF_NOFREEZE status in > > > the > > > refrigerator before marking current as frozen. > > > > > > Signed-off-by: Gautham R Shenoy <[EMAIL PROTECTED]> > > > > Looks good, although I'm not sure if we don't need to call > > recalc_sigpending() > > for tasks that turn out to be PF_NOFREEZE. > > I agree, we should clear TIF_SIGPENDING. It is not so critical for user-space > tasks, but for the kernel thread it may remain pending forever, causing subtle > failures. > > Gautham, isn't it possible to make a more simpler patch ? Just add PF_NOFREEZE > check to frozen_process, > > static inline void frozen_process(struct task_struct *p) > { > if (!unlikely(current->flags & PF_NOFREEZE)) { > p->flags |= PF_FROZEN; > wmb(); > } > clear_tsk_thread_flag(p, TIF_FREEZE); > } > > No?
Actually yes. The idea anyway was to check one last time before declaring ourselves as frozen. So I thought the best place was inside refrigerator since we are already holding the task_lock there. I wasn't too sure about calling recalc_sigpending(), but now that you mention it, I agree, this would be a nicer way to do it. Btw, since frozen_process is currently being called only from refrigerator, I am wondering if we still need the struct task_struct *p parameter there. It's very unlikely that some other task would mark a particular task as frozen. No? Anyways, Andrew, Could you please replace the earlier sent patch titled "fix_pf_nofreeze_and_freezeable_race.patch" with the following one? Thanks and Regards gautham. --> This patch fixes the race pointed out by Oleg Nesterov. * Freezer marks a thread as freezeable. * The thread now marks itself PF_NOFREEZE causing it to freeze on calling try_to_freeze(). Thus the task is frozen, even though it doesn't want to. * Subsequent thaw_processes() will also fail to thaw the task since it is marked PF_NOFREEZE. Avoid this problem by checking the task's PF_NOFREEZE status in frozen_processes() before marking the task as frozen. Signed-off-by: Gautham R Shenoy <[EMAIL PROTECTED]> --- include/linux/freezer.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) Index: linux-2.6.21-rc6/include/linux/freezer.h =================================================================== --- linux-2.6.21-rc6.orig/include/linux/freezer.h +++ linux-2.6.21-rc6/include/linux/freezer.h @@ -57,8 +57,10 @@ static inline int thaw_process(struct ta */ static inline void frozen_process(struct task_struct *p) { - p->flags |= PF_FROZEN; - wmb(); + if (!unlikely(p->flags & PF_NOFREEZE)) { + p->flags |= PF_FROZEN; + wmb(); + } clear_tsk_thread_flag(p, TIF_FREEZE); } -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" - 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/