|
@@ -2123,6 +2123,24 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
+static void set_cur_queue_map(struct pktgen_dev *pkt_dev)
|
|
|
|
+{
|
|
|
|
+ if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) {
|
|
|
|
+ __u16 t;
|
|
|
|
+ if (pkt_dev->flags & F_QUEUE_MAP_RND) {
|
|
|
|
+ t = random32() %
|
|
|
|
+ (pkt_dev->queue_map_max -
|
|
|
|
+ pkt_dev->queue_map_min + 1)
|
|
|
|
+ + pkt_dev->queue_map_min;
|
|
|
|
+ } else {
|
|
|
|
+ t = pkt_dev->cur_queue_map + 1;
|
|
|
|
+ if (t > pkt_dev->queue_map_max)
|
|
|
|
+ t = pkt_dev->queue_map_min;
|
|
|
|
+ }
|
|
|
|
+ pkt_dev->cur_queue_map = t;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
/* Increment/randomize headers according to flags and current values
|
|
/* Increment/randomize headers according to flags and current values
|
|
* for IP src/dest, UDP src/dst port, MAC-Addr src/dst
|
|
* for IP src/dest, UDP src/dst port, MAC-Addr src/dst
|
|
*/
|
|
*/
|
|
@@ -2325,19 +2343,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
|
|
pkt_dev->cur_pkt_size = t;
|
|
pkt_dev->cur_pkt_size = t;
|
|
}
|
|
}
|
|
|
|
|
|
- if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) {
|
|
|
|
- __u16 t;
|
|
|
|
- if (pkt_dev->flags & F_QUEUE_MAP_RND) {
|
|
|
|
- t = random32() %
|
|
|
|
- (pkt_dev->queue_map_max - pkt_dev->queue_map_min + 1)
|
|
|
|
- + pkt_dev->queue_map_min;
|
|
|
|
- } else {
|
|
|
|
- t = pkt_dev->cur_queue_map + 1;
|
|
|
|
- if (t > pkt_dev->queue_map_max)
|
|
|
|
- t = pkt_dev->queue_map_min;
|
|
|
|
- }
|
|
|
|
- pkt_dev->cur_queue_map = t;
|
|
|
|
- }
|
|
|
|
|
|
+ set_cur_queue_map(pkt_dev);
|
|
|
|
|
|
pkt_dev->flows[flow].count++;
|
|
pkt_dev->flows[flow].count++;
|
|
}
|
|
}
|
|
@@ -2458,7 +2464,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
|
|
__be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
|
|
__be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
|
|
__be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
|
|
__be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
|
|
__be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
|
|
__be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
|
|
-
|
|
|
|
|
|
+ u16 queue_map;
|
|
|
|
|
|
if (pkt_dev->nr_labels)
|
|
if (pkt_dev->nr_labels)
|
|
protocol = htons(ETH_P_MPLS_UC);
|
|
protocol = htons(ETH_P_MPLS_UC);
|
|
@@ -2469,6 +2475,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
|
|
/* Update any of the values, used when we're incrementing various
|
|
/* Update any of the values, used when we're incrementing various
|
|
* fields.
|
|
* fields.
|
|
*/
|
|
*/
|
|
|
|
+ queue_map = pkt_dev->cur_queue_map;
|
|
mod_cur_headers(pkt_dev);
|
|
mod_cur_headers(pkt_dev);
|
|
|
|
|
|
datalen = (odev->hard_header_len + 16) & ~0xf;
|
|
datalen = (odev->hard_header_len + 16) & ~0xf;
|
|
@@ -2507,7 +2514,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
|
|
skb->network_header = skb->tail;
|
|
skb->network_header = skb->tail;
|
|
skb->transport_header = skb->network_header + sizeof(struct iphdr);
|
|
skb->transport_header = skb->network_header + sizeof(struct iphdr);
|
|
skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
|
|
skb_put(skb, sizeof(struct iphdr) + sizeof(struct udphdr));
|
|
- skb_set_queue_mapping(skb, pkt_dev->cur_queue_map);
|
|
|
|
|
|
+ skb_set_queue_mapping(skb, queue_map);
|
|
iph = ip_hdr(skb);
|
|
iph = ip_hdr(skb);
|
|
udph = udp_hdr(skb);
|
|
udph = udp_hdr(skb);
|
|
|
|
|
|
@@ -2797,6 +2804,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
|
|
__be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
|
|
__be16 *vlan_encapsulated_proto = NULL; /* packet type ID field (or len) for VLAN tag */
|
|
__be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
|
|
__be16 *svlan_tci = NULL; /* Encapsulates priority and SVLAN ID */
|
|
__be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
|
|
__be16 *svlan_encapsulated_proto = NULL; /* packet type ID field (or len) for SVLAN tag */
|
|
|
|
+ u16 queue_map;
|
|
|
|
|
|
if (pkt_dev->nr_labels)
|
|
if (pkt_dev->nr_labels)
|
|
protocol = htons(ETH_P_MPLS_UC);
|
|
protocol = htons(ETH_P_MPLS_UC);
|
|
@@ -2807,6 +2815,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
|
|
/* Update any of the values, used when we're incrementing various
|
|
/* Update any of the values, used when we're incrementing various
|
|
* fields.
|
|
* fields.
|
|
*/
|
|
*/
|
|
|
|
+ queue_map = pkt_dev->cur_queue_map;
|
|
mod_cur_headers(pkt_dev);
|
|
mod_cur_headers(pkt_dev);
|
|
|
|
|
|
skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
|
|
skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
|
|
@@ -2844,7 +2853,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
|
|
skb->network_header = skb->tail;
|
|
skb->network_header = skb->tail;
|
|
skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
|
|
skb->transport_header = skb->network_header + sizeof(struct ipv6hdr);
|
|
skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
|
|
skb_put(skb, sizeof(struct ipv6hdr) + sizeof(struct udphdr));
|
|
- skb_set_queue_mapping(skb, pkt_dev->cur_queue_map);
|
|
|
|
|
|
+ skb_set_queue_mapping(skb, queue_map);
|
|
iph = ipv6_hdr(skb);
|
|
iph = ipv6_hdr(skb);
|
|
udph = udp_hdr(skb);
|
|
udph = udp_hdr(skb);
|
|
|
|
|
|
@@ -3263,7 +3272,9 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
|
|
static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
|
|
static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
|
|
{
|
|
{
|
|
struct net_device *odev = NULL;
|
|
struct net_device *odev = NULL;
|
|
|
|
+ struct netdev_queue *txq;
|
|
__u64 idle_start = 0;
|
|
__u64 idle_start = 0;
|
|
|
|
+ u16 queue_map;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
odev = pkt_dev->odev;
|
|
odev = pkt_dev->odev;
|
|
@@ -3285,9 +3296,15 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if ((netif_queue_stopped(odev) ||
|
|
|
|
- (pkt_dev->skb &&
|
|
|
|
- netif_subqueue_stopped(odev, pkt_dev->skb))) ||
|
|
|
|
|
|
+ if (!pkt_dev->skb) {
|
|
|
|
+ set_cur_queue_map(pkt_dev);
|
|
|
|
+ queue_map = pkt_dev->cur_queue_map;
|
|
|
|
+ } else {
|
|
|
|
+ queue_map = skb_get_queue_mapping(pkt_dev->skb);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ txq = netdev_get_tx_queue(odev, queue_map);
|
|
|
|
+ if (netif_tx_queue_stopped(txq) ||
|
|
need_resched()) {
|
|
need_resched()) {
|
|
idle_start = getCurUs();
|
|
idle_start = getCurUs();
|
|
|
|
|
|
@@ -3303,8 +3320,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
|
|
|
|
|
|
pkt_dev->idle_acc += getCurUs() - idle_start;
|
|
pkt_dev->idle_acc += getCurUs() - idle_start;
|
|
|
|
|
|
- if (netif_queue_stopped(odev) ||
|
|
|
|
- netif_subqueue_stopped(odev, pkt_dev->skb)) {
|
|
|
|
|
|
+ if (netif_tx_queue_stopped(txq)) {
|
|
pkt_dev->next_tx_us = getCurUs(); /* TODO */
|
|
pkt_dev->next_tx_us = getCurUs(); /* TODO */
|
|
pkt_dev->next_tx_ns = 0;
|
|
pkt_dev->next_tx_ns = 0;
|
|
goto out; /* Try the next interface */
|
|
goto out; /* Try the next interface */
|
|
@@ -3331,9 +3347,12 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- netif_tx_lock_bh(odev);
|
|
|
|
- if (!netif_queue_stopped(odev) &&
|
|
|
|
- !netif_subqueue_stopped(odev, pkt_dev->skb)) {
|
|
|
|
|
|
+ /* fill_packet() might have changed the queue */
|
|
|
|
+ queue_map = skb_get_queue_mapping(pkt_dev->skb);
|
|
|
|
+ txq = netdev_get_tx_queue(odev, queue_map);
|
|
|
|
+
|
|
|
|
+ __netif_tx_lock_bh(txq);
|
|
|
|
+ if (!netif_tx_queue_stopped(txq)) {
|
|
|
|
|
|
atomic_inc(&(pkt_dev->skb->users));
|
|
atomic_inc(&(pkt_dev->skb->users));
|
|
retry_now:
|
|
retry_now:
|
|
@@ -3377,7 +3396,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
|
|
pkt_dev->next_tx_ns = 0;
|
|
pkt_dev->next_tx_ns = 0;
|
|
}
|
|
}
|
|
|
|
|
|
- netif_tx_unlock_bh(odev);
|
|
|
|
|
|
+ __netif_tx_unlock_bh(txq);
|
|
|
|
|
|
/* If pkt_dev->count is zero, then run forever */
|
|
/* If pkt_dev->count is zero, then run forever */
|
|
if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
|
|
if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
|