svn commit: r199225 - head/sys/netinet6
Hajimu UMEMOTO
ume at FreeBSD.org
Thu Nov 12 14:48:37 UTC 2009
Author: ume
Date: Thu Nov 12 14:48:36 2009
New Revision: 199225
URL: http://svn.freebsd.org/changeset/base/199225
Log:
- 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
Modified:
head/sys/netinet6/nd6.c
Modified: head/sys/netinet6/nd6.c
==============================================================================
--- head/sys/netinet6/nd6.c Thu Nov 12 14:27:09 2009 (r199224)
+++ head/sys/netinet6/nd6.c Thu Nov 12 14:48:36 2009 (r199225)
@@ -439,31 +439,27 @@ skip1:
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));
}
More information about the svn-src-head
mailing list