aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c59
1 files changed, 42 insertions, 17 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 6a94475aee85..09fb03fa1ae6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -272,7 +272,7 @@ static const unsigned short netdev_lock_type[] =
272 ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY, 272 ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY,
273 ARPHRD_VOID, ARPHRD_NONE}; 273 ARPHRD_VOID, ARPHRD_NONE};
274 274
275static const char *netdev_lock_name[] = 275static const char *const netdev_lock_name[] =
276 {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25", 276 {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25",
277 "_xmit_PRONET", "_xmit_CHAOS", "_xmit_IEEE802", "_xmit_ARCNET", 277 "_xmit_PRONET", "_xmit_CHAOS", "_xmit_IEEE802", "_xmit_ARCNET",
278 "_xmit_APPLETLK", "_xmit_DLCI", "_xmit_ATM", "_xmit_METRICOM", 278 "_xmit_APPLETLK", "_xmit_DLCI", "_xmit_ATM", "_xmit_METRICOM",
@@ -1704,7 +1704,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
1704 skb_dst_drop(skb); 1704 skb_dst_drop(skb);
1705 1705
1706 rc = ops->ndo_start_xmit(skb, dev); 1706 rc = ops->ndo_start_xmit(skb, dev);
1707 if (rc == 0) 1707 if (rc == NETDEV_TX_OK)
1708 txq_trans_update(txq); 1708 txq_trans_update(txq);
1709 /* 1709 /*
1710 * TODO: if skb_orphan() was called by 1710 * TODO: if skb_orphan() was called by
@@ -1730,7 +1730,7 @@ gso:
1730 skb->next = nskb->next; 1730 skb->next = nskb->next;
1731 nskb->next = NULL; 1731 nskb->next = NULL;
1732 rc = ops->ndo_start_xmit(nskb, dev); 1732 rc = ops->ndo_start_xmit(nskb, dev);
1733 if (unlikely(rc)) { 1733 if (unlikely(rc != NETDEV_TX_OK)) {
1734 nskb->next = skb->next; 1734 nskb->next = skb->next;
1735 skb->next = nskb; 1735 skb->next = nskb;
1736 return rc; 1736 return rc;
@@ -1744,7 +1744,7 @@ gso:
1744 1744
1745out_kfree_skb: 1745out_kfree_skb:
1746 kfree_skb(skb); 1746 kfree_skb(skb);
1747 return 0; 1747 return NETDEV_TX_OK;
1748} 1748}
1749 1749
1750static u32 skb_tx_hashrnd; 1750static u32 skb_tx_hashrnd;
@@ -1786,6 +1786,40 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
1786 return netdev_get_tx_queue(dev, queue_index); 1786 return netdev_get_tx_queue(dev, queue_index);
1787} 1787}
1788 1788
1789static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
1790 struct net_device *dev,
1791 struct netdev_queue *txq)
1792{
1793 spinlock_t *root_lock = qdisc_lock(q);
1794 int rc;
1795
1796 spin_lock(root_lock);
1797 if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
1798 kfree_skb(skb);
1799 rc = NET_XMIT_DROP;
1800 } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) &&
1801 !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) {
1802 /*
1803 * This is a work-conserving queue; there are no old skbs
1804 * waiting to be sent out; and the qdisc is not running -
1805 * xmit the skb directly.
1806 */
1807 __qdisc_update_bstats(q, skb->len);
1808 if (sch_direct_xmit(skb, q, dev, txq, root_lock))
1809 __qdisc_run(q);
1810 else
1811 clear_bit(__QDISC_STATE_RUNNING, &q->state);
1812
1813 rc = NET_XMIT_SUCCESS;
1814 } else {
1815 rc = qdisc_enqueue_root(skb, q);
1816 qdisc_run(q);
1817 }
1818 spin_unlock(root_lock);
1819
1820 return rc;
1821}
1822
1789/** 1823/**
1790 * dev_queue_xmit - transmit a buffer 1824 * dev_queue_xmit - transmit a buffer
1791 * @skb: buffer to transmit 1825 * @skb: buffer to transmit
@@ -1859,19 +1893,7 @@ gso:
1859 skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS); 1893 skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
1860#endif 1894#endif
1861 if (q->enqueue) { 1895 if (q->enqueue) {
1862 spinlock_t *root_lock = qdisc_lock(q); 1896 rc = __dev_xmit_skb(skb, q, dev, txq);
1863
1864 spin_lock(root_lock);
1865
1866 if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
1867 kfree_skb(skb);
1868 rc = NET_XMIT_DROP;
1869 } else {
1870 rc = qdisc_enqueue_root(skb, q);
1871 qdisc_run(q);
1872 }
1873 spin_unlock(root_lock);
1874
1875 goto out; 1897 goto out;
1876 } 1898 }
1877 1899
@@ -3927,6 +3949,7 @@ int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
3927 } 3949 }
3928 return err; 3950 return err;
3929} 3951}
3952EXPORT_SYMBOL_GPL(__dev_addr_sync);
3930 3953
3931void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, 3954void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
3932 struct dev_addr_list **from, int *from_count) 3955 struct dev_addr_list **from, int *from_count)
@@ -3946,6 +3969,7 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
3946 da = next; 3969 da = next;
3947 } 3970 }
3948} 3971}
3972EXPORT_SYMBOL_GPL(__dev_addr_unsync);
3949 3973
3950/** 3974/**
3951 * dev_unicast_sync - Synchronize device's unicast list to another device 3975 * dev_unicast_sync - Synchronize device's unicast list to another device
@@ -5347,6 +5371,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
5347out: 5371out:
5348 return err; 5372 return err;
5349} 5373}
5374EXPORT_SYMBOL_GPL(dev_change_net_namespace);
5350 5375
5351static int dev_cpu_callback(struct notifier_block *nfb, 5376static int dev_cpu_callback(struct notifier_block *nfb,
5352 unsigned long action, 5377 unsigned long action,