This is a note to let you know that I've just added the patch titled
inetpeer: fix a race in inetpeer_gc_worker()
to the 3.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
inetpeer-fix-a-race-in-inetpeer_gc_worker.patch
and it can be found in the queue-3.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.
>From 71f9c079e7d11d8641590c44f30cc50fe36f0e3f Mon Sep 17 00:00:00 2001
From: Eric Dumazet <[email protected]>
Date: Tue, 5 Jun 2012 03:00:18 +0000
Subject: inetpeer: fix a race in inetpeer_gc_worker()
From: Eric Dumazet <[email protected]>
[ Upstream commit 55432d2b543a4b6dfae54f5c432a566877a85d90 ]
commit 5faa5df1fa2024 (inetpeer: Invalidate the inetpeer tree along with
the routing cache) added a race :
Before freeing an inetpeer, we must respect a RCU grace period, and make
sure no user will attempt to increase refcnt.
inetpeer_invalidate_tree() waits for a RCU grace period before inserting
inetpeer tree into gc_list and waking the worker. At that time, no
concurrent lookup can find a inetpeer in this tree.
Signed-off-by: Eric Dumazet <[email protected]>
Cc: Steffen Klassert <[email protected]>
Acked-by: Steffen Klassert <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/net/inetpeer.h | 5 ++++-
net/ipv4/inetpeer.c | 16 ++++++++++++----
2 files changed, 16 insertions(+), 5 deletions(-)
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -40,7 +40,10 @@ struct inet_peer {
u32 pmtu_orig;
u32 pmtu_learned;
struct inetpeer_addr_base redirect_learned;
- struct list_head gc_list;
+ union {
+ struct list_head gc_list;
+ struct rcu_head gc_rcu;
+ };
/*
* Once inet_peer is queued for deletion (refcnt == -1), following
fields
* are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -560,6 +560,17 @@ bool inet_peer_xrlim_allow(struct inet_p
}
EXPORT_SYMBOL(inet_peer_xrlim_allow);
+static void inetpeer_inval_rcu(struct rcu_head *head)
+{
+ struct inet_peer *p = container_of(head, struct inet_peer, gc_rcu);
+
+ spin_lock_bh(&gc_lock);
+ list_add_tail(&p->gc_list, &gc_list);
+ spin_unlock_bh(&gc_lock);
+
+ schedule_delayed_work(&gc_work, gc_delay);
+}
+
void inetpeer_invalidate_tree(int family)
{
struct inet_peer *old, *new, *prev;
@@ -576,10 +587,7 @@ void inetpeer_invalidate_tree(int family
prev = cmpxchg(&base->root, old, new);
if (prev == old) {
base->total = 0;
- spin_lock(&gc_lock);
- list_add_tail(&prev->gc_list, &gc_list);
- spin_unlock(&gc_lock);
- schedule_delayed_work(&gc_work, gc_delay);
+ call_rcu(&prev->gc_rcu, inetpeer_inval_rcu);
}
out:
Patches currently in stable-queue which might be from [email protected] are
queue-3.4/be2net-fix-a-race-in-be_xmit.patch
queue-3.4/drop_monitor-dont-sleep-in-atomic-context.patch
queue-3.4/lpc_eth-fix-tx-completion.patch
queue-3.4/bonding-fix-corrupted-queue_mapping.patch
queue-3.4/bnx2x-fix-checksum-validation.patch
queue-3.4/net-neighbour-fix-neigh_dump_info.patch
queue-3.4/l2tp-fix-a-race-in-l2tp_ip_sendmsg.patch
queue-3.4/bnx2x-fix-panic-when-tx-ring-is-full.patch
queue-3.4/lpc_eth-add-missing-ndo_change_mtu.patch
queue-3.4/bql-avoid-possible-inconsistent-calculation.patch
queue-3.4/net-remove-skb_orphan_try.patch
queue-3.4/bql-avoid-unneeded-limit-decrement.patch
queue-3.4/netpoll-fix-netpoll_send_udp-bugs.patch
queue-3.4/dummy-fix-rcu_sched-self-detected-stalls.patch
queue-3.4/net-l2tp_eth-fix-kernel-panic-on-rmmod-l2tp_eth.patch
queue-3.4/bql-fix-posdiff-to-integer-overflow-aware.patch
queue-3.4/inetpeer-fix-a-race-in-inetpeer_gc_worker.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html