ipvs: Restrict connection table size via Kconfig
[deliverable/linux.git] / net / ipv4 / ipvs / ip_vs_est.c
CommitLineData
1da177e4
LT
1/*
2 * ip_vs_est.c: simple rate estimator for IPVS
3 *
1da177e4
LT
4 * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 * Changes:
12 *
13 */
14#include <linux/kernel.h>
14c85021
ACM
15#include <linux/jiffies.h>
16#include <linux/slab.h>
1da177e4 17#include <linux/types.h>
4ffd2e49 18#include <linux/interrupt.h>
90754f8e 19#include <linux/sysctl.h>
3a14a313 20#include <linux/list.h>
1da177e4
LT
21
22#include <net/ip_vs.h>
23
24/*
25 This code is to estimate rate in a shorter interval (such as 8
26 seconds) for virtual services and real servers. For measure rate in a
27 long interval, it is easy to implement a user level daemon which
28 periodically reads those statistical counters and measure rate.
29
30 Currently, the measurement is activated by slow timer handler. Hope
31 this measurement will not introduce too much load.
32
33 We measure rate during the last 8 seconds every 2 seconds:
34
35 avgrate = avgrate*(1-W) + rate*W
36
37 where W = 2^(-2)
38
39 NOTES.
40
41 * The stored value for average bps is scaled by 2^5, so that maximal
42 rate is ~2.15Gbits/s, average pps and cps are scaled by 2^10.
43
44 * A lot code is taken from net/sched/estimator.c
45 */
46
47
3a14a313 48static void estimation_timer(unsigned long arg);
1da177e4 49
3a14a313
SW
50static LIST_HEAD(est_list);
51static DEFINE_SPINLOCK(est_lock);
52static DEFINE_TIMER(est_timer, estimation_timer, 0, 0);
1da177e4
LT
53
54static void estimation_timer(unsigned long arg)
55{
56 struct ip_vs_estimator *e;
57 struct ip_vs_stats *s;
58 u32 n_conns;
59 u32 n_inpkts, n_outpkts;
60 u64 n_inbytes, n_outbytes;
61 u32 rate;
62
3a14a313
SW
63 spin_lock(&est_lock);
64 list_for_each_entry(e, &est_list, list) {
65 s = container_of(e, struct ip_vs_stats, est);
1da177e4
LT
66
67 spin_lock(&s->lock);
68 n_conns = s->conns;
69 n_inpkts = s->inpkts;
70 n_outpkts = s->outpkts;
71 n_inbytes = s->inbytes;
72 n_outbytes = s->outbytes;
73
74 /* scaled by 2^10, but divided 2 seconds */
75 rate = (n_conns - e->last_conns)<<9;
76 e->last_conns = n_conns;
77 e->cps += ((long)rate - (long)e->cps)>>2;
78 s->cps = (e->cps+0x1FF)>>10;
79
80 rate = (n_inpkts - e->last_inpkts)<<9;
81 e->last_inpkts = n_inpkts;
82 e->inpps += ((long)rate - (long)e->inpps)>>2;
83 s->inpps = (e->inpps+0x1FF)>>10;
84
85 rate = (n_outpkts - e->last_outpkts)<<9;
86 e->last_outpkts = n_outpkts;
87 e->outpps += ((long)rate - (long)e->outpps)>>2;
88 s->outpps = (e->outpps+0x1FF)>>10;
89
90 rate = (n_inbytes - e->last_inbytes)<<4;
91 e->last_inbytes = n_inbytes;
92 e->inbps += ((long)rate - (long)e->inbps)>>2;
93 s->inbps = (e->inbps+0xF)>>5;
94
95 rate = (n_outbytes - e->last_outbytes)<<4;
96 e->last_outbytes = n_outbytes;
97 e->outbps += ((long)rate - (long)e->outbps)>>2;
98 s->outbps = (e->outbps+0xF)>>5;
99 spin_unlock(&s->lock);
100 }
3a14a313 101 spin_unlock(&est_lock);
1da177e4
LT
102 mod_timer(&est_timer, jiffies + 2*HZ);
103}
104
3a14a313 105void ip_vs_new_estimator(struct ip_vs_stats *stats)
1da177e4 106{
3a14a313 107 struct ip_vs_estimator *est = &stats->est;
1da177e4 108
3a14a313 109 INIT_LIST_HEAD(&est->list);
1da177e4 110
1da177e4
LT
111 est->last_conns = stats->conns;
112 est->cps = stats->cps<<10;
113
114 est->last_inpkts = stats->inpkts;
115 est->inpps = stats->inpps<<10;
116
117 est->last_outpkts = stats->outpkts;
118 est->outpps = stats->outpps<<10;
119
120 est->last_inbytes = stats->inbytes;
121 est->inbps = stats->inbps<<5;
122
123 est->last_outbytes = stats->outbytes;
124 est->outbps = stats->outbps<<5;
125
3a14a313 126 spin_lock_bh(&est_lock);
3a14a313
SW
127 list_add(&est->list, &est_list);
128 spin_unlock_bh(&est_lock);
1da177e4
LT
129}
130
131void ip_vs_kill_estimator(struct ip_vs_stats *stats)
132{
3a14a313
SW
133 struct ip_vs_estimator *est = &stats->est;
134
135 spin_lock_bh(&est_lock);
136 list_del(&est->list);
3a14a313 137 spin_unlock_bh(&est_lock);
1da177e4
LT
138}
139
140void ip_vs_zero_estimator(struct ip_vs_stats *stats)
141{
3a14a313
SW
142 struct ip_vs_estimator *est = &stats->est;
143
144 /* set counters zero, caller must hold the stats->lock lock */
145 est->last_inbytes = 0;
146 est->last_outbytes = 0;
147 est->last_conns = 0;
148 est->last_inpkts = 0;
149 est->last_outpkts = 0;
150 est->cps = 0;
151 est->inpps = 0;
152 est->outpps = 0;
153 est->inbps = 0;
154 est->outbps = 0;
1da177e4 155}
a919cf4b
SW
156
157int __init ip_vs_estimator_init(void)
158{
159 mod_timer(&est_timer, jiffies + 2 * HZ);
160 return 0;
161}
162
163void ip_vs_estimator_cleanup(void)
164{
165 del_timer_sync(&est_timer);
166}
This page took 0.352793 seconds and 5 git commands to generate.