~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to net/netfilter/ipvs/ip_vs_est.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 *              as published by the Free Software Foundation; either version
9
9
 *              2 of the License, or (at your option) any later version.
10
10
 *
11
 
 * Changes:
12
 
 *
 
11
 * Changes:     Hans Schillstrom <hans.schillstrom@ericsson.com>
 
12
 *              Network name space (netns) aware.
 
13
 *              Global data moved to netns i.e struct netns_ipvs
 
14
 *              Affected data: est_list and est_lock.
 
15
 *              estimation_timer() runs with timer per netns.
 
16
 *              get_stats()) do the per cpu summing.
13
17
 */
14
18
 
15
19
#define KMSG_COMPONENT "IPVS"
48
52
 */
49
53
 
50
54
 
51
 
static void estimation_timer(unsigned long arg);
52
 
 
53
 
static LIST_HEAD(est_list);
54
 
static DEFINE_SPINLOCK(est_lock);
55
 
static DEFINE_TIMER(est_timer, estimation_timer, 0, 0);
 
55
/*
 
56
 * Make a summary from each cpu
 
57
 */
 
58
static void ip_vs_read_cpu_stats(struct ip_vs_stats_user *sum,
 
59
                                 struct ip_vs_cpu_stats *stats)
 
60
{
 
61
        int i;
 
62
 
 
63
        for_each_possible_cpu(i) {
 
64
                struct ip_vs_cpu_stats *s = per_cpu_ptr(stats, i);
 
65
                unsigned int start;
 
66
                __u64 inbytes, outbytes;
 
67
                if (i) {
 
68
                        sum->conns += s->ustats.conns;
 
69
                        sum->inpkts += s->ustats.inpkts;
 
70
                        sum->outpkts += s->ustats.outpkts;
 
71
                        do {
 
72
                                start = u64_stats_fetch_begin(&s->syncp);
 
73
                                inbytes = s->ustats.inbytes;
 
74
                                outbytes = s->ustats.outbytes;
 
75
                        } while (u64_stats_fetch_retry(&s->syncp, start));
 
76
                        sum->inbytes += inbytes;
 
77
                        sum->outbytes += outbytes;
 
78
                } else {
 
79
                        sum->conns = s->ustats.conns;
 
80
                        sum->inpkts = s->ustats.inpkts;
 
81
                        sum->outpkts = s->ustats.outpkts;
 
82
                        do {
 
83
                                start = u64_stats_fetch_begin(&s->syncp);
 
84
                                sum->inbytes = s->ustats.inbytes;
 
85
                                sum->outbytes = s->ustats.outbytes;
 
86
                        } while (u64_stats_fetch_retry(&s->syncp, start));
 
87
                }
 
88
        }
 
89
}
 
90
 
56
91
 
57
92
static void estimation_timer(unsigned long arg)
58
93
{
62
97
        u32 n_inpkts, n_outpkts;
63
98
        u64 n_inbytes, n_outbytes;
64
99
        u32 rate;
 
100
        struct net *net = (struct net *)arg;
 
101
        struct netns_ipvs *ipvs;
65
102
 
66
 
        spin_lock(&est_lock);
67
 
        list_for_each_entry(e, &est_list, list) {
 
103
        ipvs = net_ipvs(net);
 
104
        spin_lock(&ipvs->est_lock);
 
105
        list_for_each_entry(e, &ipvs->est_list, list) {
68
106
                s = container_of(e, struct ip_vs_stats, est);
69
107
 
70
108
                spin_lock(&s->lock);
 
109
                ip_vs_read_cpu_stats(&s->ustats, s->cpustats);
71
110
                n_conns = s->ustats.conns;
72
111
                n_inpkts = s->ustats.inpkts;
73
112
                n_outpkts = s->ustats.outpkts;
75
114
                n_outbytes = s->ustats.outbytes;
76
115
 
77
116
                /* scaled by 2^10, but divided 2 seconds */
78
 
                rate = (n_conns - e->last_conns)<<9;
 
117
                rate = (n_conns - e->last_conns) << 9;
79
118
                e->last_conns = n_conns;
80
 
                e->cps += ((long)rate - (long)e->cps)>>2;
81
 
                s->ustats.cps = (e->cps+0x1FF)>>10;
 
119
                e->cps += ((long)rate - (long)e->cps) >> 2;
82
120
 
83
 
                rate = (n_inpkts - e->last_inpkts)<<9;
 
121
                rate = (n_inpkts - e->last_inpkts) << 9;
84
122
                e->last_inpkts = n_inpkts;
85
 
                e->inpps += ((long)rate - (long)e->inpps)>>2;
86
 
                s->ustats.inpps = (e->inpps+0x1FF)>>10;
 
123
                e->inpps += ((long)rate - (long)e->inpps) >> 2;
87
124
 
88
 
                rate = (n_outpkts - e->last_outpkts)<<9;
 
125
                rate = (n_outpkts - e->last_outpkts) << 9;
89
126
                e->last_outpkts = n_outpkts;
90
 
                e->outpps += ((long)rate - (long)e->outpps)>>2;
91
 
                s->ustats.outpps = (e->outpps+0x1FF)>>10;
 
127
                e->outpps += ((long)rate - (long)e->outpps) >> 2;
92
128
 
93
 
                rate = (n_inbytes - e->last_inbytes)<<4;
 
129
                rate = (n_inbytes - e->last_inbytes) << 4;
94
130
                e->last_inbytes = n_inbytes;
95
 
                e->inbps += ((long)rate - (long)e->inbps)>>2;
96
 
                s->ustats.inbps = (e->inbps+0xF)>>5;
 
131
                e->inbps += ((long)rate - (long)e->inbps) >> 2;
97
132
 
98
 
                rate = (n_outbytes - e->last_outbytes)<<4;
 
133
                rate = (n_outbytes - e->last_outbytes) << 4;
99
134
                e->last_outbytes = n_outbytes;
100
 
                e->outbps += ((long)rate - (long)e->outbps)>>2;
101
 
                s->ustats.outbps = (e->outbps+0xF)>>5;
 
135
                e->outbps += ((long)rate - (long)e->outbps) >> 2;
102
136
                spin_unlock(&s->lock);
103
137
        }
104
 
        spin_unlock(&est_lock);
105
 
        mod_timer(&est_timer, jiffies + 2*HZ);
 
138
        spin_unlock(&ipvs->est_lock);
 
139
        mod_timer(&ipvs->est_timer, jiffies + 2*HZ);
106
140
}
107
141
 
108
 
void ip_vs_new_estimator(struct ip_vs_stats *stats)
 
142
void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats)
109
143
{
 
144
        struct netns_ipvs *ipvs = net_ipvs(net);
110
145
        struct ip_vs_estimator *est = &stats->est;
111
146
 
112
147
        INIT_LIST_HEAD(&est->list);
113
148
 
114
 
        est->last_conns = stats->ustats.conns;
115
 
        est->cps = stats->ustats.cps<<10;
116
 
 
117
 
        est->last_inpkts = stats->ustats.inpkts;
118
 
        est->inpps = stats->ustats.inpps<<10;
119
 
 
120
 
        est->last_outpkts = stats->ustats.outpkts;
121
 
        est->outpps = stats->ustats.outpps<<10;
122
 
 
123
 
        est->last_inbytes = stats->ustats.inbytes;
124
 
        est->inbps = stats->ustats.inbps<<5;
125
 
 
126
 
        est->last_outbytes = stats->ustats.outbytes;
127
 
        est->outbps = stats->ustats.outbps<<5;
128
 
 
129
 
        spin_lock_bh(&est_lock);
130
 
        list_add(&est->list, &est_list);
131
 
        spin_unlock_bh(&est_lock);
 
149
        spin_lock_bh(&ipvs->est_lock);
 
150
        list_add(&est->list, &ipvs->est_list);
 
151
        spin_unlock_bh(&ipvs->est_lock);
132
152
}
133
153
 
