diff options
| -rw-r--r-- | zebra/dplane_fpm_nl.c | 34 | 
1 files changed, 34 insertions, 0 deletions
diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index e6b4af3674..3ec1c9d657 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -68,6 +68,8 @@  static const char *prov_name = "dplane_fpm_nl"; +static atomic_bool fpm_cleaning_up; +  struct fpm_nl_ctx {  	/* data plane connection. */  	int socket; @@ -524,6 +526,16 @@ static void fpm_connect(struct event *t);  static void fpm_reconnect(struct fpm_nl_ctx *fnc)  { +	bool cleaning_p = false; + +	/* This is being called in the FPM pthread: ensure we don't deadlock +	 * with similar code that may be run in the main pthread. +	 */ +	if (!atomic_compare_exchange_strong_explicit( +		    &fpm_cleaning_up, &cleaning_p, true, memory_order_seq_cst, +		    memory_order_seq_cst)) +		return; +  	/* Cancel all zebra threads first. */  	event_cancel_async(zrouter.master, &fnc->t_lspreset, NULL);  	event_cancel_async(zrouter.master, &fnc->t_lspwalk, NULL); @@ -551,6 +563,12 @@ static void fpm_reconnect(struct fpm_nl_ctx *fnc)  	EVENT_OFF(fnc->t_read);  	EVENT_OFF(fnc->t_write); +	/* Reset the barrier value */ +	cleaning_p = true; +	atomic_compare_exchange_strong_explicit( +		&fpm_cleaning_up, &cleaning_p, false, memory_order_seq_cst, +		memory_order_seq_cst); +  	/* FPM is disabled, don't attempt to connect. */  	if (fnc->disabled)  		return; @@ -1624,6 +1642,16 @@ static int fpm_nl_start(struct zebra_dplane_provider *prov)  static int fpm_nl_finish_early(struct fpm_nl_ctx *fnc)  { +	bool cleaning_p = false; + +	/* This is being called in the main pthread: ensure we don't deadlock +	 * with similar code that may be run in the FPM pthread. +	 */ +	if (!atomic_compare_exchange_strong_explicit( +		    &fpm_cleaning_up, &cleaning_p, true, memory_order_seq_cst, +		    memory_order_seq_cst)) +		return 0; +  	/* Disable all events and close socket. */  	EVENT_OFF(fnc->t_lspreset);  	EVENT_OFF(fnc->t_lspwalk); @@ -1644,6 +1672,12 @@ static int fpm_nl_finish_early(struct fpm_nl_ctx *fnc)  		fnc->socket = -1;  	} +	/* Reset the barrier value */ +	cleaning_p = true; +	atomic_compare_exchange_strong_explicit( +		&fpm_cleaning_up, &cleaning_p, false, memory_order_seq_cst, +		memory_order_seq_cst); +  	return 0;  }  | 
