aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-15 05:40:06 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-15 15:26:42 -0400
commit8e7999c44ee95e1e90ac91c83557a04e2948f160 (patch)
tree4295add7b91114fd43eef37d70b664858776dd0d /net/ipv4
parent1e4b82873af0f21002e37a81ef063d2e5410deb3 (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.c32
-rw-r--r--net/ipv4/ip_fragment.c30
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}
142EXPORT_SYMBOL(inet_frag_destroy); 142EXPORT_SYMBOL(inet_frag_destroy);
143
144int 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}
174EXPORT_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 */
175static void ip_evictor(void) 175static 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/*