All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] net: ipa: NAPI poll updates
@ 2021-01-20 22:03 Alex Elder
  2021-01-20 22:03 ` [PATCH net-next 1/5] net: ipa: count actual work done in gsi_channel_poll() Alex Elder
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Alex Elder @ 2021-01-20 22:03 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

While reviewing the IPA NAPI polling code in detail I found two
problems.  This series fixes those, and implements a few other
improvements to this part of the code.

The first two patches are minor bug fixes that avoid extra passes
through the poll function.  The third simplifies code inside the
polling loop a bit.

The last two update how interrupts are disabled; previously it was
possible for another I/O completion condition to be recorded before
NAPI got scheduled.

					-Alex

Alex Elder (5):
  net: ipa: count actual work done in gsi_channel_poll()
  net: ipa: heed napi_complete() return value
  net: ipa: have gsi_channel_update() return a value
  net: ipa: repurpose gsi_irq_ieob_disable()
  net: ipa: disable IEOB interrupts before clearing

 drivers/net/ipa/gsi.c | 41 +++++++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 20 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH net-next 1/5] net: ipa: count actual work done in gsi_channel_poll()
  2021-01-20 22:03 [PATCH net-next 0/5] net: ipa: NAPI poll updates Alex Elder
@ 2021-01-20 22:03 ` Alex Elder
  2021-01-20 22:03 ` [PATCH net-next 2/5] net: ipa: heed napi_complete() return value Alex Elder
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Alex Elder @ 2021-01-20 22:03 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

There is an off-by-one problem in gsi_channel_poll().  The count of
transactions completed is incremented each time through the loop
*before* determining whether there is any more work to do.  As a
result, if we exit the loop early the counter its value is one more
than the number of transactions actually processed.

Instead, increment the count after processing, to ensure it reflects
the number of processed transactions.  The result is more naturally
described as a for loop rather than a while loop, so change that.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/gsi.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index 5b29f7d9d6ac1..56a5eb61b20c4 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -1543,13 +1543,12 @@ static struct gsi_trans *gsi_channel_poll_one(struct gsi_channel *channel)
 static int gsi_channel_poll(struct napi_struct *napi, int budget)
 {
 	struct gsi_channel *channel;
-	int count = 0;
+	int count;
 
 	channel = container_of(napi, struct gsi_channel, napi);
-	while (count < budget) {
+	for (count = 0; count < budget; count++) {
 		struct gsi_trans *trans;
 
-		count++;
 		trans = gsi_channel_poll_one(channel);
 		if (!trans)
 			break;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 2/5] net: ipa: heed napi_complete() return value
  2021-01-20 22:03 [PATCH net-next 0/5] net: ipa: NAPI poll updates Alex Elder
  2021-01-20 22:03 ` [PATCH net-next 1/5] net: ipa: count actual work done in gsi_channel_poll() Alex Elder
@ 2021-01-20 22:03 ` Alex Elder
  2021-01-20 22:03 ` [PATCH net-next 3/5] net: ipa: have gsi_channel_update() return a value Alex Elder
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Alex Elder @ 2021-01-20 22:03 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

Pay attention to the return value of napi_complete(), completing
polling only if it returns true.

Just use napi rather than &channel->napi as the argument passed to
napi_complete().

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/gsi.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index 56a5eb61b20c4..634f514e861e7 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -1555,10 +1555,8 @@ static int gsi_channel_poll(struct napi_struct *napi, int budget)
 		gsi_trans_complete(trans);
 	}
 
-	if (count < budget) {
-		napi_complete(&channel->napi);
+	if (count < budget && napi_complete(napi))
 		gsi_irq_ieob_enable(channel->gsi, channel->evt_ring_id);
-	}
 
 	return count;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 3/5] net: ipa: have gsi_channel_update() return a value
  2021-01-20 22:03 [PATCH net-next 0/5] net: ipa: NAPI poll updates Alex Elder
  2021-01-20 22:03 ` [PATCH net-next 1/5] net: ipa: count actual work done in gsi_channel_poll() Alex Elder
  2021-01-20 22:03 ` [PATCH net-next 2/5] net: ipa: heed napi_complete() return value Alex Elder
