- We are not guaranteed that we're not dropping a reference that
we did not add. Call LLE_REMREF() only when callout_stop() actually canceled a pending callout. - callout_reset() may cancel a pending callout. When callout_reset() canceled a pending callout, call LLE_REMREF() to drop a reference for the canceled callout. MFC after: 1 week
This commit is contained in:
parent
718cdf7f80
commit
ef8d671cca
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=199225
@ -439,31 +439,27 @@ nd6_options(union nd_opts *ndopts)
|
||||
void
|
||||
nd6_llinfo_settimer_locked(struct llentry *ln, long tick)
|
||||
{
|
||||
int canceled;
|
||||
|
||||
if (tick < 0) {
|
||||
ln->la_expire = 0;
|
||||
ln->ln_ntick = 0;
|
||||
callout_stop(&ln->ln_timer_ch);
|
||||
/*
|
||||
* XXX - do we know that there is
|
||||
* callout installed? i.e. are we
|
||||
* guaranteed that we're not dropping
|
||||
* a reference that we did not add?
|
||||
* KMM
|
||||
*/
|
||||
LLE_REMREF(ln);
|
||||
canceled = callout_stop(&ln->ln_timer_ch);
|
||||
} else {
|
||||
ln->la_expire = time_second + tick / hz;
|
||||
LLE_ADDREF(ln);
|
||||
if (tick > INT_MAX) {
|
||||
ln->ln_ntick = tick - INT_MAX;
|
||||
callout_reset(&ln->ln_timer_ch, INT_MAX,
|
||||
canceled = callout_reset(&ln->ln_timer_ch, INT_MAX,
|
||||
nd6_llinfo_timer, ln);
|
||||
} else {
|
||||
ln->ln_ntick = 0;
|
||||
callout_reset(&ln->ln_timer_ch, tick,
|
||||
canceled = callout_reset(&ln->ln_timer_ch, tick,
|
||||
nd6_llinfo_timer, ln);
|
||||
}
|
||||
}
|
||||
if (canceled)
|
||||
LLE_REMREF(ln);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1048,6 +1044,9 @@ nd6_free(struct llentry *ln, int gc)
|
||||
else
|
||||
nd6_llinfo_settimer(ln, (long)V_nd6_gctimer * hz);
|
||||
splx(s);
|
||||
LLE_WLOCK(ln);
|
||||
LLE_REMREF(ln);
|
||||
LLE_WUNLOCK(ln);
|
||||
return (LIST_NEXT(ln, lle_next));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user