aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netdevice.h68
-rw-r--r--net/core/dev.c55
2 files changed, 122 insertions, 1 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 68a4627b74f5..371fa8839d51 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -646,6 +646,14 @@ struct xps_dev_maps {
646 (nr_cpu_ids * sizeof(struct xps_map *))) 646 (nr_cpu_ids * sizeof(struct xps_map *)))
647#endif /* CONFIG_XPS */ 647#endif /* CONFIG_XPS */
648 648
649#define TC_MAX_QUEUE 16
650#define TC_BITMASK 15
651/* HW offloaded queuing disciplines txq count and offset maps */
652struct netdev_tc_txq {
653 u16 count;
654 u16 offset;
655};
656
649/* 657/*
650 * This structure defines the management hooks for network devices. 658 * This structure defines the management hooks for network devices.
651 * The following hooks can be defined; unless noted otherwise, they are 659 * The following hooks can be defined; unless noted otherwise, they are
@@ -756,6 +764,11 @@ struct xps_dev_maps {
756 * int (*ndo_set_vf_port)(struct net_device *dev, int vf, 764 * int (*ndo_set_vf_port)(struct net_device *dev, int vf,
757 * struct nlattr *port[]); 765 * struct nlattr *port[]);
758 * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb); 766 * int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
767 * int (*ndo_setup_tc)(struct net_device *dev, u8 tc)
768 * Called to setup 'tc' number of traffic classes in the net device. This
769 * is always called from the stack with the rtnl lock held and netif tx
770 * queues stopped. This allows the netdevice to perform queue management
771 * safely.
759 */ 772 */
760#define HAVE_NET_DEVICE_OPS 773#define HAVE_NET_DEVICE_OPS
761struct net_device_ops { 774struct net_device_ops {
@@ -814,6 +827,7 @@ struct net_device_ops {
814 struct nlattr *port[]); 827 struct nlattr *port[]);
815 int (*ndo_get_vf_port)(struct net_device *dev, 828 int (*ndo_get_vf_port)(struct net_device *dev,
816 int vf, struct sk_buff *skb); 829 int vf, struct sk_buff *skb);
830 int (*ndo_setup_tc)(struct net_device *dev, u8 tc);
817#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) 831#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
818 int (*ndo_fcoe_enable)(struct net_device *dev); 832 int (*ndo_fcoe_enable)(struct net_device *dev);
819 int (*ndo_fcoe_disable)(struct net_device *dev); 833 int (*ndo_fcoe_disable)(struct net_device *dev);
@@ -1146,6 +1160,9 @@ struct net_device {
1146 /* Data Center Bridging netlink ops */ 1160 /* Data Center Bridging netlink ops */
1147 const struct dcbnl_rtnl_ops *dcbnl_ops; 1161 const struct dcbnl_rtnl_ops *dcbnl_ops;
1148#endif 1162#endif
1163 u8 num_tc;
1164 struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE];
1165 u8 prio_tc_map[TC_BITMASK + 1];
1149 1166
1150#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE) 1167#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
1151 /* max exchange id for FCoE LRO by ddp */ 1168 /* max exchange id for FCoE LRO by ddp */
@@ -1165,6 +1182,57 @@ struct net_device {
1165#define NETDEV_ALIGN 32 1182#define NETDEV_ALIGN 32
1166 1183
1167static inline 1184static inline
1185int netdev_get_prio_tc_map(const struct net_device *dev, u32 prio)
1186{
1187 return dev->prio_tc_map[prio & TC_BITMASK];
1188}
1189
1190static inline
1191int netdev_set_prio_tc_map(struct net_device *dev, u8 prio, u8 tc)
1192{
1193 if (tc >= dev->num_tc)
1194 return -EINVAL;
1195
1196 dev->prio_tc_map[prio & TC_BITMASK] = tc & TC_BITMASK;
1197 return 0;
1198}
1199
1200static inline
1201void netdev_reset_tc(struct net_device *dev)
1202{
1203 dev->num_tc = 0;
1204 memset(dev->tc_to_txq, 0, sizeof(dev->tc_to_txq));
1205 memset(dev->prio_tc_map, 0, sizeof(dev->prio_tc_map));
1206}
1207
1208static inline
1209int netdev_set_tc_queue(struct net_device *dev, u8 tc, u16 count, u16 offset)
1210{
1211 if (tc >= dev->num_tc)
1212 return -EINVAL;
1213
1214 dev->tc_to_txq[tc].count = count;
1215 dev->tc_to_txq[tc].offset = offset;
1216 return 0;
1217}
1218
1219static inline
1220int netdev_set_num_tc(struct net_device *dev, u8 num_tc)
1221{
1222 if (num_tc > TC_MAX_QUEUE)
1223 return -EINVAL;
1224
1225 dev->num_tc = num_tc;
1226 return 0;
1227}
1228
1229static inline
1230int netdev_get_num_tc(struct net_device *dev)
1231{
1232 return dev->num_tc;
1233}
1234
1235static inline
1168struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev, 1236struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev,
1169 unsigned int index) 1237 unsigned int index)
1170{ 1238{
diff --git a/net/core/dev.c b/net/core/dev.c
index 2b85d4ae981f..8b1d886ed23b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1593,6 +1593,48 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
1593 rcu_read_unlock(); 1593 rcu_read_unlock();
1594} 1594}
1595 1595
1596/* netif_setup_tc - Handle tc mappings on real_num_tx_queues change
1597 * @dev: Network device
1598 * @txq: number of queues available
1599 *
1600 * If real_num_tx_queues is changed the tc mappings may no longer be
1601 * valid. To resolve this verify the tc mapping remains valid and if
1602 * not NULL the mapping. With no priorities mapping to this
1603 * offset/count pair it will no longer be used. In the worst case TC0
1604 * is invalid nothing can be done so disable priority mappings. If is
1605 * expected that drivers will fix this mapping if they can before
1606 * calling netif_set_real_num_tx_queues.
1607 */
1608void netif_setup_tc(struct net_device *dev, unsigned int txq)
1609{
1610 int i;
1611 struct netdev_tc_txq *tc = &dev->tc_to_txq[0];
1612
1613 /* If TC0 is invalidated disable TC mapping */
1614 if (tc->offset + tc->count > txq) {
1615 pr_warning("Number of in use tx queues changed "
1616 "invalidating tc mappings. Priority "
1617 "traffic classification disabled!\n");
1618 dev->num_tc = 0;
1619 return;
1620 }
1621
1622 /* Invalidated prio to tc mappings set to TC0 */
1623 for (i = 1; i < TC_BITMASK + 1; i++) {
1624 int q = netdev_get_prio_tc_map(dev, i);
1625
1626 tc = &dev->tc_to_txq[q];
1627 if (tc->offset + tc->count > txq) {
1628 pr_warning("Number of in use tx queues "
1629 "changed. Priority %i to tc "
1630 "mapping %i is no longer valid "
1631 "setting map to 0\n",
1632 i, q);
1633 netdev_set_prio_tc_map(dev, i, 0);
1634 }
1635 }
1636}
1637
1596/* 1638/*
1597 * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues 1639 * Routine to help set real_num_tx_queues. To avoid skbs mapped to queues
1598 * greater then real_num_tx_queues stale skbs on the qdisc must be flushed. 1640 * greater then real_num_tx_queues stale skbs on the qdisc must be flushed.
@@ -1612,6 +1654,9 @@ int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
1612 if (rc) 1654 if (rc)
1613 return rc; 1655 return rc;
1614 1656
1657 if (dev->num_tc)
1658 netif_setup_tc(dev, txq);
1659
1615 if (txq < dev->real_num_tx_queues) 1660 if (txq < dev->real_num_tx_queues)
1616 qdisc_reset_all_tx_gt(dev, txq); 1661 qdisc_reset_all_tx_gt(dev, txq);
1617 } 1662 }
@@ -2161,6 +2206,8 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb,
2161 unsigned int num_tx_queues) 2206 unsigned int num_tx_queues)
2162{ 2207{
2163 u32 hash; 2208 u32 hash;
2209 u16 qoffset = 0;
2210 u16 qcount = num_tx_queues;
2164 2211
2165 if (skb_rx_queue_recorded(skb)) { 2212 if (skb_rx_queue_recorded(skb)) {
2166 hash = skb_get_rx_queue(skb); 2213 hash = skb_get_rx_queue(skb);
@@ -2169,13 +2216,19 @@ u16 __skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb,
2169 return hash; 2216 return hash;
2170 } 2217 }
2171 2218
2219 if (dev->num_tc) {
2220 u8 tc = netdev_get_prio_tc_map(dev, skb->priority);
2221 qoffset = dev->tc_to_txq[tc].offset;
2222 qcount = dev->tc_to_txq[tc].count;
2223 }
2224
2172 if (skb->sk && skb->sk->sk_hash) 2225 if (skb->sk && skb->sk->sk_hash)
2173 hash = skb->sk->sk_hash; 2226 hash = skb->sk->sk_hash;
2174 else 2227 else
2175 hash = (__force u16) skb->protocol ^ skb->rxhash; 2228 hash = (__force u16) skb->protocol ^ skb->rxhash;
2176 hash = jhash_1word(hash, hashrnd); 2229 hash = jhash_1word(hash, hashrnd);
2177 2230
2178 return (u16) (((u64) hash * num_tx_queues) >> 32); 2231 return (u16) (((u64) hash * qcount) >> 32) + qoffset;
2179} 2232}
2180EXPORT_SYMBOL(__skb_tx_hash); 2233EXPORT_SYMBOL(__skb_tx_hash);
2181 2234