@ 2021-01-20 22:03 ` Alex Elder
  2021-01-21  5:35   ` Jakub Kicinski
  2021-01-20 22:04 ` [PATCH net-next 4/5] net: ipa: repurpose gsi_irq_ieob_disable() Alex Elder
  2021-01-20 22:04 ` [PATCH net-next 5/5] net: ipa: disable IEOB interrupts before clearing Alex Elder
  4 siblings, 1 reply; 8+ messages in thread
From: Alex Elder @ 2021-01-20 22:03 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

Have gsi_channel_update() return the first transaction in the
updated completed transaction list, or NULL if no new transactions
have been added.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/gsi.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index 634f514e861e7..5b98003263710 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -1452,7 +1452,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel)
 }
 
 /* Consult hardware, move any newly completed transactions to completed list */
-static void gsi_channel_update(struct gsi_channel *channel)
+struct gsi_trans *gsi_channel_update(struct gsi_channel *channel)
 {
 	u32 evt_ring_id = channel->evt_ring_id;
 	struct gsi *gsi = channel->gsi;
@@ -1471,7 +1471,7 @@ static void gsi_channel_update(struct gsi_channel *channel)
 	offset = GSI_EV_CH_E_CNTXT_4_OFFSET(evt_ring_id);
 	index = gsi_ring_index(ring, ioread32(gsi->virt + offset));
 	if (index == ring->index % ring->count)
-		return;
+		return NULL;
 
 	/* Get the transaction for the latest completed event.  Take a
 	 * reference to keep it from completing before we give the events
@@ -1496,6 +1496,8 @@ static void gsi_channel_update(struct gsi_channel *channel)
 	gsi_evt_ring_doorbell(channel->gsi, channel->evt_ring_id, index);
 
 	gsi_trans_free(trans);
+
+	return gsi_channel_trans_complete(channel);
 }
 
 /**
@@ -1516,11 +1518,8 @@ static struct gsi_trans *gsi_channel_poll_one(struct gsi_channel *channel)
 
 	/* Get the first transaction from the completed list */
 	trans = gsi_channel_trans_complete(channel);
-	if (!trans) {
-		/* List is empty; see if there's more to do */
-		gsi_channel_update(channel);
-		trans = gsi_channel_trans_complete(channel);
-	}
+	if (!trans)	/* List is empty; see if there's more to do */
+		trans = gsi_channel_update(channel);
 
 	if (trans)
 		gsi_trans_move_polled(trans);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 4/5] net: ipa: repurpose gsi_irq_ieob_disable()
  2021-01-20 22:03 [PATCH net-next 0/5] net: ipa: NAPI poll updates Alex Elder
                   ` (2 preceding siblings ...)
  2021-01-20 22:03 ` [PATCH net-next 3/5] net: ipa: have gsi_channel_update() return a value Alex Elder
@ 2021-01-20 22:04 ` Alex Elder
  2021-01-20 22:04 ` [PATCH net-next 5/5] net: ipa: disable IEOB interrupts before clearing Alex Elder
  4 siblings, 0 replies; 8+ messages in thread
From: Alex Elder @ 2021-01-20 22:04 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

Rename gsi_irq_ieob_disable() to be gsi_irq_ieob_disable_one().

Introduce a new function gsi_irq_ieob_disable() that takes a mask of
events to disable rather than a single event id.  This will be used
in the next patch.

Rename gsi_irq_ieob_enable() to be gsi_irq_ieob_enable_one() to be
consistent.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/gsi.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index 5b98003263710..59fc22347a257 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -272,7 +272,7 @@ static void gsi_irq_ch_ctrl_disable(struct gsi *gsi)
 	iowrite32(0, gsi->virt + GSI_CNTXT_SRC_CH_IRQ_MSK_OFFSET);
 }
 
-static void gsi_irq_ieob_enable(struct gsi *gsi, u32 evt_ring_id)
+static void gsi_irq_ieob_enable_one(struct gsi *gsi, u32 evt_ring_id)
 {
 	bool enable_ieob = !gsi->ieob_enabled_bitmap;
 	u32 val;
@@ -286,11 +286,11 @@ static void gsi_irq_ieob_enable(struct gsi *gsi, u32 evt_ring_id)
 		gsi_irq_type_enable(gsi, GSI_IEOB);
 }
 
