1 // SPDX-License-Identifier: GPL-2.0
11 #include "netdev-user.h"
21 size_t alloc_slow
, alloc_fast
, recycle_ring
, recycle_cache
;
29 static struct stat
*find_ifc(struct stats_array
*a
, unsigned int ifindex
)
33 for (i
= 0; i
< a
->i
; i
++) {
34 if (a
->s
[i
].ifc
== ifindex
)
41 a
->s
= reallocarray(a
->s
, a
->max
, sizeof(*a
->s
));
43 a
->s
[i
].ifc
= ifindex
;
47 static void count(struct stat
*s
, unsigned int l
,
48 struct netdev_page_pool_get_rsp
*pp
)
51 if (pp
->_present
.inflight
)
52 s
->live
[l
].refs
+= pp
->inflight
;
53 if (pp
->_present
.inflight_mem
)
54 s
->live
[l
].bytes
+= pp
->inflight_mem
;
57 int main(int argc
, char **argv
)
59 struct netdev_page_pool_stats_get_list
*pp_stats
;
60 struct netdev_page_pool_get_list
*pools
;
61 struct stats_array a
= {};
62 struct ynl_error yerr
;
65 ys
= ynl_sock_create(&ynl_netdev_family
, &yerr
);
67 fprintf(stderr
, "YNL: %s\n", yerr
.msg
);
72 a
.s
= calloc(a
.max
, sizeof(*a
.s
));
76 pools
= netdev_page_pool_get_dump(ys
);
80 ynl_dump_foreach(pools
, pp
) {
81 struct stat
*s
= find_ifc(&a
, pp
->ifindex
);
84 if (pp
->_present
.detach_time
)
87 netdev_page_pool_get_list_free(pools
);
89 pp_stats
= netdev_page_pool_stats_get_dump(ys
);
93 ynl_dump_foreach(pp_stats
, pp
) {
94 struct stat
*s
= find_ifc(&a
, pp
->info
.ifindex
);
96 if (pp
->_present
.alloc_fast
)
97 s
->alloc_fast
+= pp
->alloc_fast
;
98 if (pp
->_present
.alloc_refill
)
99 s
->alloc_fast
+= pp
->alloc_refill
;
100 if (pp
->_present
.alloc_slow
)
101 s
->alloc_slow
+= pp
->alloc_slow
;
102 if (pp
->_present
.recycle_ring
)
103 s
->recycle_ring
+= pp
->recycle_ring
;
104 if (pp
->_present
.recycle_cached
)
105 s
->recycle_cache
+= pp
->recycle_cached
;
107 netdev_page_pool_stats_get_list_free(pp_stats
);
109 for (unsigned int i
= 0; i
< a
.i
; i
++) {
110 char ifname
[IF_NAMESIZE
];
111 struct stat
*s
= &a
.s
[i
];
118 name
= if_indextoname(s
->ifc
, ifname
);
121 printf("[%u]\t", s
->ifc
);
124 printf("page pools: %u (zombies: %u)\n",
125 s
->live
[1].cnt
, s
->live
[0].cnt
);
126 printf("\t\trefs: %zu bytes: %zu (refs: %zu bytes: %zu)\n",
127 s
->live
[1].refs
, s
->live
[1].bytes
,
128 s
->live
[0].refs
, s
->live
[0].bytes
);
130 /* We don't know how many pages are sitting in cache and ring
131 * so we will under-count the recycling rate a bit.
133 recycle
= (double)(s
->recycle_ring
+ s
->recycle_cache
) /
134 (s
->alloc_fast
+ s
->alloc_slow
) * 100;
135 printf("\t\trecycling: %.1lf%% (alloc: %zu:%zu recycle: %zu:%zu)\n",
136 recycle
, s
->alloc_slow
, s
->alloc_fast
,
137 s
->recycle_ring
, s
->recycle_cache
);
140 ynl_sock_destroy(ys
);
146 fprintf(stderr
, "YNL: %s\n", ys
->err
.msg
);
147 ynl_sock_destroy(ys
);