Re: Let callout_reset return if it reschedules a pending callout
On Thu, Mar 1, 2018 at 5:45 AM, Joerg Sonnenbergerwrote: > On Thu, Mar 01, 2018 at 01:58:29AM +0900, Ryota Ozaki wrote: >> On Wed, Feb 28, 2018 at 10:11 PM, Joerg Sonnenberger wrote: >> > On Wed, Feb 28, 2018 at 05:47:13PM +0900, Ryota Ozaki wrote: >> >> The feature is useful when you have a reference to an object that is >> >> passed to a callout. In this case you need to take care of a >> >> reference leak on callout_reset (and other APIs); it silently >> >> reschedules (IOW cancels) a pending callout and leaks a reference. >> >> Unfortunately callout_reset doesn't tell us the reschedule. >> > >> > Can we look at this part first before discussing any API changes? >> > Why can't you store the reference next to callout instance itself? >> >> Oh, my explanation was quite confusing... I meant that the object >> has a reference counter and the counter is incremented to indicate >> that it is referred by a callout. obj_ref and obj_unref can be >> thought as obj->refcnt++ and obj->refcnt-- respectively. > > Just consider the object reference owned by the callout struct. You > change the reference count when the callout is destroyed or if the > callout is reassigned, not because it is executed. Oh, there is a limitation I didn't mention yet; we can't use callout_halt to stop the callout when we try to destroy an obj because of the issue of softnet_lock vs. callout_halt(*). (*) http://mail-index.netbsd.org/tech-net/2018/01/12/msg006612.html We can use only callout_stop that doesn't ensure if a callout stops or not. It requires that we track the activity of the callout, which is what a refcount does. ozaki-r
Re: Let callout_reset return if it reschedules a pending callout
On Thu, Mar 01, 2018 at 01:58:29AM +0900, Ryota Ozaki wrote: > On Wed, Feb 28, 2018 at 10:11 PM, Joerg Sonnenbergerwrote: > > On Wed, Feb 28, 2018 at 05:47:13PM +0900, Ryota Ozaki wrote: > >> The feature is useful when you have a reference to an object that is > >> passed to a callout. In this case you need to take care of a > >> reference leak on callout_reset (and other APIs); it silently > >> reschedules (IOW cancels) a pending callout and leaks a reference. > >> Unfortunately callout_reset doesn't tell us the reschedule. > > > > Can we look at this part first before discussing any API changes? > > Why can't you store the reference next to callout instance itself? > > Oh, my explanation was quite confusing... I meant that the object > has a reference counter and the counter is incremented to indicate > that it is referred by a callout. obj_ref and obj_unref can be > thought as obj->refcnt++ and obj->refcnt-- respectively. Just consider the object reference owned by the callout struct. You change the reference count when the callout is destroyed or if the callout is reassigned, not because it is executed. Joerg
Re: Let callout_reset return if it reschedules a pending callout
On Wed, Feb 28, 2018 at 10:11 PM, Joerg Sonnenbergerwrote: > On Wed, Feb 28, 2018 at 05:47:13PM +0900, Ryota Ozaki wrote: >> The feature is useful when you have a reference to an object that is >> passed to a callout. In this case you need to take care of a >> reference leak on callout_reset (and other APIs); it silently >> reschedules (IOW cancels) a pending callout and leaks a reference. >> Unfortunately callout_reset doesn't tell us the reschedule. > > Can we look at this part first before discussing any API changes? > Why can't you store the reference next to callout instance itself? Oh, my explanation was quite confusing... I meant that the object has a reference counter and the counter is incremented to indicate that it is referred by a callout. obj_ref and obj_unref can be thought as obj->refcnt++ and obj->refcnt-- respectively. ozaki-r
Re: Let callout_reset return if it reschedules a pending callout
On Wed, Feb 28, 2018 at 05:47:13PM +0900, Ryota Ozaki wrote: > The feature is useful when you have a reference to an object that is > passed to a callout. In this case you need to take care of a > reference leak on callout_reset (and other APIs); it silently > reschedules (IOW cancels) a pending callout and leaks a reference. > Unfortunately callout_reset doesn't tell us the reschedule. Can we look at this part first before discussing any API changes? Why can't you store the reference next to callout instance itself? Joerg
Let callout_reset return if it reschedules a pending callout
Hi, This proposal lets callout_reset and callout_schedule return true if it reschedules a pending callout and return false otherwise. The feature is useful when you have a reference to an object that is passed to a callout. In this case you need to take care of a reference leak on callout_reset (and other APIs); it silently reschedules (IOW cancels) a pending callout and leaks a reference. Unfortunately callout_reset doesn't tell us the reschedule. To avoid the leak with the current APIs of callout, we have to do something like this: if (callout_pending(>ch)) { expired = callout_stop(>ch); if (!expired) obj_unref(obj); } obj_ref(obj); callout_reset(>ch); callout_pending is required to exclude the case that the callout has never been scheduled because callout_stop just checks CALLOUT_FIRED. The proposal makes the code simple like this: obj_ref(obj); canceled = callout_reset(>ch); if (canceled) obj_unref(obj); This is a patch (quite simple): http://www.netbsd.org/~ozaki-r/callout_reset.diff Note that this proposal changes API/ABI however we don't need to tweak existing callers of callout_reset/callout_schedule because it doesn't break the original usage. Any comments? Thanks, ozaki-r