From: Jason Wang <jasowang@redhat.com>
To: Zhi Yong Wu <zwu.kernel@gmail.com>
Cc: Tom Herbert <therbert@google.com>,
Linux Netdev List <netdev@vger.kernel.org>,
Eric Dumazet <edumazet@google.com>,
Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Subject: Re: [PATCH 2/2] tun: Add support for RFS on tun flows
Date: Thu, 02 Jan 2014 13:41:16 +0800 [thread overview]
Message-ID: <52C4FBFC.3080101@redhat.com> (raw)
In-Reply-To: <CAEH94Lg4Le2SbrAfA8XCmi1NFoLmi87Y8zgFjE28hPVF9Rz1kA@mail.gmail.com>
On 01/02/2014 01:07 PM, Zhi Yong Wu wrote:
> On Thu, Jan 2, 2014 at 12:44 PM, Jason Wang <jasowang@redhat.com> wrote:
>> On 12/22/2013 06:54 PM, Zhi Yong Wu wrote:
>>> From: Tom Herbert <therbert@google.com>
>>>
>>> This patch adds support so that the rps_flow_tables (RFS) can be
>>> programmed using the tun flows which are already set up to track flows
>>> for the purposes of queue selection.
>>>
>>> On the receive path (corresponding to select_queue and tun_net_xmit) the
>>> rxhash is saved in the flow_entry. The original code only does flow
>>> lookup in select_queue, so this patch adds a flow lookup in tun_net_xmit
>>> if num_queues == 1 (select_queue is not called from
>>> dev_queue_xmit->netdev_pick_tx in that case).
>>>
>>> The flow is recorded (processing CPU) in tun_flow_update (TX path), and
>>> reset when flow is deleted.
>>>
>>> Signed-off-by: Tom Herbert <therbert@google.com>
>>> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>>> ---
>>> drivers/net/tun.c | 37 +++++++++++++++++++++++++++++++++++--
>>> 1 files changed, 35 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
>>> index a17a701..3cf0457 100644
>>> --- a/drivers/net/tun.c
>>> +++ b/drivers/net/tun.c
>>> @@ -152,6 +152,7 @@ struct tun_flow_entry {
>>> struct tun_struct *tun;
>>>
>>> u32 rxhash;
>>> + u32 rps_rxhash;
>>> int queue_index;
>>> unsigned long updated;
>>> };
>>> @@ -220,6 +221,7 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun,
>>> rxhash, queue_index);
>>> e->updated = jiffies;
>>> e->rxhash = rxhash;
>>> + e->rps_rxhash = 0;
>>> e->queue_index = queue_index;
>>> e->tun = tun;
>>> hlist_add_head_rcu(&e->hash_link, head);
>>> @@ -232,6 +234,7 @@ static void tun_flow_delete(struct tun_struct *tun, struct tun_flow_entry *e)
>>> {
>>> tun_debug(KERN_INFO, tun, "delete flow: hash %u index %u\n",
>>> e->rxhash, e->queue_index);
>>> + sock_rps_reset_flow_hash(e->rps_rxhash);
>>> hlist_del_rcu(&e->hash_link);
>>> kfree_rcu(e, rcu);
>>> --tun->flow_count;
>>> @@ -325,6 +328,7 @@ static void tun_flow_update(struct tun_struct *tun, u32 rxhash,
>>> /* TODO: keep queueing to old queue until it's empty? */
>>> e->queue_index = queue_index;
>>> e->updated = jiffies;
>>> + sock_rps_record_flow_hash(e->rps_rxhash);
>>> } else {
>>> spin_lock_bh(&tun->lock);
>>> if (!tun_flow_find(head, rxhash) &&
>>> @@ -341,6 +345,18 @@ unlock:
>>> rcu_read_unlock();
>>> }
>>>
>>> +/**
>>> + * Save the hash received in the stack receive path and update the
>>> + * flow_hash table accordingly.
>>> + */
>>> +static inline void tun_flow_save_rps_rxhash(struct tun_flow_entry *e, u32 hash)
>>> +{
>>> + if (unlikely(e->rps_rxhash != hash)) {
>>> + sock_rps_reset_flow_hash(e->rps_rxhash);
>>> + e->rps_rxhash = hash;
>>> + }
>>> +}
>>> +
>>> /* We try to identify a flow through its rxhash first. The reason that
>>> * we do not check rxq no. is because some cards(e.g 82599), chooses
>>> * the rxq based on the txq where the last packet of the flow comes. As
>>> @@ -361,9 +377,10 @@ static u16 tun_select_queue(struct net_device *dev, struct sk_buff *skb)
>>> txq = skb_get_hash(skb);
>>> if (txq) {
>>> e = tun_flow_find(&tun->flows[tun_hashfn(txq)], txq);
>>> - if (e)
>>> + if (e) {
>>> txq = e->queue_index;
>>> - else
>>> + tun_flow_save_rps_rxhash(e, txq);
>>> + } else
>> This looks wrong, txq is the queue index here. We should do this before
>> txq = e->queue_index.
> Good catch, will try to post one patch to fix it after the perf tests
> are done, thanks.
>> Did you test the patch? You can simply verify the basic function by
> No so far, be planning to do its perf tests, do you have any good suggestions?
Maybe the first step is to check whether it works as expected, as I said
whether the rx softirq were done in the expected CPU. Then you can run a
complete round of tests (e.g TCP_RR, TCP_STREAM with different message
sizes and several sessions in parallel), to see whether it help. You may
run the performance test for single queue first to make sure there's no
regression first.
Thanks
>> checking whether the rx softirq were done in the same cpu where vhost is
>> running.
>>> /* use multiply and shift instead of expensive divide */
>>> txq = ((u64)txq * numqueues) >> 32;
>>> } else if (likely(skb_rx_queue_recorded(skb))) {
>>> @@ -728,6 +745,22 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
>>> if (txq >= tun->numqueues)
>>> goto drop;
>>>
>>> + if (tun->numqueues == 1) {
>>> + /* Select queue was not called for the skbuff, so we extract the
>>> + * RPS hash and save it into the flow_table here.
>>> + */
>>> + __u32 rxhash;
>>> +
>>> + rxhash = skb_get_hash(skb);
>>> + if (rxhash) {
>>> + struct tun_flow_entry *e;
>>> + e = tun_flow_find(&tun->flows[tun_hashfn(rxhash)],
>>> + rxhash);
>>> + if (e)
>>> + tun_flow_save_rps_rxhash(e, rxhash);
>>> + }
>>> + }
>>> +
>>> tun_debug(KERN_INFO, tun, "tun_net_xmit %d\n", skb->len);
>>>
>>> BUG_ON(!tfile);
>
>
next prev parent reply other threads:[~2014-01-02 5:41 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-22 10:54 [PATCH 0/2] tun: add the RFS support Zhi Yong Wu
2013-12-22 10:54 ` [PATCH 1/2] net: Allow setting sock flow hash without a sock Zhi Yong Wu
2013-12-22 10:54 ` [PATCH 2/2] tun: Add support for RFS on tun flows Zhi Yong Wu
2014-01-02 4:44 ` Jason Wang
2014-01-02 5:07 ` Zhi Yong Wu
2014-01-02 5:41 ` Jason Wang [this message]
2014-01-02 6:35 ` Zhi Yong Wu
2013-12-31 18:32 ` [PATCH 0/2] tun: add the RFS support David Miller
2013-12-31 22:33 ` Tom Herbert
2014-01-01 6:44 ` Zhi Yong Wu
2014-01-02 18:13 ` Tom Herbert
2014-01-04 10:53 ` Zhi Yong Wu
2014-01-13 13:29 ` Zhi Yong Wu
2014-01-13 16:49 ` Tom Herbert
2014-01-14 3:28 ` Zhi Yong Wu
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=52C4FBFC.3080101@redhat.com \
--to=jasowang@redhat.com \
--cc=edumazet@google.com \
--cc=netdev@vger.kernel.org \
--cc=therbert@google.com \
--cc=wuzhy@linux.vnet.ibm.com \
--cc=zwu.kernel@gmail.com \
/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).