32
32
33
33
#include <linux/mlx5/driver.h>
34
34
#include <linux/mlx5/fs.h>
35
+ #include <linux/rbtree.h>
35
36
#include "mlx5_core.h"
36
37
#include "fs_core.h"
37
38
#include "fs_cmd.h"
68
69
* elapsed, the thread will actually query the hardware.
69
70
*/
70
71
72
+ static void mlx5_fc_stats_insert (struct rb_root * root , struct mlx5_fc * counter )
73
+ {
74
+ struct rb_node * * new = & root -> rb_node ;
75
+ struct rb_node * parent = NULL ;
76
+
77
+ while (* new ) {
78
+ struct mlx5_fc * this = container_of (* new , struct mlx5_fc , node );
79
+ int result = counter -> id - this -> id ;
80
+
81
+ parent = * new ;
82
+ if (result < 0 )
83
+ new = & ((* new )-> rb_left );
84
+ else
85
+ new = & ((* new )-> rb_right );
86
+ }
87
+
88
+ /* Add new node and rebalance tree. */
89
+ rb_link_node (& counter -> node , parent , new );
90
+ rb_insert_color (& counter -> node , root );
91
+ }
92
+
71
93
static void mlx5_fc_stats_work (struct work_struct * work )
72
94
{
73
95
struct mlx5_core_dev * dev = container_of (work , struct mlx5_core_dev ,
74
96
priv .fc_stats .work .work );
75
97
struct mlx5_fc_stats * fc_stats = & dev -> priv .fc_stats ;
76
98
unsigned long now = jiffies ;
77
99
struct mlx5_fc * counter ;
78
- struct mlx5_fc * tmp ;
100
+ struct rb_node * node ;
101
+ LIST_HEAD (tmplist );
79
102
int err = 0 ;
80
103
81
104
spin_lock (& fc_stats -> addlist_lock );
82
105
83
- list_splice_tail_init (& fc_stats -> addlist , & fc_stats -> list );
106
+ list_splice_tail_init (& fc_stats -> addlist , & tmplist );
84
107
85
- if (!list_empty (& fc_stats -> list ))
108
+ if (!list_empty (& tmplist ) || ! RB_EMPTY_ROOT ( & fc_stats -> counters ))
86
109
queue_delayed_work (fc_stats -> wq , & fc_stats -> work , MLX5_FC_STATS_PERIOD );
87
110
88
111
spin_unlock (& fc_stats -> addlist_lock );
89
112
90
- list_for_each_entry_safe (counter , tmp , & fc_stats -> list , list ) {
91
- struct mlx5_fc_cache * c = & counter -> cache ;
113
+ list_for_each_entry (counter , & tmplist , list )
114
+ mlx5_fc_stats_insert (& fc_stats -> counters , counter );
115
+
116
+ node = rb_first (& fc_stats -> counters );
117
+ while (node ) {
118
+ struct mlx5_fc_cache * c ;
92
119
u64 packets ;
93
120
u64 bytes ;
94
121
122
+ counter = rb_entry (node , struct mlx5_fc , node );
123
+ c = & counter -> cache ;
124
+
125
+ node = rb_next (node );
126
+
95
127
if (counter -> deleted ) {
96
- list_del (& counter -> list );
128
+ rb_erase (& counter -> node , & fc_stats -> counters );
97
129
98
130
mlx5_cmd_fc_free (dev , counter -> id );
99
131
@@ -176,7 +208,7 @@ int mlx5_init_fc_stats(struct mlx5_core_dev *dev)
176
208
{
177
209
struct mlx5_fc_stats * fc_stats = & dev -> priv .fc_stats ;
178
210
179
- INIT_LIST_HEAD ( & fc_stats -> list ) ;
211
+ fc_stats -> counters = RB_ROOT ;
180
212
INIT_LIST_HEAD (& fc_stats -> addlist );
181
213
spin_lock_init (& fc_stats -> addlist_lock );
182
214
@@ -194,20 +226,32 @@ void mlx5_cleanup_fc_stats(struct mlx5_core_dev *dev)
194
226
struct mlx5_fc_stats * fc_stats = & dev -> priv .fc_stats ;
195
227
struct mlx5_fc * counter ;
196
228
struct mlx5_fc * tmp ;
229
+ struct rb_node * node ;
197
230
198
231
cancel_delayed_work_sync (& dev -> priv .fc_stats .work );
199
232
destroy_workqueue (dev -> priv .fc_stats .wq );
200
233
dev -> priv .fc_stats .wq = NULL ;
201
234
202
- list_splice_tail_init (& fc_stats -> addlist , & fc_stats -> list );
203
-
204
- list_for_each_entry_safe (counter , tmp , & fc_stats -> list , list ) {
235
+ list_for_each_entry_safe (counter , tmp , & fc_stats -> addlist , list ) {
205
236
list_del (& counter -> list );
206
237
207
238
mlx5_cmd_fc_free (dev , counter -> id );
208
239
209
240
kfree (counter );
210
241
}
242
+
243
+ node = rb_first (& fc_stats -> counters );
244
+ while (node ) {
245
+ counter = rb_entry (node , struct mlx5_fc , node );
246
+
247
+ node = rb_next (node );
248
+
249
+ rb_erase (& counter -> node , & fc_stats -> counters );
250
+
251
+ mlx5_cmd_fc_free (dev , counter -> id );
252
+
253
+ kfree (counter );
254
+ }
211
255
}
212
256
213
257
void mlx5_fc_query_cached (struct mlx5_fc * counter ,
0 commit comments