[bgpd] simplify peer refcounts, squash slow peer leak
2006-09-14 Paul Jakma <paul.jakma@sun.com>
* (general) fix the peer refcount issue exposed by previous, by
just removing refcounting of peer threads, which is mostly
senseless as they're references leading from struct peer,
which peer_free cancels anyway. No need to muck around..
* bgp_fsm.h: Just remove the refcounting from the various
TIMER/READ/WRITE/EVENT ON/OFF/ADD macros.
* bgp_fsm.c: (bgp_stop) use BGP_EVENT_FLUSH, no refcounts attached
to events anymore.
(bgp_event) remove peer_unlock, events not refcounted.
* bgpd.c: (peer_free) flush events before free.
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index 02aaf3a..393b00d 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -1,5 +1,18 @@
2006-09-14 Paul Jakma <paul.jakma@sun.com>
+ * (general) fix the peer refcount issue exposed by previous, by
+ just removing refcounting of peer threads, which is mostly
+ senseless as they're references leading from struct peer,
+ which peer_free cancels anyway. No need to muck around..
+ * bgp_fsm.h: Just remove the refcounting from the various
+ TIMER/READ/WRITE/EVENT ON/OFF/ADD macros.
+ * bgp_fsm.c: (bgp_stop) use BGP_EVENT_FLUSH, no refcounts attached
+ to events anymore.
+ (bgp_event) remove peer_unlock, events not refcounted.
+ * bgpd.c: (peer_free) flush events before free.
+
+2006-09-14 Paul Jakma <paul.jakma@sun.com>
+
* (general) Fix some niggly issues around 'shutdown' and clearing
by adding a Clearing FSM wait-state and a hidden 'Deleted'
FSM state, to allow deleted peers to 'cool off' and hit 0
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index bdb6517..cc2b2c3 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -426,7 +426,6 @@
{
afi_t afi;
safi_t safi;
- unsigned int i;
char orf_name[BUFSIZ];
/* Increment Dropped count. */
@@ -500,10 +499,8 @@
BGP_TIMER_OFF (peer->t_asorig);
BGP_TIMER_OFF (peer->t_routeadv);
- /* Delete all existing events of the peer,
- and corresponding peer ref-count */
- for (i = thread_cancel_event (master, peer); i > 0; i--)
- peer_unlock (peer); /* thread event reference */
+ /* Delete all existing events of the peer */
+ BGP_EVENT_FLUSH (peer);
/* Stream reset. */
peer->packet_size = 0;
@@ -1101,6 +1098,5 @@
bgp_timer_set (peer);
}
- peer_unlock (peer); /* bgp-event peer reference */
return ret;
}
diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h
index 0a5d371..c51bed3 100644
--- a/bgpd/bgp_fsm.h
+++ b/bgpd/bgp_fsm.h
@@ -25,77 +25,55 @@
/* Macro for BGP read, write and timer thread. */
#define BGP_READ_ON(T,F,V) \
do { \
- if (!T) \
- { \
- peer_lock (peer); \
- THREAD_READ_ON(master,T,F,peer,V); \
- } \
+ if (!(T) && (peer->status != Deleted)) \
+ THREAD_READ_ON(master,T,F,peer,V); \
} while (0)
#define BGP_READ_OFF(T) \
do { \
if (T) \
- { \
- peer_unlock (peer); \
- THREAD_READ_OFF(T); \
- } \
+ THREAD_READ_OFF(T); \
} while (0)
#define BGP_WRITE_ON(T,F,V) \
do { \
if (!(T) && (peer->status != Deleted)) \
- { \
- peer_lock (peer); \
- THREAD_WRITE_ON(master,(T),(F),peer,(V)); \
- } \
+ THREAD_WRITE_ON(master,(T),(F),peer,(V)); \
} while (0)
#define BGP_WRITE_OFF(T) \
do { \
if (T) \
- { \
- peer_unlock (peer); \
- THREAD_WRITE_OFF(T); \
- } \
+ THREAD_WRITE_OFF(T); \
} while (0)
#define BGP_TIMER_ON(T,F,V) \
do { \
if (!(T) && (peer->status != Deleted)) \
- { \
- peer_lock (peer); \
- THREAD_TIMER_ON(master,(T),(F),peer,(V)); \
- } \
+ THREAD_TIMER_ON(master,(T),(F),peer,(V)); \
} while (0)
#define BGP_TIMER_OFF(T) \
do { \
if (T) \
- { \
- peer_unlock (peer); \
- THREAD_TIMER_OFF(T); \
- } \
+ THREAD_TIMER_OFF(T); \
} while (0)
#define BGP_EVENT_ADD(P,E) \
do { \
if ((P)->status != Deleted) \
- { \
- peer_lock (peer); /* bgp event reference */ \
- thread_add_event (master, bgp_event, (P), (E)); \
- } \
+ thread_add_event (master, bgp_event, (P), (E)); \
} while (0)
-#define BGP_EVENT_DELETE(P) \
+#define BGP_EVENT_FLUSH(P) \
do { \
- peer_unlock (peer); /* bgp event peer reference */ \
assert (peer); \
thread_cancel_event (master, (P)); \
} while (0)
#define BGP_EVENT_FLUSH_ADD(P,E) \
do { \
- BGP_EVENT_DELETE(P); \
+ BGP_EVENT_FLUSH(P); \
BGP_EVENT_ADD(P,E); \
} while (0)
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 733b33a..89f8262 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -695,6 +695,7 @@
bgp_timer_set (peer);
BGP_READ_OFF (peer->t_read);
BGP_WRITE_OFF (peer->t_write);
+ BGP_EVENT_FLUSH (peer);
if (peer->desc)
XFREE (MTYPE_PEER_DESC, peer->desc);