mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-11-18 17:18:42 +00:00
Merge commit '038fcf1c' into thread-next
It was necessary to update the code to match removal of rta, as well as existence of cached nested attribute lists.
This commit is contained in:
commit
70e01358a0
@ -257,7 +257,7 @@ typedef struct ea_list {
|
|||||||
struct ea_storage {
|
struct ea_storage {
|
||||||
struct ea_storage *next_hash; /* Next in hash chain */
|
struct ea_storage *next_hash; /* Next in hash chain */
|
||||||
struct ea_storage **pprev_hash; /* Previous in hash chain */
|
struct ea_storage **pprev_hash; /* Previous in hash chain */
|
||||||
u32 uc; /* Use count */
|
_Atomic u32 uc; /* Use count */
|
||||||
u32 hash_key; /* List hash */
|
u32 hash_key; /* List hash */
|
||||||
ea_list l[0]; /* The list itself */
|
ea_list l[0]; /* The list itself */
|
||||||
};
|
};
|
||||||
@ -526,12 +526,15 @@ static inline struct ea_storage *ea_get_storage(ea_list *r)
|
|||||||
return SKIP_BACK(struct ea_storage, l[0], r);
|
return SKIP_BACK(struct ea_storage, l[0], r);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ea_list *ea_clone(ea_list *r) { ea_get_storage(r)->uc++; return r; }
|
static inline ea_list *ea_clone(ea_list *r) {
|
||||||
|
ASSERT_DIE(0 < atomic_fetch_add_explicit(&ea_get_storage(r)->uc, 1, memory_order_acq_rel));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
void ea__free(struct ea_storage *r);
|
void ea__free(struct ea_storage *r);
|
||||||
static inline void ea_free(ea_list *l) {
|
static inline void ea_free(ea_list *l) {
|
||||||
if (!l) return;
|
if (!l) return;
|
||||||
struct ea_storage *r = ea_get_storage(l);
|
struct ea_storage *r = ea_get_storage(l);
|
||||||
if (!--r->uc) ea__free(r);
|
if (1 == atomic_fetch_sub_explicit(&r->uc, 1, memory_order_acq_rel)) ea__free(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ea_dump(ea_list *);
|
void ea_dump(ea_list *);
|
||||||
|
@ -1043,6 +1043,8 @@ ea_list_ref(ea_list *l)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ea_free_nested(ea_list *l);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ea_list_unref(ea_list *l)
|
ea_list_unref(ea_list *l)
|
||||||
{
|
{
|
||||||
@ -1063,7 +1065,7 @@ ea_list_unref(ea_list *l)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (l->next)
|
if (l->next)
|
||||||
ea_free(l->next);
|
ea_free_nested(l->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1472,9 +1474,15 @@ ea_lookup(ea_list *o, int overlay)
|
|||||||
o = ea_normalize(o, overlay);
|
o = ea_normalize(o, overlay);
|
||||||
h = ea_hash(o);
|
h = ea_hash(o);
|
||||||
|
|
||||||
|
RTA_LOCK;
|
||||||
|
|
||||||
for(r=rta_hash_table[h & rta_cache_mask]; r; r=r->next_hash)
|
for(r=rta_hash_table[h & rta_cache_mask]; r; r=r->next_hash)
|
||||||
if (r->hash_key == h && ea_same(r->l, o))
|
if (r->hash_key == h && ea_same(r->l, o))
|
||||||
return ea_clone(r->l);
|
{
|
||||||
|
atomic_fetch_add_explicit(&r->uc, 1, memory_order_acq_rel);
|
||||||
|
RTA_UNLOCK;
|
||||||
|
return r->l;
|
||||||
|
}
|
||||||
|
|
||||||
uint elen = ea_list_size(o);
|
uint elen = ea_list_size(o);
|
||||||
r = mb_alloc(rta_pool, elen + sizeof(struct ea_storage));
|
r = mb_alloc(rta_pool, elen + sizeof(struct ea_storage));
|
||||||
@ -1490,12 +1498,17 @@ ea_lookup(ea_list *o, int overlay)
|
|||||||
if (++rta_cache_count > rta_cache_limit)
|
if (++rta_cache_count > rta_cache_limit)
|
||||||
rta_rehash();
|
rta_rehash();
|
||||||
|
|
||||||
|
RTA_UNLOCK;
|
||||||
return r->l;
|
return r->l;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
ea__free(struct ea_storage *a)
|
ea_free_locked(struct ea_storage *a)
|
||||||
{
|
{
|
||||||
|
/* Somebody has cloned this rta inbetween. This sometimes happens. */
|
||||||
|
if (atomic_load_explicit(&a->uc, memory_order_acquire))
|
||||||
|
return;
|
||||||
|
|
||||||
ASSERT(rta_cache_count);
|
ASSERT(rta_cache_count);
|
||||||
rta_cache_count--;
|
rta_cache_count--;
|
||||||
*a->pprev_hash = a->next_hash;
|
*a->pprev_hash = a->next_hash;
|
||||||
@ -1506,6 +1519,22 @@ ea__free(struct ea_storage *a)
|
|||||||
mb_free(a);
|
mb_free(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ea_free_nested(struct ea_list *l)
|
||||||
|
{
|
||||||
|
struct ea_storage *r = ea_get_storage(l);
|
||||||
|
if (1 == atomic_fetch_sub_explicit(&r->uc, 1, memory_order_acq_rel))
|
||||||
|
ea_free_locked(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ea__free(struct ea_storage *a)
|
||||||
|
{
|
||||||
|
RTA_LOCK;
|
||||||
|
ea_free_locked(a);
|
||||||
|
RTA_UNLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rta_dump_all - dump attribute cache
|
* rta_dump_all - dump attribute cache
|
||||||
*
|
*
|
||||||
@ -1515,6 +1544,8 @@ ea__free(struct ea_storage *a)
|
|||||||
void
|
void
|
||||||
ea_dump_all(void)
|
ea_dump_all(void)
|
||||||
{
|
{
|
||||||
|
RTA_LOCK;
|
||||||
|
|
||||||
debug("Route attribute cache (%d entries, rehash at %d):\n", rta_cache_count, rta_cache_limit);
|
debug("Route attribute cache (%d entries, rehash at %d):\n", rta_cache_count, rta_cache_limit);
|
||||||
for (uint h=0; h < rta_cache_size; h++)
|
for (uint h=0; h < rta_cache_size; h++)
|
||||||
for (struct ea_storage *a = rta_hash_table[h]; a; a = a->next_hash)
|
for (struct ea_storage *a = rta_hash_table[h]; a; a = a->next_hash)
|
||||||
@ -1524,6 +1555,8 @@ ea_dump_all(void)
|
|||||||
debug("\n");
|
debug("\n");
|
||||||
}
|
}
|
||||||
debug("\n");
|
debug("\n");
|
||||||
|
|
||||||
|
RTA_UNLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user