From: Daniel Borkmann <dborkman@redhat.com>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org
Subject: [RFC PATCH net-next 3/3] packet: make use of deferred TX queue flushing
Date: Sun, 24 Aug 2014 15:42:18 +0200 [thread overview]
Message-ID: <1408887738-7661-4-git-send-email-dborkman@redhat.com> (raw)
In-Reply-To: <1408887738-7661-1-git-send-email-dborkman@redhat.com>
This adds a first use-case of deferred tail pointer flushing
for AF_PACKET's TX_RING in QDISC_BYPASS mode.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
net/packet/af_packet.c | 49 +++++++++++++++++++++++++++++++++++++------------
1 file changed, 37 insertions(+), 12 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 0dfa990..27457e8 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -216,7 +216,8 @@ static void prb_fill_vlan_info(struct tpacket_kbdq_core *,
static void packet_flush_mclist(struct sock *sk);
struct packet_skb_cb {
- unsigned int origlen;
+ u32 enforce_flush:1,
+ origlen:31;
union {
struct sockaddr_pkt pkt;
struct sockaddr_ll ll;
@@ -237,8 +238,11 @@ struct packet_skb_cb {
static void __fanout_unlink(struct sock *sk, struct packet_sock *po);
static void __fanout_link(struct sock *sk, struct packet_sock *po);
+#define PACKET_FLUSH_THRESH 8
+
static int packet_direct_xmit(struct sk_buff *skb)
{
+ bool flush = PACKET_SKB_CB(skb)->enforce_flush;
struct net_device *dev = skb->dev;
netdev_features_t features;
struct netdev_queue *txq;
@@ -261,9 +265,12 @@ static int packet_direct_xmit(struct sk_buff *skb)
HARD_TX_LOCK(dev, txq, smp_processor_id());
if (!netif_xmit_frozen_or_drv_stopped(txq)) {
- ret = netdev_start_xmit(skb, dev);
- if (ret == NETDEV_TX_OK)
+ ret = __netdev_xmit_only(skb, dev);
+ if (ret == NETDEV_TX_OK) {
+ if (flush)
+ __netdev_xmit_flush(dev, queue_map);
txq_trans_update(txq);
+ }
}
HARD_TX_UNLOCK(dev, txq);
@@ -313,7 +320,7 @@ static u16 __packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
return (u16) raw_smp_processor_id() % dev->real_num_tx_queues;
}
-static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
+static u16 packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
{
const struct net_device_ops *ops = dev->netdev_ops;
u16 queue_index;
@@ -327,6 +334,7 @@ static void packet_pick_tx_queue(struct net_device *dev, struct sk_buff *skb)
}
skb_set_queue_mapping(skb, queue_index);
+ return queue_index;
}
/* register_prot_hook must be invoked with the po->bind_lock held,
@@ -2237,7 +2245,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
unsigned char *addr;
int len_sum = 0;
int status = TP_STATUS_AVAILABLE;
- int hlen, tlen;
+ int hlen, tlen, pending = 0;
+ u16 last_queue = 0;
mutex_lock(&po->pg_vec_lock);
@@ -2276,18 +2285,22 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
ph = packet_current_frame(po, &po->tx_ring,
TP_STATUS_SEND_REQUEST);
if (unlikely(ph == NULL)) {
- if (need_wait && need_resched())
+ if (need_wait && need_resched()) {
+ if (packet_use_direct_xmit(po) && pending > 0) {
+ __netdev_xmit_flush(dev, last_queue);
+ pending = 0;
+ }
schedule();
+ }
continue;
}
status = TP_STATUS_SEND_REQUEST;
hlen = LL_RESERVED_SPACE(dev);
- tlen = dev->needed_tailroom;
- skb = sock_alloc_send_skb(&po->sk,
- hlen + tlen + sizeof(struct sockaddr_ll),
- 0, &err);
+ tlen = dev->needed_tailroom;
+ skb = sock_alloc_send_skb(&po->sk, hlen + tlen +
+ sizeof(struct sockaddr_ll), 0, &err);
if (unlikely(skb == NULL))
goto out_status;
@@ -2319,13 +2332,18 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
}
}
- packet_pick_tx_queue(dev, skb);
+ last_queue = packet_pick_tx_queue(dev, skb);
skb->destructor = tpacket_destruct_skb;
__packet_set_status(po, ph, TP_STATUS_SENDING);
packet_inc_pending(&po->tx_ring);
status = TP_STATUS_SEND_REQUEST;
+ if (pending >= PACKET_FLUSH_THRESH) {
+ PACKET_SKB_CB(skb)->enforce_flush = 1;
+ pending = -1;
+ }
+
err = po->xmit(skb);
if (unlikely(err > 0)) {
err = net_xmit_errno(err);
@@ -2340,7 +2358,11 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
* let's treat it like congestion or err < 0
*/
err = 0;
+ } else {
+ /* Sucessfully sent out. */
+ pending++;
}
+
packet_increment_head(&po->tx_ring);
len_sum += tp_len;
} while (likely((ph != NULL) ||
@@ -2354,11 +2376,12 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
err = len_sum;
goto out_put;
-
out_status:
__packet_set_status(po, ph, status);
kfree_skb(skb);
out_put:
+ if (packet_use_direct_xmit(po) && pending > 0)
+ __netdev_xmit_flush(dev, last_queue);
dev_put(dev);
out:
mutex_unlock(&po->pg_vec_lock);
@@ -2561,6 +2584,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
if (unlikely(extra_len == 4))
skb->no_fcs = 1;
+ PACKET_SKB_CB(skb)->enforce_flush = 1;
+
err = po->xmit(skb);
if (err > 0 && (err = net_xmit_errno(err)) != 0)
goto out_unlock;
--
1.7.11.7
next prev parent reply other threads:[~2014-08-24 13:42 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-24 13:42 [RFC PATCH net-next 0/3] Some deferred TX queue follow-ups Daniel Borkmann
2014-08-24 13:42 ` [RFC PATCH net-next 1/3] ixgbe: support netdev_ops->ndo_xmit_flush() Daniel Borkmann
2014-08-25 5:55 ` David Miller
2014-08-25 12:07 ` Jesper Dangaard Brouer
2014-08-25 22:32 ` David Miller
2014-08-25 23:31 ` David Miller
2014-08-26 6:13 ` Daniel Borkmann
2014-08-25 22:51 ` Alexander Duyck
2014-08-26 6:44 ` Jesper Dangaard Brouer
2014-08-27 11:34 ` Jesper Dangaard Brouer
2014-08-24 13:42 ` [RFC PATCH net-next 2/3] net: add __netdev_xmit_{only,flush} helpers Daniel Borkmann
2014-08-24 13:42 ` Daniel Borkmann [this message]
2014-08-25 5:57 ` [RFC PATCH net-next 3/3] packet: make use of deferred TX queue flushing David Miller
2014-08-25 6:40 ` Daniel Borkmann
2014-08-25 13:54 ` Jesper Dangaard Brouer
2014-08-25 15:16 ` Jesper Dangaard Brouer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1408887738-7661-4-git-send-email-dborkman@redhat.com \
--to=dborkman@redhat.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).