Date: Thu, 4 Jul 2002 06:20:44 -0700 (PDT) From: David Xu <bsddiy@yahoo.com> To: Bruce Evans <bde@zeta.org.au> Cc: julian@elischer.org, freebsd-current@FreeBSD.ORG Subject: Re: Timeout and SMP race Message-ID: <20020704132044.7338.qmail@web20909.mail.yahoo.com>
next in thread | raw e-mail | index | archive | help
in RELENG_4, when one calls callout_stop() (not nested in softclock execute path , I am not talking about this case), after it returns, he can believe that the callout is truely stopped, however in CURRENT, this assumption is false, now we must care if callout_stop() truely stopped the callout when it returned, this is all difference I see, we bring in this race which not exists in RELENG_4, see what hacking code put in kern_condvar.c and kern_synch.c in CURRENT source, this kind of problem is arising and knocking door. sorry, our company's smtp server refuse to relay my mail from home, I must send it from yahoo. :( -David Xu ----- Original Message ----- From: "Bruce Evans" <bde@zeta.org.au> To: "David Xu" <davidx@viasoft.com.cn> Cc: "Julian Elischer" <julian@elischer.org>; <freebsd-current@FreeBSD.ORG> Sent: Thursday, July 04, 2002 7:02 PM Subject: Re: Timeout and SMP race > On Thu, 4 Jul 2002, David Xu wrote: > > > ----- Original Message ----- > > From: "Julian Elischer" <julian@elischer.org> > > To: "David Xu" <davidx@viasoft.com.cn> > > Cc: <freebsd-current@FreeBSD.ORG> > > Sent: Thursday, July 04, 2002 4:36 PM > > Subject: Re: Timeout and SMP race > > > > > > > if another thread other than softclock itself is calling callout_stop(), > > and callout_stop() detected that softclock is currently running the > > callout, it should wait until softclock finishes the work, then return. > > softclock() intentionally releases callout_lock() to allow other processes > to manipulate callouts. What is the race exactly? Concurrent calls to > softclock() seem to be possible but seem to be handled correctly (internal > locking prevents problems). Well, I can see one race in softclock(): > > % c_func = c->c_func; > % c_arg = c->c_arg; > % c_flags = c->c_flags; > > This caches some values, as is needed since the 'c' pointer may become > invalid after we release the lock ... but the things pointed to may become > invalid too. > > % c->c_func = NULL; > % if (c->c_flags & CALLOUT_LOCAL_ALLOC) { > % c->c_flags = CALLOUT_LOCAL_ALLOC; > % SLIST_INSERT_HEAD(&callfree, c, > % c_links.sle); > % } else > % c->c_flags &= ~CALLOUT_PENDING; > % mtx_unlock_spin(&callout_lock); > > callout_stop() may stop 'c' here. It won't do much, since we have already > set c->c_func to NULL, but its caller may want the callout actually stopped > so that it can do things like unloading the old c->c_func. > > % if ((c_flags & CALLOUT_MPSAFE) == 0) > % mtx_lock(&Giant); > % c_func(c_arg); > > This calls through a possibly-invalid function pointer. > > % if ((c_flags & CALLOUT_MPSAFE) == 0) > % mtx_unlock(&Giant); > % mtx_lock_spin(&callout_lock); > > This seems to be an old bug. In RELENG_4, splsoftclock() gives a more > global lock, but there is nothing to prevent callout_stop() being run > at splsoftclock(). In fact, it must be able to run when called nested > from inside softclock(), since it might be called from the handler. > Waiting in callout_stop() for softclock() to finish would deadlock in > this case. It's interesting that this case is (always?) avoided in > untimeout() by not calling callout_stop() when c->c_func == NULL. > > softclock() can't do anything about c->c_func going away after it is > called. Clients must somehow avoid killing it. > > I think c->c_func rarely goes away, and the race that you noticed is > lost more often. > > Bruce > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-current" in the body of the message __________________________________________________ Do You Yahoo!? Sign up for SBC Yahoo! Dial - First Month Free http://sbc.yahoo.com To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020704132044.7338.qmail>