-static void gsi_irq_ieob_disable(struct gsi *gsi, u32 evt_ring_id)
+static void gsi_irq_ieob_disable(struct gsi *gsi, u32 event_mask)
 {
 	u32 val;
 
-	gsi->ieob_enabled_bitmap &= ~BIT(evt_ring_id);
+	gsi->ieob_enabled_bitmap &= ~event_mask;
 
 	/* Disable the interrupt type if this was the last enabled channel */
 	if (!gsi->ieob_enabled_bitmap)
@@ -300,6 +300,11 @@ static void gsi_irq_ieob_disable(struct gsi *gsi, u32 evt_ring_id)
 	iowrite32(val, gsi->virt + GSI_CNTXT_SRC_IEOB_IRQ_MSK_OFFSET);
 }
 
+static void gsi_irq_ieob_disable_one(struct gsi *gsi, u32 evt_ring_id)
+{
+	gsi_irq_ieob_disable(gsi, BIT(evt_ring_id));
+}
+
 /* Enable all GSI_interrupt types */
 static void gsi_irq_enable(struct gsi *gsi)
 {
@@ -766,13 +771,13 @@ static void gsi_channel_freeze(struct gsi_channel *channel)
 
 	napi_disable(&channel->napi);
 
-	gsi_irq_ieob_disable(channel->gsi, channel->evt_ring_id);
+	gsi_irq_ieob_disable_one(channel->gsi, channel->evt_ring_id);
 }
 
 /* Allow transactions to be used on the channel again. */
 static void gsi_channel_thaw(struct gsi_channel *channel)
 {
-	gsi_irq_ieob_enable(channel->gsi, channel->evt_ring_id);
+	gsi_irq_ieob_enable_one(channel->gsi, channel->evt_ring_id);
 
 	napi_enable(&channel->napi);
 }
@@ -1207,7 +1212,7 @@ static void gsi_isr_ieob(struct gsi *gsi)
 
 		event_mask ^= BIT(evt_ring_id);
 
-		gsi_irq_ieob_disable(gsi, evt_ring_id);
+		gsi_irq_ieob_disable_one(gsi, evt_ring_id);
 		napi_schedule(&gsi->evt_ring[evt_ring_id].channel->napi);
 	}
 }
@@ -1555,7 +1560,7 @@ static int gsi_channel_poll(struct napi_struct *napi, int budget)
 	}
 
 	if (count < budget && napi_complete(napi))
-		gsi_irq_ieob_enable(channel->gsi, channel->evt_ring_id);
+		gsi_irq_ieob_enable_one(channel->gsi, channel->evt_ring_id);
 
 	return count;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 5/5] net: ipa: disable IEOB interrupts before clearing
  2021-01-20 22:03 [PATCH net-next 0/5] net: ipa: NAPI poll updates Alex Elder
                   ` (3 preceding siblings ...)
  2021-01-20 22:04 ` [PATCH net-next 4/5] net: ipa: repurpose gsi_irq_ieob_disable() Alex Elder
@ 2021-01-20 22:04 ` Alex Elder
  4 siblings, 0 replies; 8+ messages in thread
From: Alex Elder @ 2021-01-20 22:04 UTC (permalink / raw)
  To: davem, kuba
  Cc: elder, evgreen, bjorn.andersson, cpratapa, subashab, netdev,
	linux-kernel

Currently in gsi_isr_ieob(), event ring IEOB interrupts are disabled
one at a time.  The loop disables the IEOB interrupt for all event
rings represented in the event mask.  Instead, just disable them all
at once.

Disable them all *before* clearing the interrupt condition.  This
guarantees we'll schedule NAPI for each event once, before another
IEOB interrupt could be signaled.

Signed-off-by: Alex Elder <elder@linaro.org>
---
 drivers/net/ipa/gsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ipa/gsi.c b/drivers/net/ipa/gsi.c
index 59fc22347a257..8498326c43f40 100644
--- a/drivers/net/ipa/gsi.c
+++ b/drivers/net/ipa/gsi.c
@@ -1205,6 +1205,7 @@ static void gsi_isr_ieob(struct gsi *gsi)
 	u32 event_mask;
 
 	event_mask = ioread32(gsi->virt + GSI_CNTXT_SRC_IEOB_IRQ_OFFSET);
+	gsi_irq_ieob_disable(gsi, event_mask);
 	iowrite32(event_mask, gsi->virt + GSI_CNTXT_SRC_IEOB_IRQ_CLR_OFFSET);
 
 	while (event_mask) {
@@ -1212,7 +1213,6 @@ static void gsi_isr_ieob(struct gsi *gsi)
 
 		event_mask ^= BIT(evt_ring_id);
 
-		gsi_irq_ieob_disable_one(gsi, evt_ring_id);
 		napi_schedule(&gsi->evt_ring[evt_ring_id].channel->napi);
 	}
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 3/5] net: ipa: have gsi_channel_update() return a value
  2021-01-20 22:03 ` [PATCH net-next 3/5] net: ipa: have gsi_channel_update() return a value Alex Elder
