aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 22:25:39 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 22:25:39 -0400
commitac694dbdbc403c00e2c14d10bc7b8412cc378259 (patch)
treee37328cfbeaf43716dd5914cad9179e57e84df76 /net/core/dev.c
parenta40a1d3d0a2fd613fdec6d89d3c053268ced76ed (diff)
parent437ea90cc3afdca5229b41c6b1d38c4842756cb9 (diff)
Merge branch 'akpm' (Andrew's patch-bomb)
Merge Andrew's second set of patches: - MM - a few random fixes - a couple of RTC leftovers * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (120 commits) rtc/rtc-88pm80x: remove unneed devm_kfree rtc/rtc-88pm80x: assign ret only when rtc_register_driver fails mm: hugetlbfs: close race during teardown of hugetlbfs shared page tables tmpfs: distribute interleave better across nodes mm: remove redundant initialization mm: warn if pg_data_t isn't initialized with zero mips: zero out pg_data_t when it's allocated memcg: gix memory accounting scalability in shrink_page_list mm/sparse: remove index_init_lock mm/sparse: more checks on mem_section number mm/sparse: optimize sparse_index_alloc memcg: add mem_cgroup_from_css() helper memcg: further prevent OOM with too many dirty pages memcg: prevent OOM with too many dirty pages mm: mmu_notifier: fix freed page still mapped in secondary MMU mm: memcg: only check anon swapin page charges for swap cache mm: memcg: only check swap cache pages for repeated charging mm: memcg: split swapin charge function into private and public part mm: memcg: remove needless !mm fixup to init_mm when charging mm: memcg: remove unneeded shmem charge type ...
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c53
1 files changed, 47 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index c8569f826b71..0cb3fe8d8e72 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3156,6 +3156,23 @@ void netdev_rx_handler_unregister(struct net_device *dev)
3156} 3156}
3157EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); 3157EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
3158 3158
3159/*
3160 * Limit the use of PFMEMALLOC reserves to those protocols that implement
3161 * the special handling of PFMEMALLOC skbs.
3162 */
3163static bool skb_pfmemalloc_protocol(struct sk_buff *skb)
3164{
3165 switch (skb->protocol) {
3166 case __constant_htons(ETH_P_ARP):
3167 case __constant_htons(ETH_P_IP):
3168 case __constant_htons(ETH_P_IPV6):
3169 case __constant_htons(ETH_P_8021Q):
3170 return true;
3171 default:
3172 return false;
3173 }
3174}
3175
3159static int __netif_receive_skb(struct sk_buff *skb) 3176static int __netif_receive_skb(struct sk_buff *skb)
3160{ 3177{
3161 struct packet_type *ptype, *pt_prev; 3178 struct packet_type *ptype, *pt_prev;
@@ -3165,14 +3182,27 @@ static int __netif_receive_skb(struct sk_buff *skb)
3165 bool deliver_exact = false; 3182 bool deliver_exact = false;
3166 int ret = NET_RX_DROP; 3183 int ret = NET_RX_DROP;
3167 __be16 type; 3184 __be16 type;
3185 unsigned long pflags = current->flags;
3168 3186
3169 net_timestamp_check(!netdev_tstamp_prequeue, skb); 3187 net_timestamp_check(!netdev_tstamp_prequeue, skb);
3170 3188
3171 trace_netif_receive_skb(skb); 3189 trace_netif_receive_skb(skb);
3172 3190
3191 /*
3192 * PFMEMALLOC skbs are special, they should
3193 * - be delivered to SOCK_MEMALLOC sockets only
3194 * - stay away from userspace
3195 * - have bounded memory usage
3196 *
3197 * Use PF_MEMALLOC as this saves us from propagating the allocation
3198 * context down to all allocation sites.
3199 */
3200 if (sk_memalloc_socks() && skb_pfmemalloc(skb))
3201 current->flags |= PF_MEMALLOC;
3202
3173 /* if we've gotten here through NAPI, check netpoll */ 3203 /* if we've gotten here through NAPI, check netpoll */
3174 if (netpoll_receive_skb(skb)) 3204 if (netpoll_receive_skb(skb))
3175 return NET_RX_DROP; 3205 goto out;
3176 3206
3177 orig_dev = skb->dev; 3207 orig_dev = skb->dev;
3178 3208
@@ -3192,7 +3222,7 @@ another_round:
3192 if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { 3222 if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) {
3193 skb = vlan_untag(skb); 3223 skb = vlan_untag(skb);
3194 if (unlikely(!skb)) 3224 if (unlikely(!skb))
3195 goto out; 3225 goto unlock;
3196 } 3226 }
3197 3227
3198#ifdef CONFIG_NET_CLS_ACT 3228#ifdef CONFIG_NET_CLS_ACT
@@ -3202,6 +3232,9 @@ another_round:
3202 } 3232 }
3203#endif 3233#endif
3204 3234
3235 if (sk_memalloc_socks() && skb_pfmemalloc(skb))
3236 goto skip_taps;
3237
3205 list_for_each_entry_rcu(ptype, &ptype_all, list) { 3238 list_for_each_entry_rcu(ptype, &ptype_all, list) {
3206 if (!ptype->dev || ptype->dev == skb->dev) { 3239 if (!ptype->dev || ptype->dev == skb->dev) {
3207 if (pt_prev) 3240 if (pt_prev)
@@ -3210,13 +3243,18 @@ another_round:
3210 } 3243 }
3211 } 3244 }
3212 3245
3246skip_taps:
3213#ifdef CONFIG_NET_CLS_ACT 3247#ifdef CONFIG_NET_CLS_ACT
3214 skb = handle_ing(skb, &pt_prev, &ret, orig_dev); 3248 skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
3215 if (!skb) 3249 if (!skb)
3216 goto out; 3250 goto unlock;
3217ncls: 3251ncls:
3218#endif 3252#endif
3219 3253
3254 if (sk_memalloc_socks() && skb_pfmemalloc(skb)
3255 && !skb_pfmemalloc_protocol(skb))
3256 goto drop;
3257
3220 rx_handler = rcu_dereference(skb->dev->rx_handler); 3258 rx_handler = rcu_dereference(skb->dev->rx_handler);
3221 if (vlan_tx_tag_present(skb)) { 3259 if (vlan_tx_tag_present(skb)) {
3222 if (pt_prev) { 3260 if (pt_prev) {
@@ -3226,7 +3264,7 @@ ncls:
3226 if (vlan_do_receive(&skb, !rx_handler)) 3264 if (vlan_do_receive(&skb, !rx_handler))
3227 goto another_round; 3265 goto another_round;
3228 else if (unlikely(!skb)) 3266 else if (unlikely(!skb))
3229 goto out; 3267 goto unlock;
3230 } 3268 }
3231 3269
3232 if (rx_handler) { 3270 if (rx_handler) {
@@ -3236,7 +3274,7 @@ ncls:
3236 } 3274 }
3237 switch (rx_handler(&skb)) { 3275 switch (rx_handler(&skb)) {
3238 case RX_HANDLER_CONSUMED: 3276 case RX_HANDLER_CONSUMED:
3239 goto out; 3277 goto unlock;
3240 case RX_HANDLER_ANOTHER: 3278 case RX_HANDLER_ANOTHER:
3241 goto another_round; 3279 goto another_round;
3242 case RX_HANDLER_EXACT: 3280 case RX_HANDLER_EXACT:
@@ -3269,6 +3307,7 @@ ncls:
3269 else 3307 else
3270 ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); 3308 ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
3271 } else { 3309 } else {
3310drop:
3272 atomic_long_inc(&skb->dev->rx_dropped); 3311 atomic_long_inc(&skb->dev->rx_dropped);
3273 kfree_skb(skb); 3312 kfree_skb(skb);
3274 /* Jamal, now you will not able to escape explaining 3313 /* Jamal, now you will not able to escape explaining
@@ -3277,8 +3316,10 @@ ncls:
3277 ret = NET_RX_DROP; 3316 ret = NET_RX_DROP;
3278 } 3317 }
3279 3318
3280out: 3319unlock:
3281 rcu_read_unlock(); 3320 rcu_read_unlock();
3321out:
3322 tsk_restore_flags(current, pflags, PF_MEMALLOC);
3282 return ret; 3323 return ret;
3283} 3324}
3284 3325