From: Zoltan Kiss <zoltan.kiss@citrix.com>
To: Wei Liu <wei.liu2@citrix.com>
Cc: Ian Campbell <Ian.Campbell@citrix.com>,
David Vrabel <david.vrabel@citrix.com>, <netdev@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <xen-devel@lists.xenproject.org>
Subject: Re: [PATCH net-next 2/2] xen-netback: Turn off the carrier if the guest is not able to receive
Date: Wed, 6 Aug 2014 20:18:44 +0100 [thread overview]
Message-ID: <53E27F94.7000903@citrix.com> (raw)
In-Reply-To: <20140805124552.GE11230@zion.uk.xensource.com>
On 05/08/14 13:45, Wei Liu wrote:
> On Mon, Aug 04, 2014 at 04:20:58PM +0100, Zoltan Kiss wrote:
> [...]
>> struct xenvif {
>> diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
>> index fbdadb3..48a55cd 100644
>> --- a/drivers/net/xen-netback/interface.c
>> +++ b/drivers/net/xen-netback/interface.c
>> @@ -97,7 +101,16 @@ int xenvif_poll(struct napi_struct *napi, int budget)
>> static irqreturn_t xenvif_rx_interrupt(int irq, void *dev_id)
>> {
>> struct xenvif_queue *queue = dev_id;
>> + struct netdev_queue *net_queue =
>> + netdev_get_tx_queue(queue->vif->dev, queue->id);
>>
>> + /* QUEUE_STATUS_RX_PURGE_EVENT is only set if either QDisc was off OR
>> + * the carrier went down and this queue was previously blocked
>> + */
>
> Could you change "blocked" to "stalled" so that the comment matches the
> code closely?
Ok
>> @@ -1935,6 +1934,75 @@ static void xenvif_start_queue(struct xenvif_queue *queue)
>> xenvif_wake_queue(queue);
>> }
>>
>> +/* Only called from the queue's thread, it handles the situation when the guest
>> + * doesn't post enough requests on the receiving ring.
>> + * First xenvif_start_xmit disables QDisc and start a timer, and then either the
>> + * timer fires, or the guest send an interrupt after posting new request. If it
>> + * is the timer, the carrier is turned off here.
>> + * */
>
> Please remove that extra "*".
Ok
>> +static void xenvif_rx_purge_event(struct xenvif_queue *queue)
>> +{
>> + /* Either the last unsuccesful skb or at least 1 slot should fit */
>> + int needed = queue->rx_last_skb_slots ?
>> + queue->rx_last_skb_slots : 1;
>> +
>> + /* It is assumed that if the guest post new slots after this, the RX
>> + * interrupt will set the QUEUE_STATUS_RX_PURGE_EVENT bit and wake up
>> + * the thread again
>> + */
>
> Basically in this state machine you have a tuple (RX_STALLED bit,
> PURGE_EVENT bit, carrier state). This whole state transaction is very
> scary, any chance you can draw a graph like the xenbus state machine in
> xenbus.c?
>
> I fear that after three month noone can easily understand this code
> unless he / she spends half a day reading the code. And without defining
> what state is legal it's very hard to tell what behavior is expected and
> what is not.
Ok
>
>> + set_bit(QUEUE_STATUS_RX_STALLED, &queue->status);
>> + if (!xenvif_rx_ring_slots_available(queue, needed)) {
>> + rtnl_lock();
>> + if (netif_carrier_ok(queue->vif->dev)) {
>> + /* Timer fired and there are still no slots. Turn off
>> + * everything except the interrupts
>> + */
>> + netif_carrier_off(queue->vif->dev);
>> + skb_queue_purge(&queue->rx_queue);
>> + queue->rx_last_skb_slots = 0;
>> + if (net_ratelimit())
>> + netdev_err(queue->vif->dev, "Carrier off due to lack of guest response on queue %d\n", queue->id);
>
> Line too long.
Ok
>> @@ -1944,8 +2012,12 @@ int xenvif_kthread_guest_rx(void *data)
>> wait_event_interruptible(queue->wq,
>> rx_work_todo(queue) ||
>> queue->vif->disabled ||
>> + test_bit(QUEUE_STATUS_RX_PURGE_EVENT, &queue->status) ||
>
> Line too long.
Ok
>
>> kthread_should_stop());
>>
>> + if (kthread_should_stop())
>> + break;
>> +
>> /* This frontend is found to be rogue, disable it in
>> * kthread context. Currently this is only set when
>> * netback finds out frontend sends malformed packet,
>> @@ -1955,24 +2027,21 @@ int xenvif_kthread_guest_rx(void *data)
>> */
>> if (unlikely(queue->vif->disabled && queue->id == 0))
>> xenvif_carrier_off(queue->vif);
>
> I think you also need to check vif->disabled flag in your following code
> so that you don't accidently re-enable a rogue vif in a queue whose id
> != 0.
Yes.
>
> Further more "disabled" can be transformed to a bit in vif->status.
> You can incorporate such change in your previous patch or a separate
> prerequisite patch.
Yes, I've already done that on my non-multiqueue branch.
>
>> -
>> - if (kthread_should_stop())
>> - break;
>> -
>> - if (queue->rx_queue_purge) {
>> + else if (unlikely(test_and_clear_bit(QUEUE_STATUS_RX_PURGE_EVENT,
>> + &queue->status))) {
>> + xenvif_rx_purge_event(queue);
>> + } else if (!netif_carrier_ok(queue->vif->dev)) {
>> + /* Another queue stalled and turned the carrier off, so
>> + * purge the internal queue of queues which were not
>> + * blocked
>> + */
>
> "blocked" -> "stalled"?
Ok
>
> In theory even one queue stalls all other queues can still make
> progress, isn't it?
This patch makes sure that if a queue is stalled, none of the others can
transmit, even if they would be able to do so. It is documented at the
definition of QUEUE_STATUS_RX_STALLED.
>
> Wei.
>
next prev parent reply other threads:[~2014-08-06 19:18 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-04 15:20 [PATCH net-next 0/2] xen-netback: Changes around carrier handling Zoltan Kiss
2014-08-04 15:20 ` [PATCH net-next 1/2] xen-netback: Using a new state bit instead of carrier Zoltan Kiss
2014-08-05 12:45 ` Wei Liu
2014-08-06 18:25 ` Zoltan Kiss
2014-08-04 15:20 ` [PATCH net-next 2/2] xen-netback: Turn off the carrier if the guest is not able to receive Zoltan Kiss
2014-08-05 12:45 ` Wei Liu
2014-08-06 19:18 ` Zoltan Kiss [this message]
2014-08-04 15:34 ` [PATCH net-next 0/2] xen-netback: Changes around carrier handling Zoltan Kiss
2014-08-05 23:07 ` David Miller
2014-08-06 0:00 ` Wei Liu
2014-08-06 1:50 ` David Miller
2014-08-06 8:54 ` Wei Liu
2014-08-06 19:20 ` Zoltan Kiss
2014-08-06 21:01 ` David Miller
2014-08-07 15:51 ` Zoltan Kiss
2014-08-08 5:28 ` David Miller
2014-08-07 16:49 ` Zoltan Kiss
2014-08-08 5:29 ` David Miller
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=53E27F94.7000903@citrix.com \
--to=zoltan.kiss@citrix.com \
--cc=Ian.Campbell@citrix.com \
--cc=david.vrabel@citrix.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.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).