@ 2021-01-21  5:35   ` Jakub Kicinski
  2021-01-21 11:34     ` Alex Elder
  0 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2021-01-21  5:35 UTC (permalink / raw)
  To: Alex Elder
  Cc: davem, elder, evgreen, bjorn.andersson, cpratapa, subashab,
	netdev, linux-kernel

On Wed, 20 Jan 2021 16:03:59 -0600 Alex Elder wrote:
> Have gsi_channel_update() return the first transaction in the
> updated completed transaction list, or NULL if no new transactions
> have been added.
> 
> Signed-off-by: Alex Elder <elder@linaro.org>

> @@ -1452,7 +1452,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel)
>  }
>  
>  /* Consult hardware, move any newly completed transactions to completed list */
> -static void gsi_channel_update(struct gsi_channel *channel)
> +struct gsi_trans *gsi_channel_update(struct gsi_channel *channel)

Why did it lose the 'static'?

drivers/net/ipa/gsi.c:1455:19: warning: no previous prototype for ‘gsi_channel_update’ [-Wmissing-prototypes]
 1455 | struct gsi_trans *gsi_channel_update(struct gsi_channel *channel)
      |                   ^~~~~~~~~~~~~~~~~~

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 3/5] net: ipa: have gsi_channel_update() return a value
  2021-01-21  5:35   ` Jakub Kicinski
@ 2021-01-21 11:34     ` Alex Elder
  0 siblings, 0 replies; 8+ messages in thread
From: Alex Elder @ 2021-01-21 11:34 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: davem, elder, evgreen, bjorn.andersson, cpratapa, subashab,
	netdev, linux-kernel

On 1/20/21 11:35 PM, Jakub Kicinski wrote:
> On Wed, 20 Jan 2021 16:03:59 -0600 Alex Elder wrote:
>> Have gsi_channel_update() return the first transaction in the
>> updated completed transaction list, or NULL if no new transactions
>> have been added.
>>
>> Signed-off-by: Alex Elder <elder@linaro.org>
> 
>> @@ -1452,7 +1452,7 @@ void gsi_channel_doorbell(struct gsi_channel *channel)
>>   }
>>   
>>   /* Consult hardware, move any newly completed transactions to completed list */
>> -static void gsi_channel_update(struct gsi_channel *channel)
>> +struct gsi_trans *gsi_channel_update(struct gsi_channel *channel)
> 
> Why did it lose the 'static'?

It should not have.

My aarch64 build environment did not flag that, but I now built
for x86 and it does.  I guess I should make a habit of checking
with that, though it's a bit time-consuming.

I'll send v2 out shortly.  Thank you.

					-Alex

> drivers/net/ipa/gsi.c:1455:19: warning: no previous prototype for ‘gsi_channel_update’ [-Wmissing-prototypes]
>   1455 | struct gsi_trans *gsi_channel_update(struct gsi_channel *channel)
>        |                   ^~~~~~~~~~~~~~~~~~
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-01-21 11:35 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-20 22:03 [PATCH net-next 0/5] net: ipa: NAPI poll updates Alex Elder
2021-01-20 22:03 ` [PATCH net-next 1/5] net: ipa: count actual work done in gsi_channel_poll() Alex Elder
2021-01-20 22:03 ` [PATCH net-next 2/5] net: ipa: heed napi_complete() return value Alex Elder
2021-01-20 22:03 ` [PATCH net-next 3/5] net: ipa: have gsi_channel_update() return a value Alex Elder
2021-01-21  5:35   ` Jakub Kicinski
2021-01-21 11:34     ` Alex Elder
2021-01-20 22:04 ` [PATCH net-next 4/5] net: ipa: repurpose gsi_irq_ieob_disable() Alex Elder
2021-01-20 22:04 ` [PATCH net-next 5/5] net: ipa: disable IEOB interrupts before clearing Alex Elder

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.