[qca-nss-drv] Add N2H statistics notifier
Change-Id: I3525f26a8b218aa3c7678c9179dec84b99824958
Signed-off-by: Wayne Tan <wtan@codeaurora.org>
diff --git a/Makefile b/Makefile
index 957d3ab..d1bc7f4 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,7 @@
nss_core.o \
nss_coredump.o \
nss_drv_stats.o \
+ nss_drv_strings.o \
nss_dynamic_interface.o \
nss_dynamic_interface_log.o \
nss_dynamic_interface_stats.o \
@@ -88,6 +89,7 @@
nss_mirror_stats.o \
nss_n2h.o \
nss_n2h_stats.o \
+ nss_n2h_strings.o \
nss_oam.o \
nss_oam_log.o \
nss_phys_if.o \
diff --git a/exports/nss_n2h.h b/exports/nss_n2h.h
index 8c20548..1613f41 100644
--- a/exports/nss_n2h.h
+++ b/exports/nss_n2h.h
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -50,6 +50,8 @@
uint32_t high_water;
};
+#ifdef __KERNEL__ /* only kernel will use. */
+
/**
* nss_n2h_cfg_pvt
* N2H private data configuration.
@@ -63,6 +65,50 @@
int response; /**< Response from the firmware. */
};
+#endif /*__KERNEL__ */
+
+/**
+ * nss_n2h_stats_types
+ * N2H node statistics.
+ */
+enum nss_n2h_stats_types {
+ NSS_N2H_STATS_QUEUE_DROPPED = NSS_STATS_NODE_MAX,
+ /**< Number of packets dropped because the exception queue is too full. */
+ NSS_N2H_STATS_TOTAL_TICKS, /**< Total clock ticks spend inside the N2H. */
+ NSS_N2H_STATS_WORST_CASE_TICKS, /**< Worst case iteration of the exception path in ticks. */
+ NSS_N2H_STATS_ITERATIONS, /**< Number of iterations around the N2H. */
+ NSS_N2H_STATS_PBUF_OCM_TOTAL_COUNT, /**< Number of pbuf OCM total count. */
+ NSS_N2H_STATS_PBUF_OCM_FREE_COUNT, /**< Number of pbuf OCM free count. */
+ NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS_WITH_PAYLOAD,
+ /**< Number of pbuf OCM allocations that have failed with payload. */
+ NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS_NO_PAYLOAD,
+ /**< Number of pbuf OCM allocations that have failed without payload. */
+ NSS_N2H_STATS_PBUF_DEFAULT_TOTAL_COUNT, /**< Number of pbuf default total count. */
+ NSS_N2H_STATS_PBUF_DEFAULT_FREE_COUNT, /**< Number of pbuf default free count. */
+ NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS_WITH_PAYLOAD,
+ /**< Number of pbuf default allocations that have failed with payload. */
+ NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS_NO_PAYLOAD,
+ /**< Number of pbuf default allocations that have failed without payload. */
+
+ NSS_N2H_STATS_PAYLOAD_ALLOC_FAILS, /**< Number of pbuf allocations that have failed because there were no free payloads. */
+ NSS_N2H_STATS_PAYLOAD_FREE_COUNT, /**< Number of free payloads that exist. */
+
+ NSS_N2H_STATS_H2N_CONTROL_PACKETS, /**< Control packets received from HLOS. */
+ NSS_N2H_STATS_H2N_CONTROL_BYTES, /**< Control bytes received from HLOS. */
+ NSS_N2H_STATS_N2H_CONTROL_PACKETS, /**< Control packets sent to HLOS. */
+ NSS_N2H_STATS_N2H_CONTROL_BYTES, /**< Control bytes sent to HLOS. */
+
+ NSS_N2H_STATS_H2N_DATA_PACKETS, /**< Data packets received from HLOS. */
+ NSS_N2H_STATS_H2N_DATA_BYTES, /**< Data bytes received from HLOS. */
+ NSS_N2H_STATS_N2H_DATA_PACKETS, /**< Data packets sent to HLOS. */
+ NSS_N2H_STATS_N2H_DATA_BYTES, /**< Data bytes sent to HLOS. */
+ NSS_N2H_STATS_N2H_TOT_PAYLOADS, /**< Number of payloads in NSS. */
+ NSS_N2H_STATS_N2H_INTERFACE_INVALID, /**< Number of bad interface access. */
+ NSS_N2H_STATS_ENQUEUE_RETRIES, /**< Number of enqueue retries by N2H. */
+
+ NSS_N2H_STATS_MAX, /**< Maximum message type. */
+};
+
/**
* nss_n2h_metadata_types
* Message types for N2H requests and responses.
@@ -110,6 +156,16 @@
};
/**
+ * nss_n2h_stats_notification
+ * N2H statistics structure.
+ */
+struct nss_n2h_stats_notification {
+ uint32_t core_id; /**< Core ID. */
+ uint64_t n2h_stats[NSS_N2H_STATS_MAX]; /**< N2H statistics. */
+ uint64_t drv_stats[NSS_STATS_DRV_MAX]; /**< Driver statistics. */
+};
+
+/**
* nss_n2h_rps
* N2H RPS configuration.
*/
@@ -477,6 +533,38 @@
*/
extern nss_tx_status_t nss_n2h_update_queue_config_async(struct nss_ctx_instance *nss_ctx, bool mq_en, uint16_t *qlimits);
+#ifdef __KERNEL__ /* only kernel will use. */
+
+/**
+ * nss_n2h_stats_register_notifier
+ * Registers a statistics notifier.
+ *
+ * @datatypes
+ * notifier_block
+ *
+ * @param[in] nb Notifier block.
+ *
+ * @return
+ * 0 on success or -2 on failure.
+ */
+extern int nss_n2h_stats_register_notifier(struct notifier_block *nb);
+
+/**
+ * nss_n2h_stats_unregister_notifier
+ * Deregisters a statistics notifier.
+ *
+ * @datatypes
+ * notifier_block
+ *
+ * @param[in] nb Notifier block.
+ *
+ * @return
+ * 0 on success or -2 on failure.
+ */
+extern int nss_n2h_stats_unregister_notifier(struct notifier_block *nb);
+
+#endif /*__KERNEL__ */
+
/**
* @}
*/
diff --git a/exports/nss_stats_public.h b/exports/nss_stats_public.h
index 4f1baa4..f282ffd 100644
--- a/exports/nss_stats_public.h
+++ b/exports/nss_stats_public.h
@@ -53,6 +53,55 @@
NSS_STATS_NODE_MAX, /**< Maximum message type. */
};
+/*
+ * WARNING: There is a 1:1 mapping between values of enum nss_stats_drv and corresponding
+ * statistics string array in nss_drv_strings.c.
+ */
+/**
+ * nss_stats_drv
+ * HLOS driver statistics.
+ */
+enum nss_stats_drv {
+ NSS_STATS_DRV_NBUF_ALLOC_FAILS = 0, /**< Networking buffer allocation errors. */
+ NSS_STATS_DRV_PAGED_BUF_ALLOC_FAILS, /**< Paged buffer allocation errors. */
+ NSS_STATS_DRV_TX_QUEUE_FULL_0, /**< Tx queue full for Core 0. */
+ NSS_STATS_DRV_TX_QUEUE_FULL_1, /**< Tx queue full for Core 1. */
+ NSS_STATS_DRV_TX_EMPTY, /**< Host-to-network empty buffers. */
+ NSS_STATS_DRV_PAGED_TX_EMPTY, /**< Host-to-network paged empty buffers. */
+ NSS_STATS_DRV_TX_PACKET, /**< Host-to-network data packets. */
+ NSS_STATS_DRV_TX_CMD_REQ, /**< Host-to-network control packets. */
+ NSS_STATS_DRV_TX_CRYPTO_REQ, /**< Host-to-network crypto requests. */
+ NSS_STATS_DRV_TX_BUFFER_REUSE, /**< Host-to-network reuse buffer count. */
+ NSS_STATS_DRV_RX_EMPTY, /**< Network-to-host empty buffers. */
+ NSS_STATS_DRV_RX_PACKET, /**< Network-to-host data packets. */
+ NSS_STATS_DRV_RX_CMD_RESP, /**< Network-to-host command responses. */
+ NSS_STATS_DRV_RX_STATUS, /**< Network-to-host status packets. */
+ NSS_STATS_DRV_RX_CRYPTO_RESP, /**< Network-to-host crypto responses. */
+ NSS_STATS_DRV_RX_VIRTUAL, /**< Network-to-host virtual packets. */
+ NSS_STATS_DRV_TX_SIMPLE, /**< Host-to-network simple SKB packets. */
+ NSS_STATS_DRV_TX_NR_FRAGS, /**< Host-to-network number of fragmented SKB packets. */
+ NSS_STATS_DRV_TX_FRAGLIST, /**< Host-to-network fragmentation list of SKB packets. */
+ NSS_STATS_DRV_RX_SIMPLE, /**< Network-to-host simple SKB packets. */
+ NSS_STATS_DRV_RX_NR_FRAGS, /**< Network-to-host number of fragmented SKB packets. */
+ NSS_STATS_DRV_RX_SKB_FRAGLIST, /**< Network-to-host fragmentation list of SKB packets. */
+ NSS_STATS_DRV_RX_BAD_DESCRIPTOR, /**< Network-to-host bad descriptor reads. */
+ NSS_STATS_DRV_NSS_SKB_COUNT, /**< NSS SKB pool count. */
+ NSS_STATS_DRV_CHAIN_SEG_PROCESSED, /**< Network-to-host SKB chain processed count. */
+ NSS_STATS_DRV_FRAG_SEG_PROCESSED, /**< Network-to-host fragments processed count. */
+ NSS_STATS_DRV_TX_CMD_QUEUE_FULL, /**< Tx host-to-network control packets fail due to queue full. */
+#ifdef NSS_MULTI_H2N_DATA_RING_SUPPORT
+ NSS_STATS_DRV_TX_PACKET_QUEUE_0, /**< Host-to-network data packets on queue0. */
+ NSS_STATS_DRV_TX_PACKET_QUEUE_1, /**< Host-to-network data packets on queue1. */
+ NSS_STATS_DRV_TX_PACKET_QUEUE_2, /**< Host-to-network data packets on queue2. */
+ NSS_STATS_DRV_TX_PACKET_QUEUE_3, /**< Host-to-network data packets on queue3. */
+ NSS_STATS_DRV_TX_PACKET_QUEUE_4, /**< Host-to-network data packets on queue4. */
+ NSS_STATS_DRV_TX_PACKET_QUEUE_5, /**< Host-to-network data packets on queue5. */
+ NSS_STATS_DRV_TX_PACKET_QUEUE_6, /**< Host-to-network data packets on queue6. */
+ NSS_STATS_DRV_TX_PACKET_QUEUE_7, /**< Host-to-network data packets on queue7. */
+#endif
+ NSS_STATS_DRV_MAX, /**< Maximum message type. */
+};
+
/**
* nss_stats_types
* List of statistics categories.
diff --git a/nss_drv_stats.c b/nss_drv_stats.c
index ae27608..30b8cb5 100644
--- a/nss_drv_stats.c
+++ b/nss_drv_stats.c
@@ -15,60 +15,14 @@
*/
#include "nss_core.h"
-
-/*
- * nss_drv_stats_str
- * Host driver stats strings.
- */
-struct nss_stats_info nss_drv_stats_str[NSS_DRV_STATS_MAX] = {
- {"nbuf_alloc_errors" , NSS_STATS_TYPE_ERROR},
- {"paged_buf_alloc_errors" , NSS_STATS_TYPE_ERROR},
- {"tx_queue_full[0]" , NSS_STATS_TYPE_ERROR},
- {"tx_queue_full[1]" , NSS_STATS_TYPE_ERROR},
- {"tx_buffers_empty" , NSS_STATS_TYPE_SPECIAL},
- {"tx_paged_buffers_empty" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffer_pkt" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_cmd" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_crypto" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_reuse" , NSS_STATS_TYPE_SPECIAL},
- {"rx_buffers_empty" , NSS_STATS_TYPE_SPECIAL},
- {"rx_buffers_pkt" , NSS_STATS_TYPE_SPECIAL},
- {"rx_buffers_ext_pkt" , NSS_STATS_TYPE_SPECIAL},
- {"rx_buffers_cmd_resp" , NSS_STATS_TYPE_SPECIAL},
- {"rx_buffers_status_sync" , NSS_STATS_TYPE_SPECIAL},
- {"rx_buffers_crypto" , NSS_STATS_TYPE_SPECIAL},
- {"rx_buffers_virtual" , NSS_STATS_TYPE_SPECIAL},
- {"tx_skb_simple" , NSS_STATS_TYPE_SPECIAL},
- {"tx_skb_nr_frags" , NSS_STATS_TYPE_SPECIAL},
- {"tx_skb_fraglist" , NSS_STATS_TYPE_SPECIAL},
- {"rx_skb_simple" , NSS_STATS_TYPE_SPECIAL},
- {"rx_skb_nr_frags" , NSS_STATS_TYPE_SPECIAL},
- {"rx_skb_fraglist" , NSS_STATS_TYPE_SPECIAL},
- {"rx_bad_desciptor" , NSS_STATS_TYPE_ERROR},
- {"invalid_interface" , NSS_STATS_TYPE_ERROR},
- {"invalid_core_id" , NSS_STATS_TYPE_ERROR},
- {"invalid_buffer_type" , NSS_STATS_TYPE_ERROR},
- {"nss_skb_count" , NSS_STATS_TYPE_SPECIAL},
- {"rx_chain_seg_processed" , NSS_STATS_TYPE_SPECIAL},
- {"rx_frag_seg_processed" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_cmd_queue_full" , NSS_STATS_TYPE_ERROR},
-#ifdef NSS_MULTI_H2N_DATA_RING_SUPPORT
- {"tx_buffers_data_queue[0]" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_data_queue[1]" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_data_queue[2]" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_data_queue[3]" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_data_queue[4]" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_data_queue[5]" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_data_queue[6]" , NSS_STATS_TYPE_SPECIAL},
- {"tx_buffers_data_queue[7]" , NSS_STATS_TYPE_SPECIAL},
-#endif
-};
+#include "nss_drv_strings.h"
+#include "nss_drv_stats.h"
/*
* nss_drv_stats_read()
* Read HLOS driver stats.
*/
-ssize_t nss_drv_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+static ssize_t nss_drv_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
int32_t i;
@@ -100,7 +54,7 @@
stats_shadow[i] = NSS_PKT_STATS_READ(&nss_top_main.stats_drv[i]);
}
- size_wr += nss_stats_print("drv", NULL, NSS_STATS_SINGLE_INSTANCE, nss_drv_stats_str, stats_shadow, NSS_DRV_STATS_MAX, lbuf, size_wr, size_al);
+ size_wr += nss_stats_print("drv", NULL, NSS_STATS_SINGLE_INSTANCE, nss_drv_strings_stats, stats_shadow, NSS_DRV_STATS_MAX, lbuf, size_wr, size_al);
bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
kfree(lbuf);
@@ -110,6 +64,20 @@
}
/*
+ * drv_stats_ops
+ */
+NSS_STATS_DECLARE_FILE_OPERATIONS(drv);
+
+/*
+ * nss_drv_stats_dentry_create()
+ * Create DRV statistics debug entry.
+ */
+void nss_drv_stats_dentry_create(void)
+{
+ nss_stats_create_dentry("drv", &nss_drv_stats_ops);
+}
+
+/*
* TODO: Move this (nss_wt_stats_read) function to new file (nss_wt_stats.c)
*/
diff --git a/nss_drv_stats.h b/nss_drv_stats.h
index f96c14a..543dd5c 100644
--- a/nss_drv_stats.h
+++ b/nss_drv_stats.h
@@ -75,6 +75,6 @@
NSS_DRV_STATS_MAX,
};
-extern ssize_t nss_drv_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos);
+extern void nss_drv_stats_dentry_create(void);
extern ssize_t nss_wt_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos);
#endif /* __NSS_DRV_STATS_H */
diff --git a/nss_drv_strings.c b/nss_drv_strings.c
new file mode 100644
index 0000000..2595615
--- /dev/null
+++ b/nss_drv_strings.c
@@ -0,0 +1,92 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include "nss_strings.h"
+
+/*
+ * nss_drv_strings_stats
+ * Host driver stats names.
+ */
+struct nss_stats_info nss_drv_strings_stats[NSS_DRV_STATS_MAX] = {
+ {"nbuf_alloc_errors" , NSS_STATS_TYPE_ERROR},
+ {"paged_buf_alloc_errors" , NSS_STATS_TYPE_ERROR},
+ {"tx_queue_full[0]" , NSS_STATS_TYPE_ERROR},
+ {"tx_queue_full[1]" , NSS_STATS_TYPE_ERROR},
+ {"tx_buffers_empty" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_paged_buffers_empty" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffer_pkt" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_cmd" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_crypto" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_reuse" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_buffers_empty" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_buffers_pkt" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_buffers_ext_pkt" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_buffers_cmd_resp" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_buffers_status_sync" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_buffers_crypto" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_buffers_virtual" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_skb_simple" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_skb_nr_frags" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_skb_fraglist" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_skb_simple" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_skb_nr_frags" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_skb_fraglist" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_bad_desciptor" , NSS_STATS_TYPE_ERROR},
+ {"invalid_interface" , NSS_STATS_TYPE_ERROR},
+ {"invalid_core_id" , NSS_STATS_TYPE_ERROR},
+ {"invalid_buffer_type" , NSS_STATS_TYPE_ERROR},
+ {"nss_skb_count" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_chain_seg_processed" , NSS_STATS_TYPE_SPECIAL},
+ {"rx_frag_seg_processed" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_cmd_queue_full" , NSS_STATS_TYPE_ERROR},
+#ifdef NSS_MULTI_H2N_DATA_RING_SUPPORT
+ {"tx_buffers_data_queue[0]" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_data_queue[1]" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_data_queue[2]" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_data_queue[3]" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_data_queue[4]" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_data_queue[5]" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_data_queue[6]" , NSS_STATS_TYPE_SPECIAL},
+ {"tx_buffers_data_queue[7]" , NSS_STATS_TYPE_SPECIAL},
+#endif
+};
+
+/*
+ * nss_drv_strings_read()
+ * Read drv node statistics names.
+ */
+static ssize_t nss_drv_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ return nss_strings_print(ubuf, sz, ppos, nss_drv_strings_stats, NSS_DRV_STATS_MAX);
+}
+
+/*
+ * nss_drv_strings_ops
+ */
+NSS_STRINGS_DECLARE_FILE_OPERATIONS(drv);
+
+/*
+ * nss_drv_strings_dentry_create()
+ * Create drv statistics strings debug entry.
+ */
+void nss_drv_strings_dentry_create(void)
+{
+ nss_strings_create_dentry("drv", &nss_drv_strings_ops);
+}
diff --git a/nss_drv_strings.h b/nss_drv_strings.h
new file mode 100644
index 0000000..72a1fd7
--- /dev/null
+++ b/nss_drv_strings.h
@@ -0,0 +1,26 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_DRV_STRINGS_H
+#define __NSS_DRV_STRINGS_H
+
+extern struct nss_stats_info nss_drv_strings_stats[NSS_DRV_STATS_MAX];
+
+extern void nss_drv_strings_dentry_create(void);
+
+#endif /* __NSS_DRV_STRINGS_H */
diff --git a/nss_n2h.c b/nss_n2h.c
index dd414f3..846bd64 100644
--- a/nss_n2h.c
+++ b/nss_n2h.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -21,6 +21,8 @@
#include "nss_tx_rx_common.h"
#include "nss_n2h_stats.h"
+#include "nss_n2h_strings.h"
+#include "nss_drv_strings.h"
#define NSS_N2H_MAX_BUF_POOL_SIZE (1024 * 1024 * 20) /* 20MB */
#define NSS_N2H_MIN_EMPTY_POOL_BUF_SZ 32
@@ -94,7 +96,11 @@
break;
case NSS_RX_METADATA_TYPE_N2H_STATS_SYNC:
+ /*
+ * Update driver statistics and send statistics notifications to the registered modules.
+ */
nss_n2h_stats_sync(nss_ctx, &nnm->msg.stats_sync);
+ nss_n2h_stats_notify(nss_ctx);
break;
default:
@@ -2057,6 +2063,9 @@
if (nss_ctx->id == NSS_CORE_0) {
nss_n2h_stats_dentry_create();
}
+ nss_n2h_strings_dentry_create();
+
+ nss_drv_strings_dentry_create();
}
/*
diff --git a/nss_n2h_stats.c b/nss_n2h_stats.c
index 4cdc9ad..60ff88b 100644
--- a/nss_n2h_stats.c
+++ b/nss_n2h_stats.c
@@ -1,6 +1,6 @@
/*
**************************************************************************
- * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -16,46 +16,13 @@
#include "nss_core.h"
#include "nss_n2h_stats.h"
+#include "nss_n2h.h"
+#include "nss_n2h_strings.h"
/*
- * nss_n2h_stats_str
- * N2H stats strings
+ * Declare atomic notifier data structure for statistics.
*/
-struct nss_stats_info nss_n2h_stats_str[NSS_N2H_STATS_MAX] = {
- {"rx_pkts" , NSS_STATS_TYPE_COMMON},
- {"rx_byts" , NSS_STATS_TYPE_COMMON},
- {"tx_pkts" , NSS_STATS_TYPE_COMMON},
- {"tx_byts" , NSS_STATS_TYPE_COMMON},
- {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP},
- {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP},
- {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP},
- {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP},
- {"queue_drops" , NSS_STATS_TYPE_DROP},
- {"ticks" , NSS_STATS_TYPE_SPECIAL},
- {"worst_ticks" , NSS_STATS_TYPE_SPECIAL},
- {"iterations" , NSS_STATS_TYPE_SPECIAL},
- {"pbuf_ocm_total_count" , NSS_STATS_TYPE_SPECIAL},
- {"pbuf_ocm_free_count" , NSS_STATS_TYPE_SPECIAL},
- {"pbuf_ocm_alloc_fails_with_payload" , NSS_STATS_TYPE_SPECIAL},
- {"pbuf_ocm_alloc_fails_no_payload" , NSS_STATS_TYPE_SPECIAL},
- {"pbuf_default_free_count" , NSS_STATS_TYPE_SPECIAL},
- {"pbuf_default_total_count" , NSS_STATS_TYPE_SPECIAL},
- {"pbuf_default_alloc_fails_with_payload", NSS_STATS_TYPE_SPECIAL},
- {"pbuf_default_alloc_fails_no_payload" , NSS_STATS_TYPE_SPECIAL},
- {"payload_fails" , NSS_STATS_TYPE_SPECIAL},
- {"payload_free_count" , NSS_STATS_TYPE_SPECIAL},
- {"h2n_control_pkts" , NSS_STATS_TYPE_SPECIAL},
- {"h2n_control_byts" , NSS_STATS_TYPE_SPECIAL},
- {"n2h_control_pkts" , NSS_STATS_TYPE_SPECIAL},
- {"n2h_control_byts" , NSS_STATS_TYPE_SPECIAL},
- {"h2n_data_pkts" , NSS_STATS_TYPE_SPECIAL},
- {"h2n_data_byts" , NSS_STATS_TYPE_SPECIAL},
- {"n2h_data_pkts" , NSS_STATS_TYPE_SPECIAL},
- {"n2h_data_byts" , NSS_STATS_TYPE_SPECIAL},
- {"n2h_tot_payloads" , NSS_STATS_TYPE_SPECIAL},
- {"n2h_data_interface_invalid" , NSS_STATS_TYPE_SPECIAL},
- {"enqueue_retries" , NSS_STATS_TYPE_SPECIAL}
-};
+ATOMIC_NOTIFIER_HEAD(nss_n2h_stats_notifier);
uint64_t nss_n2h_stats[NSS_MAX_CORES][NSS_N2H_STATS_MAX];
@@ -101,7 +68,7 @@
spin_unlock_bh(&nss_top_main.stats_lock);
size_wr += nss_stats_banner(lbuf, size_wr, size_al, "n2h", core);
size_wr += nss_stats_print("n2h", NULL, NSS_STATS_SINGLE_INSTANCE
- , nss_n2h_stats_str
+ , nss_n2h_strings_stats
, stats_shadow
, NSS_N2H_STATS_MAX
, lbuf, size_wr, size_al);
@@ -117,7 +84,7 @@
/*
* nss_n2h_stats_ops
*/
-NSS_STATS_DECLARE_FILE_OPERATIONS(n2h)
+NSS_STATS_DECLARE_FILE_OPERATIONS(n2h);
/*
* nss_n2h_stats_dentry_create()
@@ -205,3 +172,43 @@
spin_unlock_bh(&nss_top->stats_lock);
}
+
+/*
+ * nss_n2h_stats_notify()
+ * Sends notifications to all the registered modules.
+ *
+ * Leverage NSS-FW statistics timing to update Netlink.
+ */
+void nss_n2h_stats_notify(struct nss_ctx_instance *nss_ctx)
+{
+ int i;
+ struct nss_n2h_stats_notification stats;
+
+ for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
+ stats.drv_stats[i] = NSS_PKT_STATS_READ(&nss_top_main.stats_drv[i]);
+ }
+
+ stats.core_id = nss_ctx->id;
+ memcpy(stats.n2h_stats, nss_n2h_stats[stats.core_id], sizeof(stats.n2h_stats));
+ atomic_notifier_call_chain(&nss_n2h_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&stats);
+}
+
+/*
+ * nss_n2h_stats_register_notifier()
+ * Registers statistics notifier.
+ */
+int nss_n2h_stats_register_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_register(&nss_n2h_stats_notifier, nb);
+}
+EXPORT_SYMBOL(nss_n2h_stats_register_notifier);
+
+/*
+ * nss_n2h_stats_unregister_notifier()
+ * Deregisters statistics notifier.
+ */
+int nss_n2h_stats_unregister_notifier(struct notifier_block *nb)
+{
+ return atomic_notifier_chain_unregister(&nss_n2h_stats_notifier, nb);
+}
+EXPORT_SYMBOL(nss_n2h_stats_unregister_notifier);
diff --git a/nss_n2h_stats.h b/nss_n2h_stats.h
index 3b24c98..96d065e 100644
--- a/nss_n2h_stats.h
+++ b/nss_n2h_stats.h
@@ -1,6 +1,6 @@
/*
******************************************************************************
- * Copyright (c) 2017, 2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017,2019-2020 The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
@@ -18,49 +18,9 @@
#define __NSS_N2H_STATS_H
/*
- * N2H node statistics
- */
-enum nss_n2h_stats_types {
- NSS_N2H_STATS_QUEUE_DROPPED = NSS_STATS_NODE_MAX,
- /* Number of packets dropped because the exception queue is too full */
- NSS_N2H_STATS_TOTAL_TICKS, /* Total clock ticks spend inside the N2H */
- NSS_N2H_STATS_WORST_CASE_TICKS, /* Worst case iteration of the exception path in ticks */
- NSS_N2H_STATS_ITERATIONS, /* Number of iterations around the N2H */
- NSS_N2H_STATS_PBUF_OCM_TOTAL_COUNT, /* Number of pbuf ocm total count */
- NSS_N2H_STATS_PBUF_OCM_FREE_COUNT, /* Number of pbuf ocm free count */
- NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS_WITH_PAYLOAD,
- /* Number of pbuf ocm allocations that have failed with payload */
- NSS_N2H_STATS_PBUF_OCM_ALLOC_FAILS_NO_PAYLOAD,
- /* Number of pbuf ocm allocations that have failed without payload */
- NSS_N2H_STATS_PBUF_DEFAULT_TOTAL_COUNT, /* Number of pbuf default total count */
- NSS_N2H_STATS_PBUF_DEFAULT_FREE_COUNT, /* Number of pbuf default free count */
- NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS_WITH_PAYLOAD,
- /* Number of pbuf default allocations that have failed with payload */
- NSS_N2H_STATS_PBUF_DEFAULT_ALLOC_FAILS_NO_PAYLOAD,
- /* Number of pbuf default allocations that have failed without payload */
-
- NSS_N2H_STATS_PAYLOAD_ALLOC_FAILS, /* Number of pbuf allocations that have failed because there were no free payloads */
- NSS_N2H_STATS_PAYLOAD_FREE_COUNT, /* Number of free payloads that exist */
-
- NSS_N2H_STATS_H2N_CONTROL_PACKETS, /* Control packets received from HLOS */
- NSS_N2H_STATS_H2N_CONTROL_BYTES, /* Control bytes received from HLOS */
- NSS_N2H_STATS_N2H_CONTROL_PACKETS, /* Control packets sent to HLOS */
- NSS_N2H_STATS_N2H_CONTROL_BYTES, /* Control bytes sent to HLOS */
-
- NSS_N2H_STATS_H2N_DATA_PACKETS, /* Data packets received from HLOS */
- NSS_N2H_STATS_H2N_DATA_BYTES, /* Data bytes received from HLOS */
- NSS_N2H_STATS_N2H_DATA_PACKETS, /* Data packets sent to HLOS */
- NSS_N2H_STATS_N2H_DATA_BYTES, /* Data bytes sent to HLOS */
- NSS_N2H_STATS_N2H_TOT_PAYLOADS, /* No. of payloads in NSS */
- NSS_N2H_STATS_N2H_INTERFACE_INVALID, /* No. of bad interface access */
- NSS_N2H_STATS_ENQUEUE_RETRIES, /* No. of enqueue retries by N2H */
-
- NSS_N2H_STATS_MAX,
-};
-
-/*
* N2H statistics APIs
*/
+extern void nss_n2h_stats_notify(struct nss_ctx_instance *nss_ctx);
extern void nss_n2h_stats_sync(struct nss_ctx_instance *nss_ctx, struct nss_n2h_stats_sync *nnss);
extern void nss_n2h_stats_dentry_create(void);
diff --git a/nss_n2h_strings.c b/nss_n2h_strings.c
new file mode 100644
index 0000000..a9d34d7
--- /dev/null
+++ b/nss_n2h_strings.c
@@ -0,0 +1,83 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#include "nss_stats.h"
+#include "nss_core.h"
+#include <nss_n2h.h>
+#include "nss_strings.h"
+
+/*
+ * nss_n2h_strings_stats
+ * N2H statistics strings.
+ */
+struct nss_stats_info nss_n2h_strings_stats[NSS_N2H_STATS_MAX] = {
+ {"rx_pkts" , NSS_STATS_TYPE_COMMON},
+ {"rx_byts" , NSS_STATS_TYPE_COMMON},
+ {"tx_pkts" , NSS_STATS_TYPE_COMMON},
+ {"tx_byts" , NSS_STATS_TYPE_COMMON},
+ {"rx_queue[0]_drops" , NSS_STATS_TYPE_DROP},
+ {"rx_queue[1]_drops" , NSS_STATS_TYPE_DROP},
+ {"rx_queue[2]_drops" , NSS_STATS_TYPE_DROP},
+ {"rx_queue[3]_drops" , NSS_STATS_TYPE_DROP},
+ {"queue_drops" , NSS_STATS_TYPE_DROP},
+ {"ticks" , NSS_STATS_TYPE_SPECIAL},
+ {"worst_ticks" , NSS_STATS_TYPE_SPECIAL},
+ {"iterations" , NSS_STATS_TYPE_SPECIAL},
+ {"pbuf_ocm_alloc_fails" , NSS_STATS_TYPE_SPECIAL},
+ {"pbuf_ocm_free_count" , NSS_STATS_TYPE_SPECIAL},
+ {"pbuf_ocm_total_count" , NSS_STATS_TYPE_SPECIAL},
+ {"pbuf_default_alloc_fails" , NSS_STATS_TYPE_SPECIAL},
+ {"pbuf_default_free_count" , NSS_STATS_TYPE_SPECIAL},
+ {"pbuf_default_total_count" , NSS_STATS_TYPE_SPECIAL},
+ {"payload_fails" , NSS_STATS_TYPE_SPECIAL},
+ {"payload_free_count" , NSS_STATS_TYPE_SPECIAL},
+ {"h2n_control_pkts" , NSS_STATS_TYPE_SPECIAL},
+ {"h2n_control_byts" , NSS_STATS_TYPE_SPECIAL},
+ {"n2h_control_pkts" , NSS_STATS_TYPE_SPECIAL},
+ {"n2h_control_byts" , NSS_STATS_TYPE_SPECIAL},
+ {"h2n_data_pkts" , NSS_STATS_TYPE_SPECIAL},
+ {"h2n_data_byts" , NSS_STATS_TYPE_SPECIAL},
+ {"n2h_data_pkts" , NSS_STATS_TYPE_SPECIAL},
+ {"n2h_data_byts" , NSS_STATS_TYPE_SPECIAL},
+ {"n2h_tot_payloads" , NSS_STATS_TYPE_SPECIAL},
+ {"n2h_data_interface_invalid" , NSS_STATS_TYPE_SPECIAL},
+ {"enqueue_retries" , NSS_STATS_TYPE_SPECIAL}
+};
+
+/*
+ * nss_n2h_strings_read()
+ * Read N2H node statistics names.
+ */
+static ssize_t nss_n2h_strings_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
+{
+ return nss_strings_print(ubuf, sz, ppos, nss_n2h_strings_stats, NSS_N2H_STATS_MAX);
+}
+
+/*
+ * nss_n2h_strings_ops
+ */
+NSS_STRINGS_DECLARE_FILE_OPERATIONS(n2h);
+
+/*
+ * nss_n2h_strings_dentry_create()
+ * Create N2H statistics strings debug entry.
+ */
+void nss_n2h_strings_dentry_create(void)
+{
+ nss_strings_create_dentry("n2h", &nss_n2h_strings_ops);
+}
diff --git a/nss_n2h_strings.h b/nss_n2h_strings.h
new file mode 100644
index 0000000..5d8c213
--- /dev/null
+++ b/nss_n2h_strings.h
@@ -0,0 +1,25 @@
+/*
+ **************************************************************************
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for
+ * any purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ **************************************************************************
+ */
+
+#ifndef __NSS_N2H_STRINGS_H
+#define __NSS_N2H_STRINGS_H
+
+extern struct nss_stats_info nss_n2h_strings_stats[NSS_N2H_STATS_MAX];
+extern void nss_n2h_strings_dentry_create(void);
+
+#endif /* __NSS_N2H_STRINGS_H */
diff --git a/nss_stats.c b/nss_stats.c
index 9872943..9605c37 100644
--- a/nss_stats.c
+++ b/nss_stats.c
@@ -16,6 +16,7 @@
#include "nss_core.h"
#include "nss_strings.h"
+#include "nss_drv_stats.h"
/*
* Maximum banner length:
@@ -382,15 +383,10 @@
}
/*
- * TODO: Move the rest of the code to (nss_wt_stats.c, nss_gmac_stats.c, nss_drv_stats.c) accordingly.
+ * TODO: Move the rest of the code to (nss_wt_stats.c, nss_gmac_stats.c) accordingly.
*/
/*
- * drv_stats_ops
- */
-NSS_STATS_DECLARE_FILE_OPERATIONS(drv);
-
-/*
* gmac_stats_ops
*/
NSS_STATS_DECLARE_FILE_OPERATIONS(gmac);
@@ -443,7 +439,7 @@
/*
* drv_stats
*/
- nss_stats_create_dentry("drv", &nss_drv_stats_ops);
+ nss_drv_stats_dentry_create();
/*
* gmac_stats
diff --git a/nss_strings.c b/nss_strings.c
index a60c3c2..432b154 100644
--- a/nss_strings.c
+++ b/nss_strings.c
@@ -21,6 +21,7 @@
#include "nss_strings.h"
#include "nss_core.h"
+#include "nss_drv_strings.h"
/*
* common stats