blob: 62cc44a14cddcc9ac6a1fa8c5ec10d0fd70cfa18 [file] [log] [blame]
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +05301/*
2 **************************************************************************
Zac Livingston866b0e22013-10-23 18:14:17 -06003 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
Radhakrishna Jiguru1c9b2252013-08-27 23:57:48 +05304 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all copies.
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
13 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 **************************************************************************
15 */
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053016
17/*
18 * nss_stats.c
19 * NSS stats APIs
20 *
21 */
22
23#include "nss_core.h"
24
25/*
26 * Maximum string length:
27 * This should be equal to maximum string size of any stats
28 * inclusive of stats value
29 */
30#define NSS_STATS_MAX_STR_LENGTH 96
31
32/*
33 * Global variables/extern declarations
34 */
35extern struct nss_top_instance nss_top_main;
36
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053037uint64_t stats_shadow_pppoe_except[NSS_PPPOE_NUM_SESSION_PER_INTERFACE][NSS_EXCEPTION_EVENT_PPPOE_MAX];
38
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053039/*
40 * Statistics structures
41 */
42
43/*
44 * nss_stats_str_ipv4
45 * IPv4 stats strings
46 */
47static int8_t *nss_stats_str_ipv4[NSS_STATS_IPV4_MAX] = {
48 "rx_pkts",
49 "rx_bytes",
50 "tx_pkts",
51 "tx_bytes",
52 "create_requests",
53 "create_collisions",
54 "create_invalid_interface",
55 "destroy_requests",
56 "destroy_misses",
57 "hash_hits",
58 "hash_reorders",
59 "flushes",
60 "evictions"
61};
62
63/*
64 * nss_stats_str_ipv6
65 * IPv6 stats strings
66 */
67static int8_t *nss_stats_str_ipv6[NSS_STATS_IPV6_MAX] = {
68 "rx_pkts",
69 "rx_bytes",
70 "tx_pkts",
71 "tx_bytes",
72 "create_requests",
73 "create_collisions",
74 "create_invalid_interface",
75 "destroy_requests",
76 "destroy_misses",
77 "hash_hits",
78 "hash_reorders",
79 "flushes",
80 "evictions",
81};
82
83/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053084 * nss_stats_str_n2h
85 * N2H stats strings
86 */
87static int8_t *nss_stats_str_n2h[NSS_STATS_N2H_MAX] = {
88 "queue_dropped",
89 "ticks",
90 "worst_ticks",
91 "iterations"
Abhishek Rastogi84d95d02014-03-26 19:31:31 +053092 "pbuf_fails",
93 "payload_fails"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +053094};
95
96/*
97 * nss_stats_str_drv
98 * Host driver stats strings
99 */
100static int8_t *nss_stats_str_drv[NSS_STATS_DRV_MAX] = {
101 "nbuf_alloc_errors",
102 "tx_queue_full[0]",
103 "tx_queue_full[1]",
104 "tx_buffers_empty",
105 "tx_buffers_pkt",
106 "tx_buffers_cmd",
107 "tx_buffers_crypto",
108 "rx_buffers_empty",
109 "rx_buffers_pkt",
110 "rx_buffers_cmd_resp",
111 "rx_buffers_status_sync",
112 "rx_buffers_crypto",
113 "rx_buffers_virtual"
114};
115
116/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530117 * nss_stats_str_pppoe
118 * PPPoE stats strings
119 */
120static int8_t *nss_stats_str_pppoe[NSS_STATS_PPPOE_MAX] = {
121 "create_requests",
122 "create_failures",
123 "destroy_requests",
124 "destroy_misses"
125};
126
127/*
128 * nss_stats_str_gmac
129 * GMAC stats strings
130 */
131static int8_t *nss_stats_str_gmac[NSS_STATS_GMAC_MAX] = {
132 "ticks",
133 "worst_ticks",
134 "iterations"
135};
136
137/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530138 * nss_stats_str_node
139 * Interface stats strings per node
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530140 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530141static int8_t *nss_stats_str_node[NSS_STATS_NODE_MAX] = {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530142 "rx_packets",
143 "rx_bytes",
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530144 "rx_dropped",
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530145 "tx_packets",
146 "tx_bytes"
147};
148
149/*
150 * nss_stats_str_if_exception_unknown
151 * Interface stats strings for unknown exceptions
152 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530153static int8_t *nss_stats_str_if_exception_eth_rx[NSS_EXCEPTION_EVENT_ETH_RX_MAX] = {
154 "UNKNOWN_L3_PROTOCOL"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530155};
156
157/*
158 * nss_stats_str_if_exception_ipv4
159 * Interface stats strings for ipv4 exceptions
160 */
161static int8_t *nss_stats_str_if_exception_ipv4[NSS_EXCEPTION_EVENT_IPV4_MAX] = {
162 "IPV4_ICMP_HEADER_INCOMPLETE",
163 "IPV4_ICMP_UNHANDLED_TYPE",
164 "IPV4_ICMP_IPV4_HEADER_INCOMPLETE",
165 "IPV4_ICMP_IPV4_UDP_HEADER_INCOMPLETE",
166 "IPV4_ICMP_IPV4_TCP_HEADER_INCOMPLETE",
167 "IPV4_ICMP_IPV4_UNKNOWN_PROTOCOL",
168 "IPV4_ICMP_NO_ICME",
169 "IPV4_ICMP_FLUSH_TO_HOST",
170 "IPV4_TCP_HEADER_INCOMPLETE",
171 "IPV4_TCP_NO_ICME",
172 "IPV4_TCP_IP_OPTION",
173 "IPV4_TCP_IP_FRAGMENT",
174 "IPV4_TCP_SMALL_TTL",
175 "IPV4_TCP_NEEDS_FRAGMENTATION",
176 "IPV4_TCP_FLAGS",
177 "IPV4_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
178 "IPV4_TCP_SMALL_DATA_OFFS",
179 "IPV4_TCP_BAD_SACK",
180 "IPV4_TCP_BIG_DATA_OFFS",
181 "IPV4_TCP_SEQ_BEFORE_LEFT_EDGE",
182 "IPV4_TCP_ACK_EXCEEDS_RIGHT_EDGE",
183 "IPV4_TCP_ACK_BEFORE_LEFT_EDGE",
184 "IPV4_UDP_HEADER_INCOMPLETE",
185 "IPV4_UDP_NO_ICME",
186 "IPV4_UDP_IP_OPTION",
187 "IPV4_UDP_IP_FRAGMENT",
188 "IPV4_UDP_SMALL_TTL",
189 "IPV4_UDP_NEEDS_FRAGMENTATION",
190 "IPV4_WRONG_TARGET_MAC",
191 "IPV4_HEADER_INCOMPLETE",
192 "IPV4_BAD_TOTAL_LENGTH",
193 "IPV4_BAD_CHECKSUM",
194 "IPV4_NON_INITIAL_FRAGMENT",
195 "IPV4_DATAGRAM_INCOMPLETE",
196 "IPV4_OPTIONS_INCOMPLETE",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530197 "IPV4_UNKNOWN_PROTOCOL",
198 "IPV4_ESP_HEADER_INCOMPLETE",
199 "IPV4_ESP_NO_ICME",
200 "IPV4_ESP_IP_OPTION",
201 "IPV4_ESP_IP_FRAGMENT",
202 "IPV4_ESP_SMALL_TTL",
203 "IPV4_ESP_NEEDS_FRAGMENTATION",
204 "IPV4_INGRESS_VID_MISMATCH",
205 "IPV4_6RD_NO_ICME",
206 "IPV4_6RD_IP_OPTION",
207 "IPV4_6RD_IP_FRAGMENT",
208 "IPV4_6RD_NEEDS_FRAGMENTATION"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530209};
210
211/*
212 * nss_stats_str_if_exception_ipv6
213 * Interface stats strings for ipv6 exceptions
214 */
215static int8_t *nss_stats_str_if_exception_ipv6[NSS_EXCEPTION_EVENT_IPV6_MAX] = {
216 "IPV6_ICMP_HEADER_INCOMPLETE",
217 "IPV6_ICMP_UNHANDLED_TYPE",
218 "IPV6_ICMP_IPV6_HEADER_INCOMPLETE",
219 "IPV6_ICMP_IPV6_UDP_HEADER_INCOMPLETE",
220 "IPV6_ICMP_IPV6_TCP_HEADER_INCOMPLETE",
221 "IPV6_ICMP_IPV6_UNKNOWN_PROTOCOL",
222 "IPV6_ICMP_NO_ICME",
223 "IPV6_ICMP_FLUSH_TO_HOST",
224 "IPV6_TCP_HEADER_INCOMPLETE",
225 "IPV6_TCP_NO_ICME",
226 "IPV6_TCP_SMALL_HOP_LIMIT",
227 "IPV6_TCP_NEEDS_FRAGMENTATION",
228 "IPV6_TCP_FLAGS",
229 "IPV6_TCP_SEQ_EXCEEDS_RIGHT_EDGE",
230 "IPV6_TCP_SMALL_DATA_OFFS",
231 "IPV6_TCP_BAD_SACK",
232 "IPV6_TCP_BIG_DATA_OFFS",
233 "IPV6_TCP_SEQ_BEFORE_LEFT_EDGE",
234 "IPV6_TCP_ACK_EXCEEDS_RIGHT_EDGE",
235 "IPV6_TCP_ACK_BEFORE_LEFT_EDGE",
236 "IPV6_UDP_HEADER_INCOMPLETE",
237 "IPV6_UDP_NO_ICME",
238 "IPV6_UDP_SMALL_HOP_LIMIT",
239 "IPV6_UDP_NEEDS_FRAGMENTATION",
240 "IPV6_WRONG_TARGET_MAC",
241 "IPV6_HEADER_INCOMPLETE",
Radha krishna Simha Jiguru59a1a1c2014-01-27 18:29:40 +0530242 "IPV6_UNKNOWN_PROTOCOL",
243 "IPV6_INGRESS_VID_MISMATCH"
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530244};
245
246/*
247 * nss_stats_str_if_exception_pppoe
248 * Interface stats strings for PPPoE exceptions
249 */
250static int8_t *nss_stats_str_if_exception_pppoe[NSS_EXCEPTION_EVENT_PPPOE_MAX] = {
251 "PPPOE_WRONG_VERSION_OR_TYPE",
252 "PPPOE_WRONG_CODE",
253 "PPPOE_HEADER_INCOMPLETE",
254 "PPPOE_UNSUPPORTED_PPP_PROTOCOL"
255};
256
257/*
258 * nss_stats_ipv4_read()
259 * Read IPV4 stats
260 */
261static ssize_t nss_stats_ipv4_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
262{
263 int32_t i;
264
265 /*
266 * max output lines = #stats + start tag line + end tag line + three blank lines
267 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530268 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV4_MAX + 3) + (NSS_EXCEPTION_EVENT_IPV4_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530269 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
270 size_t size_wr = 0;
271 ssize_t bytes_read = 0;
272 uint64_t *stats_shadow;
273
274 char *lbuf = kzalloc(size_al, GFP_KERNEL);
275 if (unlikely(lbuf == NULL)) {
276 nss_warning("Could not allocate memory for local statistics buffer");
277 return 0;
278 }
279
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530280 /*
281 * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
282 */
283 stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV4_MAX * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530284 if (unlikely(stats_shadow == NULL)) {
285 nss_warning("Could not allocate memory for local shadow buffer");
286 return 0;
287 }
288
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530289 size_wr = scnprintf(lbuf, size_al, "ipv4 stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530290
291 /*
292 * Common node stats
293 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530294 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530295 spin_lock_bh(&nss_top_main.stats_lock);
296 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
297 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV4_RX_INTERFACE][i];
298 }
299
300 spin_unlock_bh(&nss_top_main.stats_lock);
301
302 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
303 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
304 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
305 }
306
307 /*
308 * IPv4 node stats
309 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530310 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530311
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530312 spin_lock_bh(&nss_top_main.stats_lock);
313 for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
314 stats_shadow[i] = nss_top_main.stats_ipv4[i];
315 }
316
317 spin_unlock_bh(&nss_top_main.stats_lock);
318
319 for (i = 0; (i < NSS_STATS_IPV4_MAX); i++) {
320 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
321 "%s = %llu\n", nss_stats_str_ipv4[i], stats_shadow[i]);
322 }
323
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530324 /*
325 * Exception stats
326 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530327 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530328
329 spin_lock_bh(&nss_top_main.stats_lock);
330 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
331 stats_shadow[i] = nss_top_main.stats_if_exception_ipv4[i];
332 }
333
334 spin_unlock_bh(&nss_top_main.stats_lock);
335
336 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV4_MAX); i++) {
337 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
338 "%s = %llu\n", nss_stats_str_if_exception_ipv4[i], stats_shadow[i]);
339 }
340
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530341 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv4 stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530342 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
343 kfree(lbuf);
344 kfree(stats_shadow);
345
346 return bytes_read;
347}
348
349/*
350 * nss_stats_ipv6_read()
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530351 * Read IPV6 stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530352 */
353static ssize_t nss_stats_ipv6_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
354{
355 int32_t i;
356
357 /*
358 * max output lines = #stats + start tag line + end tag line + three blank lines
359 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530360 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_IPV6_MAX + 3) + (NSS_EXCEPTION_EVENT_IPV6_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530361 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
362 size_t size_wr = 0;
363 ssize_t bytes_read = 0;
364 uint64_t *stats_shadow;
365
366 char *lbuf = kzalloc(size_al, GFP_KERNEL);
367 if (unlikely(lbuf == NULL)) {
368 nss_warning("Could not allocate memory for local statistics buffer");
369 return 0;
370 }
371
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530372 /*
373 * Note: The assumption here is that exception event count is larger than other statistics count for IPv4
374 */
375 stats_shadow = kzalloc(NSS_EXCEPTION_EVENT_IPV6_MAX * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530376 if (unlikely(stats_shadow == NULL)) {
377 nss_warning("Could not allocate memory for local shadow buffer");
378 return 0;
379 }
380
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530381 size_wr = scnprintf(lbuf, size_al, "ipv6 stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530382
383 /*
384 * Common node stats
385 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530386 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530387 spin_lock_bh(&nss_top_main.stats_lock);
388 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
389 stats_shadow[i] = nss_top_main.stats_node[NSS_IPV6_RX_INTERFACE][i];
390 }
391
392 spin_unlock_bh(&nss_top_main.stats_lock);
393
394 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
395 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
396 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
397 }
398
399 /*
400 * IPv6 node stats
401 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530402 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530403
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530404 spin_lock_bh(&nss_top_main.stats_lock);
405 for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
406 stats_shadow[i] = nss_top_main.stats_ipv6[i];
407 }
408
409 spin_unlock_bh(&nss_top_main.stats_lock);
410
411 for (i = 0; (i < NSS_STATS_IPV6_MAX); i++) {
412 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
413 "%s = %llu\n", nss_stats_str_ipv6[i], stats_shadow[i]);
414 }
415
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530416 /*
417 * Exception stats
418 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530419 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nipv6 exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530420
421 spin_lock_bh(&nss_top_main.stats_lock);
422 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
423 stats_shadow[i] = nss_top_main.stats_if_exception_ipv6[i];
424 }
425
426 spin_unlock_bh(&nss_top_main.stats_lock);
427
428 for (i = 0; (i < NSS_EXCEPTION_EVENT_IPV6_MAX); i++) {
429 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
430 "%s = %llu\n", nss_stats_str_if_exception_ipv6[i], stats_shadow[i]);
431 }
432
433 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\nipv6 stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530434 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
435 kfree(lbuf);
436 kfree(stats_shadow);
437
438 return bytes_read;
439}
440
441/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530442 * nss_stats_eth_rx_read()
443 * Read ETH_RX stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530444 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530445static ssize_t nss_stats_eth_rx_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530446{
447 int32_t i;
448
449 /*
450 * max output lines = #stats + start tag line + end tag line + three blank lines
451 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530452 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_EXCEPTION_EVENT_ETH_RX_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530453 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
454 size_t size_wr = 0;
455 ssize_t bytes_read = 0;
456 uint64_t *stats_shadow;
457
458 char *lbuf = kzalloc(size_al, GFP_KERNEL);
459 if (unlikely(lbuf == NULL)) {
460 nss_warning("Could not allocate memory for local statistics buffer");
461 return 0;
462 }
463
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530464 /*
465 * Note: The assumption here is that we do not have more than 64 stats
466 */
467 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530468 if (unlikely(stats_shadow == NULL)) {
469 nss_warning("Could not allocate memory for local shadow buffer");
470 return 0;
471 }
472
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530473 size_wr = scnprintf(lbuf, size_al,"eth_rx stats start:\n\n");
474
475 /*
476 * Common node stats
477 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530478 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530479 spin_lock_bh(&nss_top_main.stats_lock);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530480 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
481 stats_shadow[i] = nss_top_main.stats_node[NSS_ETH_RX_INTERFACE][i];
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530482 }
483
484 spin_unlock_bh(&nss_top_main.stats_lock);
485
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530486 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530487 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530488 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530489 }
490
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530491 /*
492 * Exception stats
493 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530494 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\neth_rx exception stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530495
496 spin_lock_bh(&nss_top_main.stats_lock);
497 for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
498 stats_shadow[i] = nss_top_main.stats_if_exception_eth_rx[i];
499 }
500
501 spin_unlock_bh(&nss_top_main.stats_lock);
502
503 for (i = 0; (i < NSS_EXCEPTION_EVENT_ETH_RX_MAX); i++) {
504 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
505 "%s = %llu\n", nss_stats_str_if_exception_eth_rx[i], stats_shadow[i]);
506 }
507
508 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\neth_rx stats end\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530509 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
510 kfree(lbuf);
511 kfree(stats_shadow);
512
513 return bytes_read;
514}
515
516/*
517 * nss_stats_n2h_read()
518 * Read N2H stats
519 */
520static ssize_t nss_stats_n2h_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
521{
522 int32_t i;
523
524 /*
525 * max output lines = #stats + start tag line + end tag line + three blank lines
526 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530527 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_N2H_MAX + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530528 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
529 size_t size_wr = 0;
530 ssize_t bytes_read = 0;
531 uint64_t *stats_shadow;
532
533 char *lbuf = kzalloc(size_al, GFP_KERNEL);
534 if (unlikely(lbuf == NULL)) {
535 nss_warning("Could not allocate memory for local statistics buffer");
536 return 0;
537 }
538
539 stats_shadow = kzalloc(NSS_STATS_N2H_MAX * 8, GFP_KERNEL);
540 if (unlikely(stats_shadow == NULL)) {
541 nss_warning("Could not allocate memory for local shadow buffer");
542 return 0;
543 }
544
545 size_wr = scnprintf(lbuf, size_al, "n2h stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530546
547 /*
548 * Common node stats
549 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530550 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530551 spin_lock_bh(&nss_top_main.stats_lock);
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530552 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
553 stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530554 }
555
556 spin_unlock_bh(&nss_top_main.stats_lock);
557
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530558 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
559 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
560 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
561 }
562
563 /*
564 * N2H node stats
565 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530566 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530567 spin_lock_bh(&nss_top_main.stats_lock);
568 for (i = NSS_STATS_NODE_MAX; (i < NSS_STATS_N2H_MAX); i++) {
569 stats_shadow[i] = nss_top_main.nss[0].stats_n2h[i];
570 }
571
572 spin_unlock_bh(&nss_top_main.stats_lock);
573
574 for (i = NSS_STATS_NODE_MAX; (i < NSS_STATS_N2H_MAX); i++) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530575 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
576 "%s = %llu\n", nss_stats_str_n2h[i], stats_shadow[i]);
577 }
578
579 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nn2h stats end\n\n");
580 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
581 kfree(lbuf);
582 kfree(stats_shadow);
583
584 return bytes_read;
585}
586
587/*
588 * nss_stats_drv_read()
589 * Read HLOS driver stats
590 */
591static ssize_t nss_stats_drv_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
592{
593 int32_t i;
594
595 /*
596 * max output lines = #stats + start tag line + end tag line + three blank lines
597 */
598 uint32_t max_output_lines = NSS_STATS_DRV_MAX + 5;
599 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
600 size_t size_wr = 0;
601 ssize_t bytes_read = 0;
602 uint64_t *stats_shadow;
603
604 char *lbuf = kzalloc(size_al, GFP_KERNEL);
605 if (unlikely(lbuf == NULL)) {
606 nss_warning("Could not allocate memory for local statistics buffer");
607 return 0;
608 }
609
610 stats_shadow = kzalloc(NSS_STATS_DRV_MAX * 8, GFP_KERNEL);
611 if (unlikely(stats_shadow == NULL)) {
612 nss_warning("Could not allocate memory for local shadow buffer");
613 return 0;
614 }
615
616 size_wr = scnprintf(lbuf, size_al, "drv stats start:\n\n");
617 spin_lock_bh(&nss_top_main.stats_lock);
618 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
619 stats_shadow[i] = nss_top_main.stats_drv[i];
620 }
621
622 spin_unlock_bh(&nss_top_main.stats_lock);
623
624 for (i = 0; (i < NSS_STATS_DRV_MAX); i++) {
625 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
626 "%s = %llu\n", nss_stats_str_drv[i], stats_shadow[i]);
627 }
628
629 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ndrv stats end\n\n");
630 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
631 kfree(lbuf);
632 kfree(stats_shadow);
633
634 return bytes_read;
635}
636
637/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530638 * nss_stats_pppoe_read()
639 * Read PPPoE stats
640 */
641static ssize_t nss_stats_pppoe_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
642{
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530643 int32_t i, j, k;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530644
645 /*
646 * max output lines = #stats + start tag line + end tag line + three blank lines
647 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530648 uint32_t max_output_lines = (NSS_STATS_NODE_MAX + 2) + (NSS_STATS_PPPOE_MAX + 3) +
649 ((NSS_MAX_PHYSICAL_INTERFACES * NSS_PPPOE_NUM_SESSION_PER_INTERFACE * (NSS_EXCEPTION_EVENT_PPPOE_MAX + 5)) + 3) + 5;
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530650 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
651 size_t size_wr = 0;
652 ssize_t bytes_read = 0;
653 uint64_t *stats_shadow;
654
655 char *lbuf = kzalloc(size_al, GFP_KERNEL);
656 if (unlikely(lbuf == NULL)) {
657 nss_warning("Could not allocate memory for local statistics buffer");
658 return 0;
659 }
660
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530661 stats_shadow = kzalloc(64 * 8, GFP_KERNEL);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530662 if (unlikely(stats_shadow == NULL)) {
663 nss_warning("Could not allocate memory for local shadow buffer");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530664 kfree(lbuf);
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530665 return 0;
666 }
667
668 size_wr = scnprintf(lbuf, size_al, "pppoe stats start:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530669
670 /*
671 * Common node stats
672 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530673 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "common node stats:\n\n");
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530674 spin_lock_bh(&nss_top_main.stats_lock);
675 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
676 stats_shadow[i] = nss_top_main.stats_node[NSS_PPPOE_RX_INTERFACE][i];
677 }
678
679 spin_unlock_bh(&nss_top_main.stats_lock);
680
681 for (i = 0; (i < NSS_STATS_NODE_MAX); i++) {
682 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
683 "%s = %llu\n", nss_stats_str_node[i], stats_shadow[i]);
684 }
685
686 /*
687 * PPPoE node stats
688 */
Abhishek Rastogia1a07972014-04-01 19:43:33 +0530689 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "pppoe node stats:\n\n");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530690 spin_lock_bh(&nss_top_main.stats_lock);
691 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
692 stats_shadow[i] = nss_top_main.stats_pppoe[i];
693 }
694
695 spin_unlock_bh(&nss_top_main.stats_lock);
696
697 for (i = 0; (i < NSS_STATS_PPPOE_MAX); i++) {
698 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
699 "%s = %llu\n", nss_stats_str_pppoe[i], stats_shadow[i]);
700 }
701
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530702 /*
703 * Exception stats
704 */
705 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nException PPPoE:\n\n");
706
707 for (j = 0; j < NSS_MAX_PHYSICAL_INTERFACES; j++) {
708 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\nInterface %d:\n\n", j);
709
710 spin_lock_bh(&nss_top_main.stats_lock);
711 for (k = 0; k < NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
712 for (i = 0; (i < NSS_EXCEPTION_EVENT_PPPOE_MAX); i++) {
713 stats_shadow_pppoe_except[k][i] = nss_top_main.stats_if_exception_pppoe[j][k][i];
714 }
715 }
716
717 spin_unlock_bh(&nss_top_main.stats_lock);
718
719 for (k = 0; k < NSS_PPPOE_NUM_SESSION_PER_INTERFACE; k++) {
720 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "%d. Session\n", k);
721 for (i = 0; (i < NSS_EXCEPTION_EVENT_PPPOE_MAX); i++) {
722 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
723 "%s = %llu\n",
724 nss_stats_str_if_exception_pppoe[i],
725 stats_shadow_pppoe_except[k][i]);
726 }
727 }
728
729 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\npppoe stats end\n\n");
730 }
731
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530732 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
733 kfree(lbuf);
734 kfree(stats_shadow);
735
736 return bytes_read;
737}
738
739/*
740 * nss_stats_gmac_read()
741 * Read GMAC stats
742 */
743static ssize_t nss_stats_gmac_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
744{
745 uint32_t i, id;
746
747 /*
748 * max output lines = ((#stats + start tag + one blank) * #GMACs) + start/end tag + 3 blank
749 */
750 uint32_t max_output_lines = ((NSS_STATS_GMAC_MAX + 2) * NSS_MAX_PHYSICAL_INTERFACES) + 5;
751 size_t size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines;
752 size_t size_wr = 0;
753 ssize_t bytes_read = 0;
754 uint64_t *stats_shadow;
755
756 char *lbuf = kzalloc(size_al, GFP_KERNEL);
757 if (unlikely(lbuf == NULL)) {
758 nss_warning("Could not allocate memory for local statistics buffer");
759 return 0;
760 }
761
762 stats_shadow = kzalloc(NSS_STATS_GMAC_MAX * 8, GFP_KERNEL);
763 if (unlikely(stats_shadow == NULL)) {
764 nss_warning("Could not allocate memory for local shadow buffer");
765 return 0;
766 }
767
768 size_wr = scnprintf(lbuf, size_al, "gmac stats start:\n\n");
769
770 for (id = 0; id < NSS_MAX_PHYSICAL_INTERFACES; id++) {
771 spin_lock_bh(&nss_top_main.stats_lock);
772 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
773 stats_shadow[i] = nss_top_main.stats_gmac[id][i];
774 }
775
776 spin_unlock_bh(&nss_top_main.stats_lock);
777
778 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "GMAC ID: %d\n", id);
779 for (i = 0; (i < NSS_STATS_GMAC_MAX); i++) {
780 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,
781 "%s = %llu\n", nss_stats_str_gmac[i], stats_shadow[i]);
782 }
783 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr,"\n");
784 }
785
786 size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\ngmac stats end\n\n");
787 bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, strlen(lbuf));
788 kfree(lbuf);
789 kfree(stats_shadow);
790
791 return bytes_read;
792}
793
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530794#define NSS_STATS_DECLARE_FILE_OPERATIONS(name) \
795static const struct file_operations nss_stats_##name##_ops = { \
796 .open = simple_open, \
797 .read = nss_stats_##name##_read, \
798 .llseek = generic_file_llseek, \
799};
800
801/*
802 * nss_ipv4_stats_ops
803 */
804NSS_STATS_DECLARE_FILE_OPERATIONS(ipv4)
805
806/*
807 * ipv6_stats_ops
808 */
809NSS_STATS_DECLARE_FILE_OPERATIONS(ipv6)
810
811/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530812 * n2h_stats_ops
813 */
814NSS_STATS_DECLARE_FILE_OPERATIONS(n2h)
815/*
816 * drv_stats_ops
817 */
818NSS_STATS_DECLARE_FILE_OPERATIONS(drv)
819
820/*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530821 * pppoe_stats_ops
822 */
823NSS_STATS_DECLARE_FILE_OPERATIONS(pppoe)
824
825/*
826 * gmac_stats_ops
827 */
828NSS_STATS_DECLARE_FILE_OPERATIONS(gmac)
829
830/*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530831 * eth_rx_stats_ops
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530832 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530833NSS_STATS_DECLARE_FILE_OPERATIONS(eth_rx)
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530834
835/*
836 * nss_stats_init()
837 * Enable NSS statistics
838 */
839void nss_stats_init(void)
840{
841 /*
842 * NSS driver entry
843 */
844 nss_top_main.top_dentry = debugfs_create_dir("qca-nss-drv", NULL);
845 if (unlikely(nss_top_main.top_dentry == NULL)) {
846 nss_warning("Failed to create qca-nss-drv directory in debugfs");
847
848 /*
849 * Non availability of debugfs directory is not a catastrophy
850 * We can still go ahead with other initialization
851 */
852 return;
853 }
854
855 nss_top_main.stats_dentry = debugfs_create_dir("stats", nss_top_main.top_dentry);
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530856 if (unlikely(nss_top_main.stats_dentry == NULL)) {
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530857 nss_warning("Failed to create qca-nss-drv directory in debugfs");
858
859 /*
860 * Non availability of debugfs directory is not a catastrophy
861 * We can still go ahead with rest of initialization
862 */
863 return;
864 }
865
866 /*
867 * Create files to obtain statistics
868 */
869
870 /*
871 * ipv4_stats
872 */
873 nss_top_main.ipv4_dentry = debugfs_create_file("ipv4", 0400,
874 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv4_ops);
875 if (unlikely(nss_top_main.ipv4_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530876 nss_warning("Failed to create qca-nss-drv/stats/ipv4 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530877 return;
878 }
879
880 /*
881 * ipv6_stats
882 */
883 nss_top_main.ipv6_dentry = debugfs_create_file("ipv6", 0400,
884 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_ipv6_ops);
885 if (unlikely(nss_top_main.ipv6_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530886 nss_warning("Failed to create qca-nss-drv/stats/ipv6 file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530887 return;
888 }
889
890 /*
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530891 * ipv6_stats
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530892 */
Abhishek Rastogi84d95d02014-03-26 19:31:31 +0530893 nss_top_main.eth_rx_dentry = debugfs_create_file("eth_rx", 0400,
894 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_eth_rx_ops);
895 if (unlikely(nss_top_main.eth_rx_dentry == NULL)) {
896 nss_warning("Failed to create qca-nss-drv/stats/eth_rx file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530897 return;
898 }
899
900 /*
901 * n2h_stats
902 */
903 nss_top_main.n2h_dentry = debugfs_create_file("n2h", 0400,
904 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_n2h_ops);
905 if (unlikely(nss_top_main.n2h_dentry == NULL)) {
906 nss_warning("Failed to create qca-nss-drv/stats/n2h directory in debugfs");
907 return;
908 }
909
910 /*
911 * drv_stats
912 */
913 nss_top_main.drv_dentry = debugfs_create_file("drv", 0400,
914 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_drv_ops);
915 if (unlikely(nss_top_main.drv_dentry == NULL)) {
916 nss_warning("Failed to create qca-nss-drv/stats/drv directory in debugfs");
917 return;
918 }
919
920 /*
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530921 * pppoe_stats
922 */
923 nss_top_main.pppoe_dentry = debugfs_create_file("pppoe", 0400,
924 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_pppoe_ops);
925 if (unlikely(nss_top_main.pppoe_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530926 nss_warning("Failed to create qca-nss-drv/stats/pppoe file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530927 return;
928 }
929
930 /*
931 * gmac_stats
932 */
933 nss_top_main.gmac_dentry = debugfs_create_file("gmac", 0400,
934 nss_top_main.stats_dentry, &nss_top_main, &nss_stats_gmac_ops);
935 if (unlikely(nss_top_main.gmac_dentry == NULL)) {
Abhishek Rastogi80f4eb12013-09-24 14:31:21 +0530936 nss_warning("Failed to create qca-nss-drv/stats/gmac file in debugfs");
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530937 return;
938 }
Abhishek Rastogi38cffff2013-06-02 11:25:47 +0530939}
940
941
942/*
943 * nss_stats_clean()
944 * Cleanup NSS statistics files
945 */
946void nss_stats_clean(void)
947{
948 /*
949 * Remove debugfs tree
950 */
951 if (likely(nss_top_main.top_dentry != NULL)) {
952 debugfs_remove_recursive(nss_top_main.top_dentry);
953 }
954}