diff options
author | Scott Wood <scottwood@freescale.com> | 2013-10-29 20:03:43 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2013-10-29 20:03:43 (GMT) |
commit | ae60d5d27c429b13cf28a09ab8b9d30682433c5a (patch) | |
tree | 16b67511ef66b0580c267a5438d1face3a3778e6 /net/core/dev.c | |
parent | b095c5c2577aeedce2db847fa117596628d4e7cb (diff) | |
parent | d0ebef8230e267ec47d4d4a65fe3262e2ebb8026 (diff) | |
download | linux-fsl-qoriq-ae60d5d27c429b13cf28a09ab8b9d30682433c5a.tar.xz |
Revert to 3.8 (no rt, no stable)
This is a merge from rtmerge, which has been similarly reverted.
Conflicts:
drivers/crypto/caam/caamalg.c
drivers/misc/Makefile
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 113 |
1 files changed, 28 insertions, 85 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 67c8074..147a682 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -203,7 +203,7 @@ static struct list_head offload_base __read_mostly; DEFINE_RWLOCK(dev_base_lock); EXPORT_SYMBOL(dev_base_lock); -DEFINE_MUTEX(devnet_rename_mutex); +seqcount_t devnet_rename_seq; static inline void dev_base_seq_inc(struct net *net) { @@ -225,14 +225,14 @@ static inline struct hlist_head *dev_index_hash(struct net *net, int ifindex) static inline void rps_lock(struct softnet_data *sd) { #ifdef CONFIG_RPS - raw_spin_lock(&sd->input_pkt_queue.raw_lock); + spin_lock(&sd->input_pkt_queue.lock); #endif } static inline void rps_unlock(struct softnet_data *sd) { #ifdef CONFIG_RPS - raw_spin_unlock(&sd->input_pkt_queue.raw_lock); + spin_unlock(&sd->input_pkt_queue.lock); #endif } @@ -1093,11 +1093,10 @@ int dev_change_name(struct net_device *dev, const char *newname) if (dev->flags & IFF_UP) return -EBUSY; - - mutex_lock(&devnet_rename_mutex); + write_seqcount_begin(&devnet_rename_seq); if (strncmp(newname, dev->name, IFNAMSIZ) == 0) { - mutex_unlock(&devnet_rename_mutex); + write_seqcount_end(&devnet_rename_seq); return 0; } @@ -1105,7 +1104,7 @@ int dev_change_name(struct net_device *dev, const char *newname) err = dev_get_valid_name(net, dev, newname); if (err < 0) { - mutex_unlock(&devnet_rename_mutex); + write_seqcount_end(&devnet_rename_seq); return err; } @@ -1113,11 +1112,11 @@ rollback: ret = device_rename(&dev->dev, dev->name); if (ret) { memcpy(dev->name, oldname, IFNAMSIZ); - mutex_unlock(&devnet_rename_mutex); + write_seqcount_end(&devnet_rename_seq); return ret; } - mutex_unlock(&devnet_rename_mutex); + write_seqcount_end(&devnet_rename_seq); write_lock_bh(&dev_base_lock); hlist_del_rcu(&dev->name_hlist); @@ -1136,7 +1135,7 @@ rollback: /* err >= 0 after dev_alloc_name() or stores the first errno */ if (err >= 0) { err = ret; - mutex_lock(&devnet_rename_mutex); + write_seqcount_begin(&devnet_rename_seq); memcpy(dev->name, oldname, IFNAMSIZ); goto rollback; } else { @@ -1592,6 +1591,7 @@ void net_enable_timestamp(void) return; } #endif + WARN_ON(in_interrupt()); static_key_slow_inc(&netstamp_needed); } EXPORT_SYMBOL(net_enable_timestamp); @@ -1738,7 +1738,6 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb) skb->mark = 0; secpath_reset(skb); nf_reset(skb); - nf_reset_trace(skb); return netif_rx(skb); } EXPORT_SYMBOL_GPL(dev_forward_skb); @@ -1947,7 +1946,6 @@ static inline void __netif_reschedule(struct Qdisc *q) sd->output_queue_tailp = &q->next_sched; raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_restore(flags); - preempt_check_resched_rt(); } void __netif_schedule(struct Qdisc *q) @@ -1969,7 +1967,6 @@ void dev_kfree_skb_irq(struct sk_buff *skb) sd->completion_queue = skb; raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_restore(flags); - preempt_check_resched_rt(); } } EXPORT_SYMBOL(dev_kfree_skb_irq); @@ -2021,9 +2018,6 @@ static void skb_warn_bad_offload(const struct sk_buff *skb) struct net_device *dev = skb->dev; const char *driver = ""; - if (!net_ratelimit()) - return; - if (dev && dev->dev.parent) driver = dev_driver_string(dev->dev.parent); @@ -3084,7 +3078,6 @@ enqueue: rps_unlock(sd); local_irq_restore(flags); - preempt_check_resched_rt(); atomic_long_inc(&skb->dev->rx_dropped); kfree_skb(skb); @@ -3122,7 +3115,7 @@ int netif_rx(struct sk_buff *skb) struct rps_dev_flow voidflow, *rflow = &voidflow; int cpu; - migrate_disable(); + preempt_disable(); rcu_read_lock(); cpu = get_rps_cpu(skb->dev, skb, &rflow); @@ -3132,13 +3125,13 @@ int netif_rx(struct sk_buff *skb) ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail); rcu_read_unlock(); - migrate_enable(); + preempt_enable(); } else #endif { unsigned int qtail; - ret = enqueue_to_backlog(skb, get_cpu_light(), &qtail); - put_cpu_light(); + ret = enqueue_to_backlog(skb, get_cpu(), &qtail); + put_cpu(); } return ret; } @@ -3148,44 +3141,16 @@ int netif_rx_ni(struct sk_buff *skb) { int err; - local_bh_disable(); + preempt_disable(); err = netif_rx(skb); - local_bh_enable(); + if (local_softirq_pending()) + do_softirq(); + preempt_enable(); return err; } EXPORT_SYMBOL(netif_rx_ni); -#ifdef CONFIG_PREEMPT_RT_FULL -/* - * RT runs ksoftirqd as a real time thread and the root_lock is a - * "sleeping spinlock". If the trylock fails then we can go into an - * infinite loop when ksoftirqd preempted the task which actually - * holds the lock, because we requeue q and raise NET_TX softirq - * causing ksoftirqd to loop forever. - * - * It's safe to use spin_lock on RT here as softirqs run in thread - * context and cannot deadlock against the thread which is holding - * root_lock. - * - * On !RT the trylock might fail, but there we bail out from the - * softirq loop after 10 attempts which we can't do on RT. And the - * task holding root_lock cannot be preempted, so the only downside of - * that trylock is that we need 10 loops to decide that we should have - * given up in the first one :) - */ -static inline int take_root_lock(spinlock_t *lock) -{ - spin_lock(lock); - return 1; -} -#else -static inline int take_root_lock(spinlock_t *lock) -{ - return spin_trylock(lock); -} -#endif - static void net_tx_action(struct softirq_action *h) { struct softnet_data *sd = &__get_cpu_var(softnet_data); @@ -3224,7 +3189,7 @@ static void net_tx_action(struct softirq_action *h) head = head->next_sched; root_lock = qdisc_lock(q); - if (take_root_lock(root_lock)) { + if (spin_trylock(root_lock)) { smp_mb__before_clear_bit(); clear_bit(__QDISC_STATE_SCHED, &q->state); @@ -3338,7 +3303,6 @@ int netdev_rx_handler_register(struct net_device *dev, if (dev->rx_handler) return -EBUSY; - /* Note: rx_handler_data must be set before rx_handler */ rcu_assign_pointer(dev->rx_handler_data, rx_handler_data); rcu_assign_pointer(dev->rx_handler, rx_handler); @@ -3359,11 +3323,6 @@ void netdev_rx_handler_unregister(struct net_device *dev) ASSERT_RTNL(); RCU_INIT_POINTER(dev->rx_handler, NULL); - /* a reader seeing a non NULL rx_handler in a rcu_read_lock() - * section has a guarantee to see a non NULL rx_handler_data - * as well. - */ - synchronize_net(); RCU_INIT_POINTER(dev->rx_handler_data, NULL); } EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); @@ -3486,7 +3445,6 @@ ncls: } switch (rx_handler(&skb)) { case RX_HANDLER_CONSUMED: - ret = NET_RX_SUCCESS; goto unlock; case RX_HANDLER_ANOTHER: goto another_round; @@ -3595,7 +3553,7 @@ static void flush_backlog(void *arg) skb_queue_walk_safe(&sd->input_pkt_queue, skb, tmp) { if (skb->dev == dev) { __skb_unlink(skb, &sd->input_pkt_queue); - __skb_queue_tail(&sd->tofree_queue, skb); + kfree_skb(skb); input_queue_head_incr(sd); } } @@ -3604,13 +3562,10 @@ static void flush_backlog(void *arg) skb_queue_walk_safe(&sd->process_queue, skb, tmp) { if (skb->dev == dev) { __skb_unlink(skb, &sd->process_queue); - __skb_queue_tail(&sd->tofree_queue, skb); + kfree_skb(skb); input_queue_head_incr(sd); } } - - if (!skb_queue_empty(&sd->tofree_queue)) - raise_softirq_irqoff(NET_RX_SOFTIRQ); } static int napi_gro_complete(struct sk_buff *skb) @@ -3969,7 +3924,6 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd) } else #endif local_irq_enable(); - preempt_check_resched_rt(); } static int process_backlog(struct napi_struct *napi, int quota) @@ -4042,7 +3996,6 @@ void __napi_schedule(struct napi_struct *n) local_irq_save(flags); ____napi_schedule(&__get_cpu_var(softnet_data), n); local_irq_restore(flags); - preempt_check_resched_rt(); } EXPORT_SYMBOL(__napi_schedule); @@ -4117,17 +4070,10 @@ static void net_rx_action(struct softirq_action *h) struct softnet_data *sd = &__get_cpu_var(softnet_data); unsigned long time_limit = jiffies + 2; int budget = netdev_budget; - struct sk_buff *skb; void *have; local_irq_disable(); - while ((skb = __skb_dequeue(&sd->tofree_queue))) { - local_irq_enable(); - kfree_skb(skb); - local_irq_disable(); - } - while (!list_empty(&sd->poll_list)) { struct napi_struct *n; int work, weight; @@ -4250,6 +4196,7 @@ static int dev_ifname(struct net *net, struct ifreq __user *arg) { struct net_device *dev; struct ifreq ifr; + unsigned seq; /* * Fetch the caller's info block. @@ -4258,18 +4205,19 @@ static int dev_ifname(struct net *net, struct ifreq __user *arg) if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) return -EFAULT; - mutex_lock(&devnet_rename_mutex); +retry: + seq = read_seqcount_begin(&devnet_rename_seq); rcu_read_lock(); dev = dev_get_by_index_rcu(net, ifr.ifr_ifindex); if (!dev) { rcu_read_unlock(); - mutex_unlock(&devnet_rename_mutex); return -ENODEV; } strcpy(ifr.ifr_name, dev->name); rcu_read_unlock(); - mutex_unlock(&devnet_rename_mutex); + if (read_seqcount_retry(&devnet_rename_seq, seq)) + goto retry; if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) return -EFAULT; @@ -6597,7 +6545,6 @@ static int dev_cpu_callback(struct notifier_block *nfb, raise_softirq_irqoff(NET_TX_SOFTIRQ); local_irq_enable(); - preempt_check_resched_rt(); /* Process offline CPU's input_pkt_queue */ while ((skb = __skb_dequeue(&oldsd->process_queue))) { @@ -6608,9 +6555,6 @@ static int dev_cpu_callback(struct notifier_block *nfb, netif_rx(skb); input_queue_head_incr(oldsd); } - while ((skb = __skb_dequeue(&oldsd->tofree_queue))) { - kfree_skb(skb); - } return NOTIFY_OK; } @@ -6883,9 +6827,8 @@ static int __init net_dev_init(void) struct softnet_data *sd = &per_cpu(softnet_data, i); memset(sd, 0, sizeof(*sd)); - skb_queue_head_init_raw(&sd->input_pkt_queue); - skb_queue_head_init_raw(&sd->process_queue); - skb_queue_head_init_raw(&sd->tofree_queue); + skb_queue_head_init(&sd->input_pkt_queue); + skb_queue_head_init(&sd->process_queue); sd->completion_queue = NULL; INIT_LIST_HEAD(&sd->poll_list); sd->output_queue = NULL; |