mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Hostentry usecount converted to lfuc
This commit is contained in:
parent
e0a1bbdf65
commit
728d19703d
10
nest/route.h
10
nest/route.h
@ -92,6 +92,7 @@ extern uint rtable_max_id;
|
||||
struct birdloop *loop; /* Service thread */ \
|
||||
netindex_hash *netindex; /* Prefix index for this table */ \
|
||||
event *nhu_event; /* Nexthop updater */ \
|
||||
event *hcu_event; /* Hostcache updater */ \
|
||||
|
||||
/* The complete rtable structure */
|
||||
struct rtable_private {
|
||||
@ -121,6 +122,7 @@ struct rtable_private {
|
||||
* obstacle from this routing table.
|
||||
*/
|
||||
struct event *nhu_uncork_event; /* Helper event to schedule NHU on uncork */
|
||||
struct event *hcu_uncork_event; /* Helper event to schedule HCU on uncork */
|
||||
struct timer *prune_timer; /* Timer for periodic pruning / GC */
|
||||
struct event *prune_event; /* Event for prune execution */
|
||||
struct birdloop_flag_handler fh; /* Handler for simple events */
|
||||
@ -503,14 +505,15 @@ struct hostentry {
|
||||
rtable *owner; /* Nexthop owner table */
|
||||
struct hostentry *next; /* Next in hash chain */
|
||||
unsigned hash_key; /* Hash key */
|
||||
unsigned uc; /* Use count */
|
||||
ea_list *src; /* Source attributes */
|
||||
byte nexthop_linkable; /* Nexthop list is completely non-device */
|
||||
u32 igp_metric; /* Chosen route IGP metric */
|
||||
ea_list *src; /* Source attributes */
|
||||
struct lfuc uc; /* Use count */
|
||||
byte nexthop_linkable; /* Nexthop list is completely non-device */
|
||||
};
|
||||
|
||||
struct hostcache {
|
||||
slab *slab; /* Slab holding all hostentries */
|
||||
rtable *tab; /* Parent routing table */
|
||||
struct hostentry **hash_table; /* Hash table for hostentries */
|
||||
unsigned hash_order, hash_shift;
|
||||
unsigned hash_max, hash_min;
|
||||
@ -518,7 +521,6 @@ struct hostcache {
|
||||
linpool *lp; /* Linpool for trie */
|
||||
struct f_trie *trie; /* Trie of prefixes that might affect hostentries */
|
||||
list hostentries; /* List of all hostentries */
|
||||
event update;
|
||||
struct rt_export_request req; /* Notifier */
|
||||
};
|
||||
|
||||
|
@ -143,14 +143,14 @@ struct ea_class ea_gen_nexthop = {
|
||||
ea_gen_hostentry_stored(const eattr *ea)
|
||||
{
|
||||
struct hostentry_adata *had = (struct hostentry_adata *) ea->u.ptr;
|
||||
had->he->uc++;
|
||||
lfuc_lock(&had->he->uc);
|
||||
}
|
||||
|
||||
static void
|
||||
ea_gen_hostentry_freed(const eattr *ea)
|
||||
{
|
||||
struct hostentry_adata *had = (struct hostentry_adata *) ea->u.ptr;
|
||||
had->he->uc--;
|
||||
lfuc_unlock(&had->he->uc, birdloop_event_list(had->he->owner->loop), had->he->owner->hcu_event);
|
||||
}
|
||||
|
||||
struct ea_class ea_gen_hostentry = {
|
||||
|
@ -3812,8 +3812,8 @@ rt_commit(struct config *new, struct config *old)
|
||||
|
||||
rt_check_cork_low(tab);
|
||||
|
||||
if (tab->hostcache && ev_get_list(&tab->hostcache->update) == &rt_cork.queue)
|
||||
ev_postpone(&tab->hostcache->update);
|
||||
if (tab->hcu_event && (ev_get_list(tab->hcu_event) == &rt_cork.queue))
|
||||
ev_postpone(tab->hcu_event);
|
||||
|
||||
/* Force one more loop run */
|
||||
birdloop_flag(tab->loop, RTF_DELETE);
|
||||
@ -4223,7 +4223,7 @@ static void
|
||||
hc_notify_log_state_change(struct rt_export_request *req, u8 state)
|
||||
{
|
||||
struct hostcache *hc = SKIP_BACK(struct hostcache, req, req);
|
||||
rt_trace((rtable *) hc->update.data, D_STATES, "HCU Export state changed to %s", rt_export_state_name(state));
|
||||
rt_trace(hc->tab, D_STATES, "HCU Export state changed to %s", rt_export_state_name(state));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4231,8 +4231,8 @@ hc_notify_export_one(struct rt_export_request *req, const net_addr *net, struct
|
||||
{
|
||||
struct hostcache *hc = SKIP_BACK(struct hostcache, req, req);
|
||||
|
||||
RT_LOCKED((rtable *) hc->update.data, tab)
|
||||
if (ev_active(&hc->update) || !trie_match_net(hc->trie, net))
|
||||
RT_LOCKED(hc->tab, tab)
|
||||
if (ev_active(tab->hcu_event) || !trie_match_net(hc->trie, net))
|
||||
/* No interest in this update, mark seen only */
|
||||
rpe_mark_seen_all(req->hook, first, NULL, NULL);
|
||||
else
|
||||
@ -4250,8 +4250,8 @@ hc_notify_export_one(struct rt_export_request *req, const net_addr *net, struct
|
||||
/* Yes, something has actually changed. Do the hostcache update. */
|
||||
if ((o != RTE_VALID_OR_NULL(new_best))
|
||||
&& (atomic_load_explicit(&req->hook->export_state, memory_order_acquire) == TES_READY)
|
||||
&& !ev_active(&hc->update))
|
||||
ev_send_loop(tab->loop, &hc->update);
|
||||
&& !ev_active(tab->hcu_event))
|
||||
ev_send_loop(tab->loop, tab->hcu_event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4269,14 +4269,13 @@ rt_init_hostcache(struct rtable_private *tab)
|
||||
hc->lp = lp_new(tab->rp);
|
||||
hc->trie = f_new_trie(hc->lp, 0);
|
||||
|
||||
hc->update = (event) {
|
||||
.hook = rt_update_hostcache,
|
||||
.data = tab,
|
||||
};
|
||||
hc->tab = RT_PUB(tab);
|
||||
|
||||
tab->hcu_event = ev_new_init(tab->rp, rt_update_hostcache, tab);
|
||||
tab->hcu_uncork_event = ev_new_init(tab->rp, rt_update_hostcache, tab);
|
||||
tab->hostcache = hc;
|
||||
|
||||
ev_send_loop(tab->loop, &hc->update);
|
||||
ev_send_loop(tab->loop, tab->hcu_event);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -4290,7 +4289,7 @@ rt_free_hostcache(struct rtable_private *tab)
|
||||
struct hostentry *he = SKIP_BACK(struct hostentry, ln, n);
|
||||
rta_free(he->src);
|
||||
|
||||
if (he->uc)
|
||||
if (!lfuc_finished(&he->uc))
|
||||
log(L_ERR "Hostcache is not empty in table %s", tab->name);
|
||||
}
|
||||
|
||||
@ -4426,7 +4425,7 @@ rt_update_hostcache(void *data)
|
||||
if (!hc->req.hook)
|
||||
return;
|
||||
|
||||
if (rt_cork_check(&hc->update))
|
||||
if (rt_cork_check(tab->hcu_uncork_event))
|
||||
{
|
||||
rt_trace(tab, D_STATES, "Hostcache update corked");
|
||||
return;
|
||||
@ -4445,11 +4444,11 @@ rt_update_hostcache(void *data)
|
||||
WALK_LIST_DELSAFE(n, x, hc->hostentries)
|
||||
{
|
||||
he = SKIP_BACK(struct hostentry, ln, n);
|
||||
if (!he->uc)
|
||||
{
|
||||
hc_delete_hostentry(hc, tab->rp, he);
|
||||
continue;
|
||||
}
|
||||
if (lfuc_finished(&he->uc))
|
||||
{
|
||||
hc_delete_hostentry(hc, tab->rp, he);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rt_update_hostentry(tab, he))
|
||||
nhu_pending[he->tab->id] = he->tab;
|
||||
@ -4462,36 +4461,6 @@ rt_update_hostcache(void *data)
|
||||
rt_schedule_nhu(dst);
|
||||
}
|
||||
|
||||
struct hostentry_tmp_lock {
|
||||
resource r;
|
||||
rtable *tab;
|
||||
struct hostentry *he;
|
||||
};
|
||||
|
||||
static void
|
||||
hostentry_tmp_unlock(resource *r)
|
||||
{
|
||||
struct hostentry_tmp_lock *l = SKIP_BACK(struct hostentry_tmp_lock, r, r);
|
||||
RT_LOCKED(l->tab, tab)
|
||||
l->he->uc--;
|
||||
}
|
||||
|
||||
static void
|
||||
hostentry_tmp_lock_dump(resource *r, unsigned indent UNUSED)
|
||||
{
|
||||
struct hostentry_tmp_lock *l = SKIP_BACK(struct hostentry_tmp_lock, r, r);
|
||||
debug("he=%p tab=%s\n", l->he, l->tab->name);
|
||||
}
|
||||
|
||||
struct resclass hostentry_tmp_lock_class = {
|
||||
.name = "Temporary hostentry lock",
|
||||
.size = sizeof(struct hostentry_tmp_lock),
|
||||
.free = hostentry_tmp_unlock,
|
||||
.dump = hostentry_tmp_lock_dump,
|
||||
.lookup = NULL,
|
||||
.memsize = NULL,
|
||||
};
|
||||
|
||||
static struct hostentry *
|
||||
rt_get_hostentry(struct rtable_private *tab, ip_addr a, ip_addr ll, rtable *dep)
|
||||
{
|
||||
@ -4507,17 +4476,19 @@ rt_get_hostentry(struct rtable_private *tab, ip_addr a, ip_addr ll, rtable *dep)
|
||||
if (ipa_equal(he->addr, a) && ipa_equal(he->link, link) && (he->tab == dep))
|
||||
break;
|
||||
|
||||
if (!he)
|
||||
if (he)
|
||||
lfuc_lock(&he->uc);
|
||||
else
|
||||
{
|
||||
he = hc_new_hostentry(hc, tab->rp, a, link, dep, k);
|
||||
lfuc_lock_revive(&he->uc);
|
||||
|
||||
he->owner = RT_PUB(tab);
|
||||
rt_update_hostentry(tab, he);
|
||||
}
|
||||
|
||||
struct hostentry_tmp_lock *l = ralloc(tmp_res.pool, &hostentry_tmp_lock_class);
|
||||
l->he = he;
|
||||
l->tab = RT_PUB(tab);
|
||||
l->he->uc++;
|
||||
/* Free the hostentry if filtered out */
|
||||
lfuc_unlock(&he->uc, birdloop_event_list(tab->loop), tab->hcu_event);
|
||||
|
||||
return he;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user