From: Maria Matejka Date: Thu, 5 Dec 2024 13:59:54 +0000 (+0100) Subject: BMP: refactored lists and table locks to tlists X-Git-Tag: v3.0.0~33 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1a04ce190e43b2878f15a8f2e3518cb578a2981;p=thirdparty%2Fbird.git BMP: refactored lists and table locks to tlists --- diff --git a/proto/bmp/bmp.c b/proto/bmp/bmp.c index 442798747..0a8ac03f3 100644 --- a/proto/bmp/bmp.c +++ b/proto/bmp/bmp.c @@ -583,12 +583,7 @@ bmp_add_table(struct bmp_proto *p, rtable *tab) static void bmp_remove_table(struct bmp_proto *p, struct bmp_table *bt) { - if (bt->channel) - { - channel_set_state(bt->channel, CS_STOP); - channel_set_state(bt->channel, CS_DOWN); - } - rt_export_unsubscribe(all, &bt->out_req); + rt_export_unsubscribe(all, &bt->out_req); HASH_REMOVE(p->table_map, HASH_TABLE, bt); @@ -598,38 +593,10 @@ bmp_remove_table(struct bmp_proto *p, struct bmp_table *bt) mb_free(bt); } -static inline void bmp_lock_table(struct bmp_proto *p UNUSED, struct bmp_table *bt) -{ bt->uc++; } - -struct bmp_table * +static inline struct bmp_table * bmp_get_table(struct bmp_proto *p, rtable *tab) { - struct bmp_table *bt = bmp_find_table(p, tab); - if (bt) - { - while (true) { - atomic_int i = bt->uc; - if (i == 0) - { - struct bmp_table *new = bmp_add_table(p, tab); - bmp_lock_table(p, new); - return new; - } - if (atomic_compare_exchange_strong_explicit(&bt->uc, &i, i+1, memory_order_acq_rel, memory_order_relaxed)) - return bt; - } - } - struct bmp_table *new = bmp_add_table(p, tab); - bmp_lock_table(p, new); - return new; -} - -static inline void bmp_unlock_table(struct bmp_proto *p, struct bmp_table *bt) -{ atomic_int i = 1; - if (atomic_compare_exchange_strong_explicit(&bt->uc, &i, 0, memory_order_acq_rel, memory_order_relaxed)) - bmp_remove_table(p, bt); - else - bt->uc--; + return bmp_find_table(p, tab) ?: bmp_add_table(p, tab); } @@ -674,10 +641,11 @@ bmp_add_stream(struct bmp_proto *p, struct bmp_peer *bp, u32 afi, bool policy, r bs->bgp = bp->bgp; bs->key = bmp_stream_key(afi, policy); - add_tail(&bp->streams, &bs->n); + bmp_peer_stream_add_tail(&bp->streams, bs); HASH_INSERT(p->stream_map, HASH_STREAM, bs); - bs->table = bmp_get_table(p, tab); + struct bmp_table *bt = bmp_get_table(p, tab); + bmp_table_stream_add_tail(&bt->streams, bs); bs->sender = sender; bs->sync = false; @@ -689,11 +657,13 @@ bmp_add_stream(struct bmp_proto *p, struct bmp_peer *bp, u32 afi, bool policy, r static void bmp_remove_stream(struct bmp_proto *p, struct bmp_stream *bs) { - rem_node(&bs->n); + bmp_peer_stream_rem_node(bmp_peer_stream_enlisted(bs), bs); HASH_REMOVE(p->stream_map, HASH_STREAM, bs); - bmp_unlock_table(p, bs->table); - bs->table = NULL; + SKIP_BACK_DECLARE(struct bmp_table, bt, streams, bmp_table_stream_enlisted(bs)); + bmp_table_stream_rem_node(&bt->streams, bs); + if (EMPTY_TLIST(bmp_table_stream, &bt->streams)) + bmp_remove_table(p, bt); mb_free(bs); } @@ -723,7 +693,7 @@ bmp_add_peer(struct bmp_proto *p, ea_list *bgp_attr) } bp->bgp = bgp_attr; - init_list(&bp->streams); + bp->streams = (TLIST_LIST(bmp_peer_stream)) {}; HASH_INSERT(p->peer_map, HASH_PEER, bp); @@ -764,8 +734,7 @@ bmp_add_peer(struct bmp_proto *p, ea_list *bgp_attr) static void bmp_remove_peer(struct bmp_proto *p, struct bmp_peer *bp) { - struct bmp_stream *bs, *bs_next; - WALK_LIST_DELSAFE(bs, bs_next, bp->streams) + WALK_TLIST_DELSAFE(bmp_peer_stream, bs, &bp->streams) bmp_remove_stream(p, bs); HASH_REMOVE(p->peer_map, HASH_PEER, bp); @@ -1115,7 +1084,7 @@ bmp_feed_end(struct rt_export_request *req) HASH_WALK(p->stream_map, next, bs) { - if ((bs->table == bt) && !bs->sync) + if ((bmp_table_stream_enlisted(bs) == &bt->streams) && !bs->sync) { bmp_route_monitor_end_of_rib(p, bs); bs->sync = true; @@ -1377,8 +1346,7 @@ bmp_process_proto_state_change(struct bmp_proto *p, struct lfjour_item *last_up) * notifications from that peer. Therefore, peers established after BMP * session are considered synced with empty RIB. */ - struct bmp_stream *bs; - WALK_LIST(bs, bp->streams) + WALK_TLIST(bmp_peer_stream, bs, &bp->streams) { bmp_route_monitor_end_of_rib(p, bs); bs->sync = true; diff --git a/proto/bmp/bmp.h b/proto/bmp/bmp.h index 9ab379221..283c74d08 100644 --- a/proto/bmp/bmp.h +++ b/proto/bmp/bmp.h @@ -12,6 +12,7 @@ #include "nest/bird.h" #include "nest/protocol.h" #include "lib/lists.h" +#include "lib/tlists.h" #include "nest/route.h" #include "lib/event.h" #include "lib/hash.h" @@ -91,33 +92,46 @@ struct bmp_proto { byte msgbuf[BMP_MSGBUF_LEN]; // Buffer for preparing the messages before sending them out }; -struct bmp_peer { - ea_list *bgp; - struct bmp_peer *next; - list streams; -}; - struct bmp_stream { - node n; + TLIST_NODE(bmp_peer_stream, struct bmp_stream) peer_node; + TLIST_NODE(bmp_table_stream, struct bmp_stream) table_node; ea_list *bgp; u32 key; bool sync; bool shutting_down; struct bmp_stream *next; - struct bmp_table *table; ea_list *sender; int in_pre_policy; }; +#define TLIST_PREFIX bmp_peer_stream +#define TLIST_TYPE struct bmp_stream +#define TLIST_ITEM peer_node +#define TLIST_WANT_ADD_TAIL + +#include "lib/tlists.h" + +#define TLIST_PREFIX bmp_table_stream +#define TLIST_TYPE struct bmp_stream +#define TLIST_ITEM table_node +#define TLIST_WANT_ADD_TAIL + +#include "lib/tlists.h" + +struct bmp_peer { + ea_list *bgp; + struct bmp_peer *next; + TLIST_LIST(bmp_peer_stream) streams; +}; + struct bmp_table { rtable *table; struct bmp_table *next; - struct channel *channel; struct rt_export_request out_req; struct bmp_proto *p; struct rt_export_feeder in_req; event event; - atomic_int uc; + TLIST_LIST(bmp_table_stream) streams; };