This source file includes following definitions.
- ip_vs_read_cpu_stats
- estimation_timer
- ip_vs_start_estimator
- ip_vs_stop_estimator
- ip_vs_zero_estimator
- ip_vs_read_estimator
- ip_vs_estimator_net_init
- ip_vs_estimator_net_cleanup
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #define KMSG_COMPONENT "IPVS"
16 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
17
18 #include <linux/kernel.h>
19 #include <linux/jiffies.h>
20 #include <linux/types.h>
21 #include <linux/interrupt.h>
22 #include <linux/sysctl.h>
23 #include <linux/list.h>
24
25 #include <net/ip_vs.h>
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 static void ip_vs_read_cpu_stats(struct ip_vs_kstats *sum,
57 struct ip_vs_cpu_stats __percpu *stats)
58 {
59 int i;
60 bool add = false;
61
62 for_each_possible_cpu(i) {
63 struct ip_vs_cpu_stats *s = per_cpu_ptr(stats, i);
64 unsigned int start;
65 u64 conns, inpkts, outpkts, inbytes, outbytes;
66
67 if (add) {
68 do {
69 start = u64_stats_fetch_begin(&s->syncp);
70 conns = s->cnt.conns;
71 inpkts = s->cnt.inpkts;
72 outpkts = s->cnt.outpkts;
73 inbytes = s->cnt.inbytes;
74 outbytes = s->cnt.outbytes;
75 } while (u64_stats_fetch_retry(&s->syncp, start));
76 sum->conns += conns;
77 sum->inpkts += inpkts;
78 sum->outpkts += outpkts;
79 sum->inbytes += inbytes;
80 sum->outbytes += outbytes;
81 } else {
82 add = true;
83 do {
84 start = u64_stats_fetch_begin(&s->syncp);
85 sum->conns = s->cnt.conns;
86 sum->inpkts = s->cnt.inpkts;
87 sum->outpkts = s->cnt.outpkts;
88 sum->inbytes = s->cnt.inbytes;
89 sum->outbytes = s->cnt.outbytes;
90 } while (u64_stats_fetch_retry(&s->syncp, start));
91 }
92 }
93 }
94
95
96 static void estimation_timer(struct timer_list *t)
97 {
98 struct ip_vs_estimator *e;
99 struct ip_vs_stats *s;
100 u64 rate;
101 struct netns_ipvs *ipvs = from_timer(ipvs, t, est_timer);
102
103 spin_lock(&ipvs->est_lock);
104 list_for_each_entry(e, &ipvs->est_list, list) {
105 s = container_of(e, struct ip_vs_stats, est);
106
107 spin_lock(&s->lock);
108 ip_vs_read_cpu_stats(&s->kstats, s->cpustats);
109
110
111 rate = (s->kstats.conns - e->last_conns) << 9;
112 e->last_conns = s->kstats.conns;
113 e->cps += ((s64)rate - (s64)e->cps) >> 2;
114
115 rate = (s->kstats.inpkts - e->last_inpkts) << 9;
116 e->last_inpkts = s->kstats.inpkts;
117 e->inpps += ((s64)rate - (s64)e->inpps) >> 2;
118
119 rate = (s->kstats.outpkts - e->last_outpkts) << 9;
120 e->last_outpkts = s->kstats.outpkts;
121 e->outpps += ((s64)rate - (s64)e->outpps) >> 2;
122
123
124 rate = (s->kstats.inbytes - e->last_inbytes) << 4;
125 e->last_inbytes = s->kstats.inbytes;
126 e->inbps += ((s64)rate - (s64)e->inbps) >> 2;
127
128 rate = (s->kstats.outbytes - e->last_outbytes) << 4;
129 e->last_outbytes = s->kstats.outbytes;
130 e->outbps += ((s64)rate - (s64)e->outbps) >> 2;
131 spin_unlock(&s->lock);
132 }
133 spin_unlock(&ipvs->est_lock);
134 mod_timer(&ipvs->est_timer, jiffies + 2*HZ);
135 }
136
137 void ip_vs_start_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats)
138 {
139 struct ip_vs_estimator *est = &stats->est;
140
141 INIT_LIST_HEAD(&est->list);
142
143 spin_lock_bh(&ipvs->est_lock);
144 list_add(&est->list, &ipvs->est_list);
145 spin_unlock_bh(&ipvs->est_lock);
146 }
147
148 void ip_vs_stop_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats)
149 {
150 struct ip_vs_estimator *est = &stats->est;
151
152 spin_lock_bh(&ipvs->est_lock);
153 list_del(&est->list);
154 spin_unlock_bh(&ipvs->est_lock);
155 }
156
157 void ip_vs_zero_estimator(struct ip_vs_stats *stats)
158 {
159 struct ip_vs_estimator *est = &stats->est;
160 struct ip_vs_kstats *k = &stats->kstats;
161
162
163 est->last_inbytes = k->inbytes;
164 est->last_outbytes = k->outbytes;
165 est->last_conns = k->conns;
166 est->last_inpkts = k->inpkts;
167 est->last_outpkts = k->outpkts;
168 est->cps = 0;
169 est->inpps = 0;
170 est->outpps = 0;
171 est->inbps = 0;
172 est->outbps = 0;
173 }
174
175
176 void ip_vs_read_estimator(struct ip_vs_kstats *dst, struct ip_vs_stats *stats)
177 {
178 struct ip_vs_estimator *e = &stats->est;
179
180 dst->cps = (e->cps + 0x1FF) >> 10;
181 dst->inpps = (e->inpps + 0x1FF) >> 10;
182 dst->outpps = (e->outpps + 0x1FF) >> 10;
183 dst->inbps = (e->inbps + 0xF) >> 5;
184 dst->outbps = (e->outbps + 0xF) >> 5;
185 }
186
187 int __net_init ip_vs_estimator_net_init(struct netns_ipvs *ipvs)
188 {
189 INIT_LIST_HEAD(&ipvs->est_list);
190 spin_lock_init(&ipvs->est_lock);
191 timer_setup(&ipvs->est_timer, estimation_timer, 0);
192 mod_timer(&ipvs->est_timer, jiffies + 2 * HZ);
193 return 0;
194 }
195
196 void __net_exit ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs)
197 {
198 del_timer_sync(&ipvs->est_timer);
199 }