diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2007-10-15 05:40:06 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-15 15:26:42 -0400 |
commit | 8e7999c44ee95e1e90ac91c83557a04e2948f160 (patch) | |
tree | 4295add7b91114fd43eef37d70b664858776dd0d /net/ipv4 | |
parent | 1e4b82873af0f21002e37a81ef063d2e5410deb3 (diff) |
[INET]: Consolidate the xxx_evictor
The evictors collect some statistics for ipv4 and ipv6,
so make it return the number of evicted queues and account
them all at once in the caller.
The XXX_ADD_STATS_BH() macros are just for this case,
but maybe there are places in code, that can make use of
them as well.
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/inet_fragment.c | 32 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 30 |
2 files changed, 36 insertions, 26 deletions
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 15fb2c4a36a7..484cf512858f 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
@@ -140,3 +140,35 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f, | |||
140 | 140 | ||
141 | } | 141 | } |
142 | EXPORT_SYMBOL(inet_frag_destroy); | 142 | EXPORT_SYMBOL(inet_frag_destroy); |
143 | |||
144 | int inet_frag_evictor(struct inet_frags *f) | ||
145 | { | ||
146 | struct inet_frag_queue *q; | ||
147 | int work, evicted = 0; | ||
148 | |||
149 | work = atomic_read(&f->mem) - f->ctl->low_thresh; | ||
150 | while (work > 0) { | ||
151 | read_lock(&f->lock); | ||
152 | if (list_empty(&f->lru_list)) { | ||
153 | read_unlock(&f->lock); | ||
154 | break; | ||
155 | } | ||
156 | |||
157 | q = list_first_entry(&f->lru_list, | ||
158 | struct inet_frag_queue, lru_list); | ||
159 | atomic_inc(&q->refcnt); | ||
160 | read_unlock(&f->lock); | ||
161 | |||
162 | spin_lock(&q->lock); | ||
163 | if (!(q->last_in & COMPLETE)) | ||
164 | inet_frag_kill(q, f); | ||
165 | spin_unlock(&q->lock); | ||
166 | |||
167 | if (atomic_dec_and_test(&q->refcnt)) | ||
168 | inet_frag_destroy(q, f, &work); | ||
169 | evicted++; | ||
170 | } | ||
171 | |||
172 | return evicted; | ||
173 | } | ||
174 | EXPORT_SYMBOL(inet_frag_evictor); | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index e8736632094a..ee6e04159627 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -174,33 +174,11 @@ static void ipq_kill(struct ipq *ipq) | |||
174 | */ | 174 | */ |
175 | static void ip_evictor(void) | 175 | static void ip_evictor(void) |
176 | { | 176 | { |
177 | struct ipq *qp; | 177 | int evicted; |
178 | struct list_head *tmp; | ||
179 | int work; | ||
180 | |||
181 | work = atomic_read(&ip4_frags.mem) - ip4_frags_ctl.low_thresh; | ||
182 | if (work <= 0) | ||
183 | return; | ||
184 | |||
185 | while (work > 0) { | ||
186 | read_lock(&ip4_frags.lock); | ||
187 | if (list_empty(&ip4_frags.lru_list)) { | ||
188 | read_unlock(&ip4_frags.lock); | ||
189 | return; | ||
190 | } | ||
191 | tmp = ip4_frags.lru_list.next; | ||
192 | qp = list_entry(tmp, struct ipq, q.lru_list); | ||
193 | atomic_inc(&qp->q.refcnt); | ||
194 | read_unlock(&ip4_frags.lock); | ||
195 | 178 | ||
196 | spin_lock(&qp->q.lock); | 179 | evicted = inet_frag_evictor(&ip4_frags); |
197 | if (!(qp->q.last_in&COMPLETE)) | 180 | if (evicted) |
198 | ipq_kill(qp); | 181 | IP_ADD_STATS_BH(IPSTATS_MIB_REASMFAILS, evicted); |
199 | spin_unlock(&qp->q.lock); | ||
200 | |||
201 | ipq_put(qp, &work); | ||
202 | IP_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); | ||
203 | } | ||
204 | } | 182 | } |
205 | 183 | ||
206 | /* | 184 | /* |