History

linux/dim: Move logic to dim.h

In preparation for supporting more implementations of the DIM algorithm, I'm moving what would become common logic to a common library. Downstream DIM implementations will use the common lib for their implementation.

Tal Gilboa committed 8 years ago

Commit 0e589831 parent cd6c84d3 files · +156 −146Browse files

Showing the changes to include/linux (2 of 3 files). Show all

Unified · Split

2 files
  1. include/linux/dim.h +153 −0
  2. include/linux/net_dim.h +2 −146
include/linux/dim.h+153−0
@@ -0,0 +1,153 @@
1/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2/* Copyright (c) 2019 Mellanox Technologies. */
3
4#ifndef DIM_H
5#define DIM_H
6
7#include <linux/module.h>
8
9#define NET_DIM_NEVENTS 64
10
11/* more than 10% difference */
12#define IS_SIGNIFICANT_DIFF(val, ref) \
13 (((100UL * abs((val) - (ref))) / (ref)) > 10)
14#define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) \
15& (BIT_ULL(bits) - 1))
16
17struct net_dim_cq_moder {
18 u16 usec;
19 u16 pkts;
20 u8 cq_period_mode;
21};
22
23struct net_dim_sample {
24 ktime_t time;
25 u32 pkt_ctr;
26 u32 byte_ctr;
27 u16 event_ctr;
28};
29
30struct net_dim_stats {
31 int ppms; /* packets per msec */
32 int bpms; /* bytes per msec */
33 int epms; /* events per msec */
34};
35
36struct net_dim { /* Dynamic Interrupt Moderation */
37 u8 state;
38 struct net_dim_stats prev_stats;
39 struct net_dim_sample start_sample;
40 struct work_struct work;
41 u8 profile_ix;
42 u8 mode;
43 u8 tune_state;
44 u8 steps_right;
45 u8 steps_left;
46 u8 tired;
47};
48
49enum {
50 NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE = 0x0,
51 NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE = 0x1,
52 NET_DIM_CQ_PERIOD_NUM_MODES
53};
54
55enum {
56 NET_DIM_START_MEASURE,
57 NET_DIM_MEASURE_IN_PROGRESS,
58 NET_DIM_APPLY_NEW_PROFILE,
59};
60
61enum {
62 NET_DIM_PARKING_ON_TOP,
63 NET_DIM_PARKING_TIRED,
64 NET_DIM_GOING_RIGHT,
65 NET_DIM_GOING_LEFT,
66};
67
68enum {
69 NET_DIM_STATS_WORSE,
70 NET_DIM_STATS_SAME,
71 NET_DIM_STATS_BETTER,
72};
73
74enum {
75 NET_DIM_STEPPED,
76 NET_DIM_TOO_TIRED,
77 NET_DIM_ON_EDGE,
78};
79
80static inline bool net_dim_on_top(struct net_dim *net_dim)
81{
82 switch (net_dim->tune_state) {
83 case NET_DIM_PARKING_ON_TOP:
84 case NET_DIM_PARKING_TIRED:
85 return true;
86 case NET_DIM_GOING_RIGHT:
87 return (net_dim->steps_left > 1) && (net_dim->steps_right == 1);
88 default: /* NET_DIM_GOING_LEFT */
89 return (net_dim->steps_right > 1) && (net_dim->steps_left == 1);
90 }
91}
92
93static inline void net_dim_turn(struct net_dim *net_dim)
94{
95 switch (net_dim->tune_state) {
96 case NET_DIM_PARKING_ON_TOP:
97 case NET_DIM_PARKING_TIRED:
98 break;
99 case NET_DIM_GOING_RIGHT:
100 net_dim->tune_state = NET_DIM_GOING_LEFT;
101 net_dim->steps_left = 0;
102 break;
103 case NET_DIM_GOING_LEFT:
104 net_dim->tune_state = NET_DIM_GOING_RIGHT;
105 net_dim->steps_right = 0;
106 break;
107 }
108}
109
110static inline void net_dim_park_on_top(struct net_dim *net_dim)
111{
112 net_dim->steps_right = 0;
113 net_dim->steps_left = 0;
114 net_dim->tired = 0;
115 net_dim->tune_state = NET_DIM_PARKING_ON_TOP;
116}
117
118static inline void net_dim_park_tired(struct net_dim *net_dim)
119{
120 net_dim->steps_right = 0;
121 net_dim->steps_left = 0;
122 net_dim->tune_state = NET_DIM_PARKING_TIRED;
123}
124
125static inline void
126net_dim_sample(u16 event_ctr, u64 packets, u64 bytes, struct net_dim_sample *s)
127{
128 s->time = ktime_get();
129 s->pkt_ctr = packets;
130 s->byte_ctr = bytes;
131 s->event_ctr = event_ctr;
132}
133
134static inline void
135net_dim_calc_stats(struct net_dim_sample *start, struct net_dim_sample *end,
136 struct net_dim_stats *curr_stats)
137{
138 /* u32 holds up to 71 minutes, should be enough */
139 u32 delta_us = ktime_us_delta(end->time, start->time);
140 u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr);
141 u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr,
142 start->byte_ctr);
143
144 if (!delta_us)
145 return;
146
147 curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
148 curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
149 curr_stats->epms = DIV_ROUND_UP(NET_DIM_NEVENTS * USEC_PER_MSEC,
150 delta_us);
151}
152
153#endif /* DIM_H */
include/linux/net_dim.h+2−146
@@ -35,73 +35,10 @@ · 34 unmodified lines
35#define NET_DIM_H35#define NET_DIM_H
36 36
37#include <linux/module.h>37#include <linux/module.h>
38 38#include <linux/dim.h>
39struct net_dim_cq_moder {
40 u16 usec;
41 u16 pkts;
42 u8 cq_period_mode;
43};
44
45struct net_dim_sample {
46 ktime_t time;
47 u32 pkt_ctr;
48 u32 byte_ctr;
49 u16 event_ctr;
50};
51
52struct net_dim_stats {
53 int ppms; /* packets per msec */
54 int bpms; /* bytes per msec */
55 int epms; /* events per msec */
56};
57
58struct net_dim { /* Adaptive Moderation */
59 u8 state;
60 struct net_dim_stats prev_stats;
61 struct net_dim_sample start_sample;
62 struct work_struct work;
63 u8 profile_ix;
64 u8 mode;
65 u8 tune_state;
66 u8 steps_right;
67 u8 steps_left;
68 u8 tired;
69};
70
71enum {
72 NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE = 0x0,
73 NET_DIM_CQ_PERIOD_MODE_START_FROM_CQE = 0x1,
74 NET_DIM_CQ_PERIOD_NUM_MODES
75};
76
77/* Adaptive moderation logic */
78enum {
79 NET_DIM_START_MEASURE,
80 NET_DIM_MEASURE_IN_PROGRESS,
81 NET_DIM_APPLY_NEW_PROFILE,
82};
83
84enum {
85 NET_DIM_PARKING_ON_TOP,
86 NET_DIM_PARKING_TIRED,
87 NET_DIM_GOING_RIGHT,
88 NET_DIM_GOING_LEFT,
89};
90
91enum {
92 NET_DIM_STATS_WORSE,
93 NET_DIM_STATS_SAME,
94 NET_DIM_STATS_BETTER,
95};
96
97enum {
98 NET_DIM_STEPPED,
99 NET_DIM_TOO_TIRED,
100 NET_DIM_ON_EDGE,
101};
102 39
103#define NET_DIM_PARAMS_NUM_PROFILES 540#define NET_DIM_PARAMS_NUM_PROFILES 5
104/* Adaptive moderation profiles */41/* Netdev dynamic interrupt moderation profiles */
105#define NET_DIM_DEFAULT_RX_CQ_MODERATION_PKTS_FROM_EQE 25642#define NET_DIM_DEFAULT_RX_CQ_MODERATION_PKTS_FROM_EQE 256
106#define NET_DIM_DEFAULT_TX_CQ_MODERATION_PKTS_FROM_EQE 12843#define NET_DIM_DEFAULT_TX_CQ_MODERATION_PKTS_FROM_EQE 128
107#define NET_DIM_DEF_PROFILE_CQE 144#define NET_DIM_DEF_PROFILE_CQE 1
@@ -188,36 +125,6 @@ net_dim_get_def_tx_moderation(u8 cq_period_mode) · 80 unmodified lines
188 return net_dim_get_tx_moderation(cq_period_mode, profile_ix);125 return net_dim_get_tx_moderation(cq_period_mode, profile_ix);
189}126}
190 127
191static inline bool net_dim_on_top(struct net_dim *dim)
192{
193 switch (dim->tune_state) {
194 case NET_DIM_PARKING_ON_TOP:
195 case NET_DIM_PARKING_TIRED:
196 return true;
197 case NET_DIM_GOING_RIGHT:
198 return (dim->steps_left > 1) && (dim->steps_right == 1);
199 default: /* NET_DIM_GOING_LEFT */
200 return (dim->steps_right > 1) && (dim->steps_left == 1);
201 }
202}
203
204static inline void net_dim_turn(struct net_dim *dim)
205{
206 switch (dim->tune_state) {
207 case NET_DIM_PARKING_ON_TOP:
208 case NET_DIM_PARKING_TIRED:
209 break;
210 case NET_DIM_GOING_RIGHT:
211 dim->tune_state = NET_DIM_GOING_LEFT;
212 dim->steps_left = 0;
213 break;
214 case NET_DIM_GOING_LEFT:
215 dim->tune_state = NET_DIM_GOING_RIGHT;
216 dim->steps_right = 0;
217 break;
218 }
219}
220
221static inline int net_dim_step(struct net_dim *dim)128static inline int net_dim_step(struct net_dim *dim)
222{129{
223 if (dim->tired == (NET_DIM_PARAMS_NUM_PROFILES * 2))130 if (dim->tired == (NET_DIM_PARAMS_NUM_PROFILES * 2))
@@ -245,21 +152,6 @@ static inline int net_dim_step(struct net_dim *dim) · 21 unmodified lines
245 return NET_DIM_STEPPED;152 return NET_DIM_STEPPED;
246}153}
247 154
248static inline void net_dim_park_on_top(struct net_dim *dim)
249{
250 dim->steps_right = 0;
251 dim->steps_left = 0;
252 dim->tired = 0;
253 dim->tune_state = NET_DIM_PARKING_ON_TOP;
254}
255
256static inline void net_dim_park_tired(struct net_dim *dim)
257{
258 dim->steps_right = 0;
259 dim->steps_left = 0;
260 dim->tune_state = NET_DIM_PARKING_TIRED;
261}
262
263static inline void net_dim_exit_parking(struct net_dim *dim)155static inline void net_dim_exit_parking(struct net_dim *dim)
264{156{
265 dim->tune_state = dim->profile_ix ? NET_DIM_GOING_LEFT :157 dim->tune_state = dim->profile_ix ? NET_DIM_GOING_LEFT :
@@ -267,9 +159,6 @@ static inline void net_dim_exit_parking(struct net_dim *dim) · 1 unmodified line
267 net_dim_step(dim);159 net_dim_step(dim);
268}160}
269 161
270#define IS_SIGNIFICANT_DIFF(val, ref) \
271 (((100UL * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
272
273static inline int net_dim_stats_compare(struct net_dim_stats *curr,162static inline int net_dim_stats_compare(struct net_dim_stats *curr,
274 struct net_dim_stats *prev)163 struct net_dim_stats *prev)
275{164{
@@ -351,39 +240,6 @@ static inline bool net_dim_decision(struct net_dim_stats *curr_stats, · 75 unmodified lines
351 return dim->profile_ix != prev_ix;240 return dim->profile_ix != prev_ix;
352}241}
353 242
354static inline void net_dim_sample(u16 event_ctr,
355 u64 packets,
356 u64 bytes,
357 struct net_dim_sample *s)
358{
359 s->time = ktime_get();
360 s->pkt_ctr = packets;
361 s->byte_ctr = bytes;
362 s->event_ctr = event_ctr;
363}
364
365#define NET_DIM_NEVENTS 64
366#define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) & (BIT_ULL(bits) - 1))
367
368static inline void net_dim_calc_stats(struct net_dim_sample *start,
369 struct net_dim_sample *end,
370 struct net_dim_stats *curr_stats)
371{
372 /* u32 holds up to 71 minutes, should be enough */
373 u32 delta_us = ktime_us_delta(end->time, start->time);
374 u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr);
375 u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr,
376 start->byte_ctr);
377
378 if (!delta_us)
379 return;
380
381 curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
382 curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
383 curr_stats->epms = DIV_ROUND_UP(NET_DIM_NEVENTS * USEC_PER_MSEC,
384 delta_us);
385}
386
387static inline void net_dim(struct net_dim *dim,243static inline void net_dim(struct net_dim *dim,
388 struct net_dim_sample end_sample)244 struct net_dim_sample end_sample)
389{245{

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t