Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rcu bites the bitey thing #15298

Merged
merged 2 commits into from
Feb 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 29 additions & 1 deletion bgpd/bgp_rpki.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ struct rpki_vrf {
QOBJ_FIELDS;
};

static pthread_key_t rpki_pthread;

static struct rpki_vrf *find_rpki_vrf(const char *vrfname);
static int bgp_rpki_vrf_update(struct vrf *vrf, bool enabled);
static int bgp_rpki_write_vrf(struct vty *vty, struct vrf *vrf);
Expand Down Expand Up @@ -887,6 +889,8 @@ static int bgp_rpki_fini(void)

static int bgp_rpki_module_init(void)
{
pthread_key_create(&rpki_pthread, NULL);

lrtr_set_alloc_functions(malloc_wrapper, realloc_wrapper, free_wrapper);

hook_register(bgp_rpki_prefix_status, rpki_validate_prefix);
Expand Down Expand Up @@ -1297,11 +1301,35 @@ static int rpki_create_socket(void *_cache)

rpki_vrf = cache->rpki_vrf;

if (frr_pthread_non_controlled_startup(cache->rtr_socket->thread_id,
/*
* the rpki infrastructure can call this function
* multiple times per pthread. Why? I have absolutely
* no idea, and I am not sure I care a whole bunch.
* Why does this matter? Well when we attempt to
* hook this pthread into the rcu structure multiple
* times the rcu code asserts on shutdown. Clearly
* upset that you have rcu data associated with a pthread
* that has not been cleaned up. And frankly this is rightly so.
*
* At this point we know that this function is not
* called a million bajillion times so let's just
* add a bit of insurance by looking to see if
* some thread specific code has been set for this
* pthread. If not, hook into the rcu code and
* make things happy.
*
* IF YOU PUT A ZLOG_XXXX prior to the call into
* frr_pthread_non_controlled_startup in this function
* BGP WILL CRASH. You have been warned.
*/
if (!pthread_getspecific(rpki_pthread) &&
frr_pthread_non_controlled_startup(cache->rtr_socket->thread_id,
"RPKI RTRLIB socket",
"rpki_create_socket") < 0)
return -1;

pthread_setspecific(rpki_pthread, &rpki_pthread);

if (rpki_vrf->vrfname == NULL)
vrf = vrf_lookup_by_id(VRF_DEFAULT);
else
Expand Down
6 changes: 5 additions & 1 deletion lib/frr_pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ static void *frr_pthread_attr_non_controlled_start(void *arg)
int frr_pthread_non_controlled_startup(pthread_t thread, const char *name,
const char *os_name)
{
struct rcu_thread *rcu_thread = rcu_thread_new(NULL);

rcu_thread_start(rcu_thread);

struct frr_pthread_attr attr = {
.start = frr_pthread_attr_non_controlled_start,
.stop = frr_pthread_attr_default.stop,
Expand All @@ -245,7 +249,7 @@ int frr_pthread_non_controlled_startup(pthread_t thread, const char *name,
return -1;

fpt->thread = thread;
fpt->rcu_thread = rcu_thread_new(NULL);
fpt->rcu_thread = rcu_thread;
frr_pthread_inner(fpt);

return 0;
Expand Down
Loading