Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux-2.6-block.git] / net / core / dev.c
index 068b60db35aedeb3730ae06e61c0f67bad4bbb49..7542848733554c33b79a433de2597c2c8933bc2f 100644 (file)
@@ -2187,6 +2187,20 @@ static bool remove_xps_queue_cpu(struct net_device *dev,
        return active;
 }
 
+static void reset_xps_maps(struct net_device *dev,
+                          struct xps_dev_maps *dev_maps,
+                          bool is_rxqs_map)
+{
+       if (is_rxqs_map) {
+               static_key_slow_dec_cpuslocked(&xps_rxqs_needed);
+               RCU_INIT_POINTER(dev->xps_rxqs_map, NULL);
+       } else {
+               RCU_INIT_POINTER(dev->xps_cpus_map, NULL);
+       }
+       static_key_slow_dec_cpuslocked(&xps_needed);
+       kfree_rcu(dev_maps, rcu);
+}
+
 static void clean_xps_maps(struct net_device *dev, const unsigned long *mask,
                           struct xps_dev_maps *dev_maps, unsigned int nr_ids,
                           u16 offset, u16 count, bool is_rxqs_map)
@@ -2198,18 +2212,15 @@ static void clean_xps_maps(struct net_device *dev, const unsigned long *mask,
             j < nr_ids;)
                active |= remove_xps_queue_cpu(dev, dev_maps, j, offset,
                                               count);
-       if (!active) {
-               if (is_rxqs_map) {
-                       RCU_INIT_POINTER(dev->xps_rxqs_map, NULL);
-               } else {
-                       RCU_INIT_POINTER(dev->xps_cpus_map, NULL);
+       if (!active)
+               reset_xps_maps(dev, dev_maps, is_rxqs_map);
 
-                       for (i = offset + (count - 1); count--; i--)
-                               netdev_queue_numa_node_write(
-                                       netdev_get_tx_queue(dev, i),
-                                                       NUMA_NO_NODE);
+       if (!is_rxqs_map) {
+               for (i = offset + (count - 1); count--; i--) {
+                       netdev_queue_numa_node_write(
+                               netdev_get_tx_queue(dev, i),
+                               NUMA_NO_NODE);
                }
-               kfree_rcu(dev_maps, rcu);
        }
 }
 
@@ -2246,10 +2257,6 @@ static void netif_reset_xps_queues(struct net_device *dev, u16 offset,
                       false);
 
 out_no_maps:
-       if (static_key_enabled(&xps_rxqs_needed))
-               static_key_slow_dec_cpuslocked(&xps_rxqs_needed);
-
-       static_key_slow_dec_cpuslocked(&xps_needed);
        mutex_unlock(&xps_map_mutex);
        cpus_read_unlock();
 }
@@ -2367,9 +2374,12 @@ int __netif_set_xps_queue(struct net_device *dev, const unsigned long *mask,
        if (!new_dev_maps)
                goto out_no_new_maps;
 
-       static_key_slow_inc_cpuslocked(&xps_needed);
-       if (is_rxqs_map)
-               static_key_slow_inc_cpuslocked(&xps_rxqs_needed);
+       if (!dev_maps) {
+               /* Increment static keys at most once per type */
+               static_key_slow_inc_cpuslocked(&xps_needed);
+               if (is_rxqs_map)
+                       static_key_slow_inc_cpuslocked(&xps_rxqs_needed);
+       }
 
        for (j = -1; j = netif_attrmask_next(j, possible_mask, nr_ids),
             j < nr_ids;) {
@@ -2467,13 +2477,8 @@ out_no_new_maps:
        }
 
        /* free map if not active */
-       if (!active) {
-               if (is_rxqs_map)
-                       RCU_INIT_POINTER(dev->xps_rxqs_map, NULL);
-               else
-                       RCU_INIT_POINTER(dev->xps_cpus_map, NULL);
-               kfree_rcu(dev_maps, rcu);
-       }
+       if (!active)
+               reset_xps_maps(dev, dev_maps, is_rxqs_map);
 
 out_no_maps:
        mutex_unlock(&xps_map_mutex);
@@ -5034,7 +5039,7 @@ static void __netif_receive_skb_list_core(struct list_head *head, bool pfmemallo
                struct net_device *orig_dev = skb->dev;
                struct packet_type *pt_prev = NULL;
 
-               list_del(&skb->list);
+               skb_list_del_init(skb);
                __netif_receive_skb_core(skb, pfmemalloc, &pt_prev);
                if (!pt_prev)
                        continue;
@@ -5190,7 +5195,7 @@ static void netif_receive_skb_list_internal(struct list_head *head)
        INIT_LIST_HEAD(&sublist);
        list_for_each_entry_safe(skb, next, head, list) {
                net_timestamp_check(netdev_tstamp_prequeue, skb);
-               list_del(&skb->list);
+               skb_list_del_init(skb);
                if (!skb_defer_rx_timestamp(skb))
                        list_add_tail(&skb->list, &sublist);
        }
@@ -5201,7 +5206,7 @@ static void netif_receive_skb_list_internal(struct list_head *head)
                rcu_read_lock();
                list_for_each_entry_safe(skb, next, head, list) {
                        xdp_prog = rcu_dereference(skb->dev->xdp_prog);
-                       list_del(&skb->list);
+                       skb_list_del_init(skb);
                        if (do_xdp_generic(xdp_prog, skb) == XDP_PASS)
                                list_add_tail(&skb->list, &sublist);
                }
@@ -5220,7 +5225,7 @@ static void netif_receive_skb_list_internal(struct list_head *head)
 
                        if (cpu >= 0) {
                                /* Will be handled, remove from list */
-                               list_del(&skb->list);
+                               skb_list_del_init(skb);
                                enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
                        }
                }
@@ -6251,8 +6256,8 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
        napi->skb = NULL;
        napi->poll = poll;
        if (weight > NAPI_POLL_WEIGHT)
-               pr_err_once("netif_napi_add() called with weight %d on device %s\n",
-                           weight, dev->name);
+               netdev_err_once(dev, "%s() called with weight %d\n", __func__,
+                               weight);
        napi->weight = weight;
        list_add(&napi->dev_list, &dev->napi_list);
        napi->dev = dev;