From 29578624e354f56143d92510fff33a8b2aaa2c03 Mon Sep 17 00:00:00 2001 From: Olaf Kirch Date: Wed, 11 Jul 2007 19:32:02 -0700 Subject: [NET]: Fix races in net_rx_action vs netpoll. Keep netpoll/poll_napi from messing with the poll_list. Only net_rx_action is allowed to manipulate the list. Signed-off-by: Olaf Kirch Signed-off-by: David S. Miller --- net/core/netpoll.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'net/core/netpoll.c') diff --git a/net/core/netpoll.c b/net/core/netpoll.c index de1b26aa572..d1264e9a50a 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -124,6 +124,13 @@ static void poll_napi(struct netpoll *np) if (test_bit(__LINK_STATE_RX_SCHED, &np->dev->state) && npinfo->poll_owner != smp_processor_id() && spin_trylock(&npinfo->poll_lock)) { + /* When calling dev->poll from poll_napi, we may end up in + * netif_rx_complete. However, only the CPU to which the + * device was queued is allowed to remove it from poll_list. + * Setting POLL_LIST_FROZEN tells netif_rx_complete + * to leave the NAPI state alone. + */ + set_bit(__LINK_STATE_POLL_LIST_FROZEN, &np->dev->state); npinfo->rx_flags |= NETPOLL_RX_DROP; atomic_inc(&trapped); @@ -131,6 +138,7 @@ static void poll_napi(struct netpoll *np) atomic_dec(&trapped); npinfo->rx_flags &= ~NETPOLL_RX_DROP; + clear_bit(__LINK_STATE_POLL_LIST_FROZEN, &np->dev->state); spin_unlock(&npinfo->poll_lock); } } -- cgit v1.2.3