134
 
void ip_vs_kill_estimator(struct ip_vs_stats *stats)
 
154
void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats)
135
155
{
 
156
        struct netns_ipvs *ipvs = net_ipvs(net);
136
157
        struct ip_vs_estimator *est = &stats->est;
137
158
 
138
 
        spin_lock_bh(&est_lock);
 
159
        spin_lock_bh(&ipvs->est_lock);
139
160
        list_del(&est->list);
140
 
        spin_unlock_bh(&est_lock);
 
161
        spin_unlock_bh(&ipvs->est_lock);
141
162
}
142
163
 
143
164
void ip_vs_zero_estimator(struct ip_vs_stats *stats)
144
165
{
145
166
        struct ip_vs_estimator *est = &stats->est;
 
167
        struct ip_vs_stats_user *u = &stats->ustats;
146
168
 
147
 
        /* set counters zero, caller must hold the stats->lock lock */
148
 
        est->last_inbytes = 0;
149
 
        est->last_outbytes = 0;
150
 
        est->last_conns = 0;
151
 
        est->last_inpkts = 0;
152
 
        est->last_outpkts = 0;
 
169
        /* reset counters, caller must hold the stats->lock lock */
 
170
        est->last_inbytes = u->inbytes;
 
171
        est->last_outbytes = u->outbytes;
 
172
        est->last_conns = u->conns;
 
173
        est->last_inpkts = u->inpkts;
 
174
        est->last_outpkts = u->outpkts;
153
175
        est->cps = 0;
154
176
        est->inpps = 0;
155
177
        est->outpps = 0;
157
179
        est->outbps = 0;
158
180
}
159
181
 
 
182
/* Get decoded rates */
 
183
void ip_vs_read_estimator(struct ip_vs_stats_user *dst,
 
184
                          struct ip_vs_stats *stats)
 
185
{
 
186
        struct ip_vs_estimator *e = &stats->est;
 
187
 
 
188
        dst->cps = (e->cps + 0x1FF) >> 10;
 
189
        dst->inpps = (e->inpps + 0x1FF) >> 10;
 
190
        dst->outpps = (e->outpps + 0x1FF) >> 10;
 
191
        dst->inbps = (e->inbps + 0xF) >> 5;
 
192
        dst->outbps = (e->outbps + 0xF) >> 5;
 
193
}
 
194
 
 
195
int __net_init __ip_vs_estimator_init(struct net *net)
 
196
{
 
197
        struct netns_ipvs *ipvs = net_ipvs(net);
 
198
 
 
199
        INIT_LIST_HEAD(&ipvs->est_list);
 
200
        spin_lock_init(&ipvs->est_lock);
 
201
        setup_timer(&ipvs->est_timer, estimation_timer, (unsigned long)net);
 
202
        mod_timer(&ipvs->est_timer, jiffies + 2 * HZ);
 
203
        return 0;
 
204
}
 
205
 
 
206
void __net_exit __ip_vs_estimator_cleanup(struct net *net)
 
207
{
 
208
        del_timer_sync(&net_ipvs(net)->est_timer);
 
209
}
 
210
 
160
211
int __init ip_vs_estimator_init(void)
161
212
{
162
 
        mod_timer(&est_timer, jiffies + 2 * HZ);
163
213
        return 0;
164
214
}
165
215
 
166
216
void ip_vs_estimator_cleanup(void)
167
217
{
168
 
        del_timer_sync(&est_timer);
169
218
}