diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-30 11:08:40 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-30 11:08:40 -0400 |
| commit | 2d175d438f297bcd75a7b88baf3a304137047af6 (patch) | |
| tree | 22fa745d13f85dd8fd74bb35ba0e3bf01cab12f8 /net/core/netpoll.c | |
| parent | c2db6376c934b9e4c0b905bee5222d5475bbd98a (diff) | |
| parent | 502ef38da15d817f8e67acefc12dc2212f7f8aa1 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
[TIPC]: Add tipc_config.h to include/linux/Kbuild.
[WAN]: lmc_ioctl: don't return with locks held
[SUNRPC]: fix rpc debugging
[TCP]: Saner thash_entries default with much memory.
[SUNRPC] rpc_rdma: we need to cast u64 to unsigned long long for printing
[IPv4] SNMP: Refer correct memory location to display ICMP out-going statistics
[NET]: Fix error reporting in sys_socketpair().
[NETFILTER]: nf_ct_alloc_hashtable(): use __GFP_NOWARN
[NET]: Fix race between poll_napi() and net_rx_action()
[TCP] MD5: Remove some more unnecessary casting.
[TCP] vegas: Fix a bug in disabling slow start by gamma parameter.
[IPVS]: use proper timeout instead of fixed value
[IPV6] NDISC: Fix setting base_reachable_time_ms variable.
Diffstat (limited to 'net/core/netpoll.c')
| -rw-r--r-- | net/core/netpoll.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index bf8d18f1b013..c499b5c69bed 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
| @@ -116,6 +116,29 @@ static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh, | |||
| 116 | * network adapter, forcing superfluous retries and possibly timeouts. | 116 | * network adapter, forcing superfluous retries and possibly timeouts. |
| 117 | * Thus, we set our budget to greater than 1. | 117 | * Thus, we set our budget to greater than 1. |
| 118 | */ | 118 | */ |
| 119 | static int poll_one_napi(struct netpoll_info *npinfo, | ||
| 120 | struct napi_struct *napi, int budget) | ||
| 121 | { | ||
| 122 | int work; | ||
| 123 | |||
| 124 | /* net_rx_action's ->poll() invocations and our's are | ||
| 125 | * synchronized by this test which is only made while | ||
| 126 | * holding the napi->poll_lock. | ||
| 127 | */ | ||
| 128 | if (!test_bit(NAPI_STATE_SCHED, &napi->state)) | ||
| 129 | return budget; | ||
| 130 | |||
| 131 | npinfo->rx_flags |= NETPOLL_RX_DROP; | ||
| 132 | atomic_inc(&trapped); | ||
| 133 | |||
| 134 | work = napi->poll(napi, budget); | ||
| 135 | |||
| 136 | atomic_dec(&trapped); | ||
| 137 | npinfo->rx_flags &= ~NETPOLL_RX_DROP; | ||
| 138 | |||
| 139 | return budget - work; | ||
| 140 | } | ||
| 141 | |||
| 119 | static void poll_napi(struct netpoll *np) | 142 | static void poll_napi(struct netpoll *np) |
| 120 | { | 143 | { |
| 121 | struct netpoll_info *npinfo = np->dev->npinfo; | 144 | struct netpoll_info *npinfo = np->dev->npinfo; |
| @@ -123,17 +146,13 @@ static void poll_napi(struct netpoll *np) | |||
| 123 | int budget = 16; | 146 | int budget = 16; |
| 124 | 147 | ||
| 125 | list_for_each_entry(napi, &np->dev->napi_list, dev_list) { | 148 | list_for_each_entry(napi, &np->dev->napi_list, dev_list) { |
| 126 | if (test_bit(NAPI_STATE_SCHED, &napi->state) && | 149 | if (napi->poll_owner != smp_processor_id() && |
| 127 | napi->poll_owner != smp_processor_id() && | ||
| 128 | spin_trylock(&napi->poll_lock)) { | 150 | spin_trylock(&napi->poll_lock)) { |
| 129 | npinfo->rx_flags |= NETPOLL_RX_DROP; | 151 | budget = poll_one_napi(npinfo, napi, budget); |
| 130 | atomic_inc(&trapped); | ||
| 131 | |||
| 132 | napi->poll(napi, budget); | ||
| 133 | |||
| 134 | atomic_dec(&trapped); | ||
| 135 | npinfo->rx_flags &= ~NETPOLL_RX_DROP; | ||
| 136 | spin_unlock(&napi->poll_lock); | 152 | spin_unlock(&napi->poll_lock); |
| 153 | |||
| 154 | if (!budget) | ||
| 155 | break; | ||
| 137 | } | 156 | } |
| 138 | } | 157 | } |
| 139 | } | 158 | } |
