OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [ipv4/] [ipvs/] [ip_vs_est.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * ip_vs_est.c  Simple rate estimator for IPVS
3
 *
4
 * Version:     $Id: ip_vs_est.c,v 1.1.1.1 2004-04-15 01:14:05 phoenix Exp $
5
 *
6
 * Authors:     Wensong Zhang <wensong@linuxvirtualserver.org>
7
 *
8
 *              This program is free software; you can redistribute it and/or
9
 *              modify it under the terms of the GNU General Public License
10
 *              as published by the Free Software Foundation; either version
11
 *              2 of the License, or (at your option) any later version.
12
 *
13
 * Changes:
14
 *
15
 */
16
#include <linux/kernel.h>
17
#include <linux/types.h>
18
 
19
#include <net/ip_vs.h>
20
 
21
/*
22
  This code is to estimate rate in a shorter interval (such as 8
23
  seconds) for virtual services and real servers. For measure rate in a
24
  long interval, it is easy to implement a user level daemon which
25
  periodically reads those statistical counters and measure rate.
26
 
27
  Currently, the measurement is activated by slow timer handler. Hope
28
  this measurement will not introduce too much load.
29
 
30
  We measure rate during the last 8 seconds every 2 seconds:
31
 
32
    avgrate = avgrate*(1-W) + rate*W
33
 
34
    where W = 2^(-2)
35
 
36
  NOTES.
37
 
38
  * The stored value for average bps is scaled by 2^5, so that maximal
39
    rate is ~2.15Gbits/s, average pps and cps are scaled by 2^10.
40
 
41
  * A lot code is taken from net/sched/estimator.c
42
 */
43
 
44
 
45
struct ip_vs_estimator
46
{
47
        struct ip_vs_estimator  *next;
48
        struct ip_vs_stats      *stats;
49
 
50
        u32                     last_conns;
51
        u32                     last_inpkts;
52
        u32                     last_outpkts;
53
        u64                     last_inbytes;
54
        u64                     last_outbytes;
55
 
56
        u32                     cps;
57
        u32                     inpps;
58
        u32                     outpps;
59
        u32                     inbps;
60
        u32                     outbps;
61
};
62
 
63
 
64
static struct ip_vs_estimator *est_list = NULL;
65
static rwlock_t est_lock = RW_LOCK_UNLOCKED;
66
static struct timer_list est_timer;
67
 
68
static void estimation_timer(unsigned long arg)
69
{
70
        struct ip_vs_estimator *e;
71
        struct ip_vs_stats *s;
72
        u32 n_conns;
73
        u32 n_inpkts, n_outpkts;
74
        u64 n_inbytes, n_outbytes;
75
        u32 rate;
76
 
77
        read_lock(&est_lock);
78
        for (e = est_list; e; e = e->next) {
79
                s = e->stats;
80
 
81
                spin_lock(&s->lock);
82
                n_conns = s->conns;
83
                n_inpkts = s->inpkts;
84
                n_outpkts = s->outpkts;
85
                n_inbytes = s->inbytes;
86
                n_outbytes = s->outbytes;
87
 
88
                /* scaled by 2^10, but divided 2 seconds */
89
                rate = (n_conns - e->last_conns)<<9;
90
                e->last_conns = n_conns;
91
                e->cps += ((long)rate - (long)e->cps)>>2;
92
                s->cps = (e->cps+0x1FF)>>10;
93
 
94
                rate = (n_inpkts - e->last_inpkts)<<9;
95
                e->last_inpkts = n_inpkts;
96
                e->inpps += ((long)rate - (long)e->inpps)>>2;
97
                s->inpps = (e->inpps+0x1FF)>>10;
98
 
99
                rate = (n_outpkts - e->last_outpkts)<<9;
100
                e->last_outpkts = n_outpkts;
101
                e->outpps += ((long)rate - (long)e->outpps)>>2;
102
                s->outpps = (e->outpps+0x1FF)>>10;
103
 
104
                rate = (n_inbytes - e->last_inbytes)<<4;
105
                e->last_inbytes = n_inbytes;
106
                e->inbps += ((long)rate - (long)e->inbps)>>2;
107
                s->inbps = (e->inbps+0xF)>>5;
108
 
109
                rate = (n_outbytes - e->last_outbytes)<<4;
110
                e->last_outbytes = n_outbytes;
111
                e->outbps += ((long)rate - (long)e->outbps)>>2;
112
                s->outbps = (e->outbps+0xF)>>5;
113
                spin_unlock(&s->lock);
114
        }
115
        read_unlock(&est_lock);
116
        mod_timer(&est_timer, jiffies + 2*HZ);
117
}
118
 
119
int ip_vs_new_estimator(struct ip_vs_stats *stats)
120
{
121
        struct ip_vs_estimator *est;
122
 
123
        est = kmalloc(sizeof(*est), GFP_KERNEL);
124
        if (est == NULL)
125
                return -ENOMEM;
126
 
127
        memset(est, 0, sizeof(*est));
128
        est->stats = stats;
129
        est->last_conns = stats->conns;
130
        est->cps = stats->cps<<10;
131
 
132
        est->last_inpkts = stats->inpkts;
133
        est->inpps = stats->inpps<<10;
134
 
135
        est->last_outpkts = stats->outpkts;
136
        est->outpps = stats->outpps<<10;
137
 
138
        est->last_inbytes = stats->inbytes;
139
        est->inbps = stats->inbps<<5;
140
 
141
        est->last_outbytes = stats->outbytes;
142
        est->outbps = stats->outbps<<5;
143
 
144
        est->next = est_list;
145
        if (est->next == NULL) {
146
                init_timer(&est_timer);
147
                est_timer.expires = jiffies + 2*HZ;
148
                est_timer.function = estimation_timer;
149
                add_timer(&est_timer);
150
        }
151
        write_lock_bh(&est_lock);
152
        est_list = est;
153
        write_unlock_bh(&est_lock);
154
        return 0;
155
}
156
 
157
void ip_vs_kill_estimator(struct ip_vs_stats *stats)
158
{
159
        struct ip_vs_estimator *est, **pest;
160
        int killed = 0;
161
 
162
        write_lock_bh(&est_lock);
163
        pest = &est_list;
164
        while ((est=*pest) != NULL) {
165
                if (est->stats != stats) {
166
                        pest = &est->next;
167
                        continue;
168
                }
169
                *pest = est->next;
170
                kfree(est);
171
                killed++;
172
        }
173
        if (killed && est_list == NULL)
174
                del_timer_sync(&est_timer);
175
        write_unlock_bh(&est_lock);
176
}
177
 
178
void ip_vs_zero_estimator(struct ip_vs_stats *stats)
179
{
180
        struct ip_vs_estimator *e;
181
 
182
        write_lock_bh(&est_lock);
183
        for (e = est_list; e; e = e->next) {
184
                if (e->stats != stats)
185
                        continue;
186
 
187
                /* set counters zero */
188
                e->last_conns = 0;
189
                e->last_inpkts = 0;
190
                e->last_outpkts = 0;
191
                e->last_inbytes = 0;
192
                e->last_outbytes = 0;
193
                e->cps = 0;
194
                e->inpps = 0;
195
                e->outpps = 0;
196
                e->inbps = 0;
197
                e->outbps = 0;
198
        }
199
        write_unlock_bh(&est_lock);
200
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.