Ignore:
Timestamp:
Apr 16, 2017, 3:07:01 PM (3 months ago)
Author:
brainslayer
Message:

update

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-3.18/net/core/dev.c

    r31168 r31869  
    16191619static struct static_key netstamp_needed __read_mostly;
    16201620#ifdef HAVE_JUMP_LABEL
    1621 /* We are not allowed to call static_key_slow_dec() from irq context
    1622  * If net_disable_timestamp() is called from irq context, defer the
    1623  * static_key_slow_dec() calls.
    1624  */
    16251621static atomic_t netstamp_needed_deferred;
     1622static void netstamp_clear(struct work_struct *work)
     1623{
     1624        int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
     1625
     1626        while (deferred--)
     1627                static_key_slow_dec(&netstamp_needed);
     1628}
     1629static DECLARE_WORK(netstamp_work, netstamp_clear);
    16261630#endif
    16271631
    16281632void net_enable_timestamp(void)
    16291633{
     1634        static_key_slow_inc(&netstamp_needed);
     1635}
     1636EXPORT_SYMBOL(net_enable_timestamp);
     1637
     1638void net_disable_timestamp(void)
     1639{
    16301640#ifdef HAVE_JUMP_LABEL
    1631         int deferred = atomic_xchg(&netstamp_needed_deferred, 0);
    1632 
    1633         if (deferred) {
    1634                 while (--deferred)
    1635                         static_key_slow_dec(&netstamp_needed);
    1636                 return;
    1637         }
     1641        /* net_disable_timestamp() can be called from non process context */
     1642        atomic_inc(&netstamp_needed_deferred);
     1643        schedule_work(&netstamp_work);
     1644#else
     1645        static_key_slow_dec(&netstamp_needed);
    16381646#endif
    1639         static_key_slow_inc(&netstamp_needed);
    1640 }
    1641 EXPORT_SYMBOL(net_enable_timestamp);
    1642 
    1643 void net_disable_timestamp(void)
    1644 {
    1645 #ifdef HAVE_JUMP_LABEL
    1646         if (in_interrupt()) {
    1647                 atomic_inc(&netstamp_needed_deferred);
    1648                 return;
    1649         }
    1650 #endif
    1651         static_key_slow_dec(&netstamp_needed);
    16521647}
    16531648EXPORT_SYMBOL(net_disable_timestamp);
     
    27672762        return head;
    27682763}
     2764EXPORT_SYMBOL_GPL(validate_xmit_skb_list);
    27692765
    27702766static void qdisc_pkt_len_init(struct sk_buff *skb)
     
    49214917static int __netdev_adjacent_dev_insert(struct net_device *dev,
    49224918                                        struct net_device *adj_dev,
     4919                                        u16 ref_nr,
    49234920                                        struct list_head *dev_list,
    49244921                                        void *private, bool master)
     
    49304927
    49314928        if (adj) {
    4932                 adj->ref_nr++;
     4929                adj->ref_nr += ref_nr;
    49334930                return 0;
    49344931        }
     
    49404937        adj->dev = adj_dev;
    49414938        adj->master = master;
    4942         adj->ref_nr = 1;
     4939        adj->ref_nr = ref_nr;
    49434940        adj->private = private;
    49444941        dev_hold(adj_dev);
     
    49794976static void __netdev_adjacent_dev_remove(struct net_device *dev,
    49804977                                         struct net_device *adj_dev,
     4978                                         u16 ref_nr,
    49814979                                         struct list_head *dev_list)
    49824980{
     
    49914989        }
    49924990
    4993         if (adj->ref_nr > 1) {
    4994                 pr_debug("%s to %s ref_nr-- = %d\n", dev->name, adj_dev->name,
    4995                          adj->ref_nr-1);
    4996                 adj->ref_nr--;
     4991        if (adj->ref_nr > ref_nr) {
     4992                pr_debug("%s to %s ref_nr-%d = %d\n", dev->name, adj_dev->name,
     4993                         ref_nr, adj->ref_nr-ref_nr);
     4994                adj->ref_nr -= ref_nr;
    49974995                return;
    49984996        }
     
    50135011static int __netdev_adjacent_dev_link_lists(struct net_device *dev,
    50145012                                            struct net_device *upper_dev,
     5013                                            u16 ref_nr,
    50155014                                            struct list_head *up_list,
    50165015                                            struct list_head *down_list,
     
    50195018        int ret;
    50205019
    5021         ret = __netdev_adjacent_dev_insert(dev, upper_dev, up_list, private,
    5022                                            master);
     5020        ret = __netdev_adjacent_dev_insert(dev, upper_dev, ref_nr, up_list,
     5021                                           private, master);
    50235022        if (ret)
    50245023                return ret;
    50255024
    5026         ret = __netdev_adjacent_dev_insert(upper_dev, dev, down_list, private,
    5027                                            false);
     5025        ret = __netdev_adjacent_dev_insert(upper_dev, dev, ref_nr, down_list,
     5026                                           private, false);
    50285027        if (ret) {
    5029                 __netdev_adjacent_dev_remove(dev, upper_dev, up_list);
     5028                __netdev_adjacent_dev_remove(dev, upper_dev, ref_nr, up_list);
    50305029                return ret;
    50315030        }
     
    50355034
    50365035static int __netdev_adjacent_dev_link(struct net_device *dev,
    5037                                       struct net_device *upper_dev)
    5038 {
    5039         return __netdev_adjacent_dev_link_lists(dev, upper_dev,
     5036                                      struct net_device *upper_dev,
     5037                                      u16 ref_nr)
     5038{
     5039        return __netdev_adjacent_dev_link_lists(dev, upper_dev, ref_nr,
    50405040                                                &dev->all_adj_list.upper,
    50415041                                                &upper_dev->all_adj_list.lower,
     
    50455045static void __netdev_adjacent_dev_unlink_lists(struct net_device *dev,
    50465046                                               struct net_device *upper_dev,
     5047                                               u16 ref_nr,
    50475048                                               struct list_head *up_list,
    50485049                                               struct list_head *down_list)
    50495050{
    5050         __netdev_adjacent_dev_remove(dev, upper_dev, up_list);
    5051         __netdev_adjacent_dev_remove(upper_dev, dev, down_list);
     5051        __netdev_adjacent_dev_remove(dev, upper_dev, ref_nr, up_list);
     5052        __netdev_adjacent_dev_remove(upper_dev, dev, ref_nr, down_list);
    50525053}
    50535054
    50545055static void __netdev_adjacent_dev_unlink(struct net_device *dev,
    5055                                          struct net_device *upper_dev)
    5056 {
    5057         __netdev_adjacent_dev_unlink_lists(dev, upper_dev,
     5056                                         struct net_device *upper_dev,
     5057                                         u16 ref_nr)
     5058{
     5059        __netdev_adjacent_dev_unlink_lists(dev, upper_dev, ref_nr,
    50585060                                           &dev->all_adj_list.upper,
    50595061                                           &upper_dev->all_adj_list.lower);
     
    50645066                                                void *private, bool master)
    50655067{
    5066         int ret = __netdev_adjacent_dev_link(dev, upper_dev);
     5068        int ret = __netdev_adjacent_dev_link(dev, upper_dev, 1);
    50675069
    50685070        if (ret)
    50695071                return ret;
    50705072
    5071         ret = __netdev_adjacent_dev_link_lists(dev, upper_dev,
     5073        ret = __netdev_adjacent_dev_link_lists(dev, upper_dev, 1,
    50725074                                               &dev->adj_list.upper,
    50735075                                               &upper_dev->adj_list.lower,
    50745076                                               private, master);
    50755077        if (ret) {
    5076                 __netdev_adjacent_dev_unlink(dev, upper_dev);
     5078                __netdev_adjacent_dev_unlink(dev, upper_dev, 1);
    50775079                return ret;
    50785080        }
     
    50845086                                                   struct net_device *upper_dev)
    50855087{
    5086         __netdev_adjacent_dev_unlink(dev, upper_dev);
    5087         __netdev_adjacent_dev_unlink_lists(dev, upper_dev,
     5088        __netdev_adjacent_dev_unlink(dev, upper_dev, 1);
     5089        __netdev_adjacent_dev_unlink_lists(dev, upper_dev, 1,
    50885090                                           &dev->adj_list.upper,
    50895091                                           &upper_dev->adj_list.lower);
     
    51265128                        pr_debug("Interlinking %s with %s, non-neighbour\n",
    51275129                                 i->dev->name, j->dev->name);
    5128                         ret = __netdev_adjacent_dev_link(i->dev, j->dev);
     5130                        ret = __netdev_adjacent_dev_link(i->dev, j->dev, i->ref_nr);
    51295131                        if (ret)
    51305132                                goto rollback_mesh;
     
    51365138                pr_debug("linking %s's upper device %s with %s\n",
    51375139                         upper_dev->name, i->dev->name, dev->name);
    5138                 ret = __netdev_adjacent_dev_link(dev, i->dev);
     5140                ret = __netdev_adjacent_dev_link(dev, i->dev, i->ref_nr);
    51395141                if (ret)
    51405142                        goto rollback_upper_mesh;
     
    51455147                pr_debug("linking %s's lower device %s with %s\n", dev->name,
    51465148                         i->dev->name, upper_dev->name);
    5147                 ret = __netdev_adjacent_dev_link(i->dev, upper_dev);
     5149                ret = __netdev_adjacent_dev_link(i->dev, upper_dev, i->ref_nr);
    51485150                if (ret)
    51495151                        goto rollback_lower_mesh;
     
    51585160                if (i == to_i)
    51595161                        break;
    5160                 __netdev_adjacent_dev_unlink(i->dev, upper_dev);
     5162                __netdev_adjacent_dev_unlink(i->dev, upper_dev, i->ref_nr);
    51615163        }
    51625164
     
    51685170                if (i == to_i)
    51695171                        break;
    5170                 __netdev_adjacent_dev_unlink(dev, i->dev);
     5172                __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr);
    51715173        }
    51725174
     
    51805182                        if (i == to_i && j == to_j)
    51815183                                break;
    5182                         __netdev_adjacent_dev_unlink(i->dev, j->dev);
     5184                        __netdev_adjacent_dev_unlink(i->dev, j->dev, i->ref_nr);
    51835185                }
    51845186                if (i == to_i)
     
    52565258        list_for_each_entry(i, &dev->all_adj_list.lower, list)
    52575259                list_for_each_entry(j, &upper_dev->all_adj_list.upper, list)
    5258                         __netdev_adjacent_dev_unlink(i->dev, j->dev);
     5260                        __netdev_adjacent_dev_unlink(i->dev, j->dev, i->ref_nr);
    52595261
    52605262        /* remove also the devices itself from lower/upper device
     
    52625264         */
    52635265        list_for_each_entry(i, &dev->all_adj_list.lower, list)
    5264                 __netdev_adjacent_dev_unlink(i->dev, upper_dev);
     5266                __netdev_adjacent_dev_unlink(i->dev, upper_dev, i->ref_nr);
    52655267
    52665268        list_for_each_entry(i, &upper_dev->all_adj_list.upper, list)
    5267                 __netdev_adjacent_dev_unlink(dev, i->dev);
     5269                __netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr);
    52685270
    52695271        call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev);
Note: See TracChangeset for help on using the changeset viewer.