diff --git a/zebra/zserv.c b/zebra/zserv.c index d4fa6dadae..2024f34534 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -232,14 +232,16 @@ static void zserv_write(struct thread *thread) struct stream *msg; uint32_t wcmd = 0; struct stream_fifo *cache; + uint64_t time_now = monotime(NULL); /* If we have any data pending, try to flush it first */ switch (buffer_flush_all(client->wb, client->sock)) { case BUFFER_ERROR: goto zwrite_fail; case BUFFER_PENDING: - atomic_store_explicit(&client->last_write_time, monotime(NULL), - memory_order_relaxed); + frr_with_mutex (&client->stats_mtx) { + client->last_write_time = time_now; + } zserv_client_event(client, ZSERV_CLIENT_WRITE); return; case BUFFER_EMPTY: @@ -273,20 +275,19 @@ static void zserv_write(struct thread *thread) case BUFFER_ERROR: goto zwrite_fail; case BUFFER_PENDING: - atomic_store_explicit(&client->last_write_time, monotime(NULL), - memory_order_relaxed); + frr_with_mutex (&client->stats_mtx) { + client->last_write_time = time_now; + } zserv_client_event(client, ZSERV_CLIENT_WRITE); return; case BUFFER_EMPTY: break; } - atomic_store_explicit(&client->last_write_cmd, wcmd, - memory_order_relaxed); - - atomic_store_explicit(&client->last_write_time, monotime(NULL), - memory_order_relaxed); - + frr_with_mutex (&client->stats_mtx) { + client->last_write_cmd = wcmd; + client->last_write_time = time_now; + } return; zwrite_fail: @@ -433,11 +434,13 @@ static void zserv_read(struct thread *thread) } if (p2p < p2p_orig) { + uint64_t time_now = monotime(NULL); + /* update session statistics */ - atomic_store_explicit(&client->last_read_time, monotime(NULL), - memory_order_relaxed); - atomic_store_explicit(&client->last_read_cmd, hdr.command, - memory_order_relaxed); + frr_with_mutex (&client->stats_mtx) { + client->last_read_time = time_now; + client->last_read_cmd = hdr.command; + } /* publish read packets on client's input queue */ frr_with_mutex (&client->ibuf_mtx) { @@ -631,6 +634,7 @@ static void zserv_client_free(struct zserv *client) buffer_free(client->wb); /* Free buffer mutexes */ + pthread_mutex_destroy(&client->stats_mtx); pthread_mutex_destroy(&client->obuf_mtx); pthread_mutex_destroy(&client->ibuf_mtx); @@ -751,14 +755,13 @@ static struct zserv *zserv_client_create(int sock) client->obuf_fifo = stream_fifo_new(); client->ibuf_work = stream_new(stream_size); client->obuf_work = stream_new(stream_size); + client->connect_time = monotime(NULL); pthread_mutex_init(&client->ibuf_mtx, NULL); pthread_mutex_init(&client->obuf_mtx, NULL); + pthread_mutex_init(&client->stats_mtx, NULL); client->wb = buffer_new(0); TAILQ_INIT(&(client->gr_info_queue)); - atomic_store_explicit(&client->connect_time, monotime(NULL), - memory_order_relaxed); - /* Initialize flags */ for (afi = AFI_IP; afi < AFI_MAX; afi++) { for (i = 0; i < ZEBRA_ROUTE_MAX; i++) @@ -1019,8 +1022,14 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) vty_out(vty, "------------------------ \n"); vty_out(vty, "FD: %d \n", client->sock); - connect_time = (time_t) atomic_load_explicit(&client->connect_time, - memory_order_relaxed); + frr_with_mutex (&client->stats_mtx) { + connect_time = client->connect_time; + last_read_time = client->last_read_time; + last_write_time = client->last_write_time; + + last_read_cmd = client->last_read_cmd; + last_write_cmd = client->last_write_cmd; + } vty_out(vty, "Connect Time: %s \n", zserv_time_buf(&connect_time, cbuf, ZEBRA_TIME_BUF)); @@ -1041,16 +1050,6 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client) "Client will %sbe notified about the status of its routes.\n", client->notify_owner ? "" : "Not "); - last_read_time = (time_t)atomic_load_explicit(&client->last_read_time, - memory_order_relaxed); - last_write_time = (time_t)atomic_load_explicit(&client->last_write_time, - memory_order_relaxed); - - last_read_cmd = atomic_load_explicit(&client->last_read_cmd, - memory_order_relaxed); - last_write_cmd = atomic_load_explicit(&client->last_write_cmd, - memory_order_relaxed); - vty_out(vty, "Last Msg Rx Time: %s \n", zserv_time_buf(&last_read_time, rbuf, ZEBRA_TIME_BUF)); vty_out(vty, "Last Msg Tx Time: %s \n", @@ -1184,12 +1183,11 @@ static void zebra_show_client_brief(struct vty *vty, struct zserv *client) char wbuf[ZEBRA_TIME_BUF]; time_t connect_time, last_read_time, last_write_time; - connect_time = (time_t)atomic_load_explicit(&client->connect_time, - memory_order_relaxed); - last_read_time = (time_t)atomic_load_explicit(&client->last_read_time, - memory_order_relaxed); - last_write_time = (time_t)atomic_load_explicit(&client->last_write_time, - memory_order_relaxed); + frr_with_mutex (&client->stats_mtx) { + connect_time = client->connect_time; + last_read_time = client->last_read_time; + last_write_time = client->last_write_time; + } if (client->instance || client->session_id) snprintfrr(client_string, sizeof(client_string), "%s[%u:%u]", diff --git a/zebra/zserv.h b/zebra/zserv.h index de784e382a..cfc33f9169 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -215,16 +215,21 @@ struct zserv { * relative to last_read_time. */ + pthread_mutex_t stats_mtx; + /* BEGIN covered by stats_mtx */ + /* monotime of client creation */ - _Atomic uint64_t connect_time; + uint64_t connect_time; /* monotime of last message received */ - _Atomic uint64_t last_read_time; + uint64_t last_read_time; /* monotime of last message sent */ - _Atomic uint64_t last_write_time; + uint64_t last_write_time; /* command code of last message read */ - _Atomic uint64_t last_read_cmd; + uint64_t last_read_cmd; /* command code of last message written */ - _Atomic uint64_t last_write_cmd; + uint64_t last_write_cmd; + + /* END covered by stats_mtx */ /* * Number of instances configured with