Re: [PATCH v2 net-next] net: core: use listified Rx for GRO_NORMAL in napi_gro_receive()

2020-06-25 Thread Edward Cree
On 24/06/2020 22:06, Jason A. Donenfeld wrote:
> Hi Alexander,
>
> This patch introduced a behavior change around GRO_DROP:
>
> napi_skb_finish used to sometimes return GRO_DROP:
>
>> -static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
>> +static gro_result_t napi_skb_finish(struct napi_struct *napi,
>> +struct sk_buff *skb,
>> +gro_result_t ret)
>>  {
>>  switch (ret) {
>>  case GRO_NORMAL:
>> -if (netif_receive_skb_internal(skb))
>> -ret = GRO_DROP;
>> +gro_normal_one(napi, skb);
>>
> But under your change, gro_normal_one and the various calls that makes
> never propagates its return value, and so GRO_DROP is never returned to
> the caller, even if something drops it.
This followed the pattern set by napi_frags_finish(), and is
 intentional: gro_normal_one() usually defers processing of
 the skb to the end of the napi poll, so by the time we know
 that the network stack has dropped it, the caller has long
 since returned.
In fact the RX will be handled by netif_receive_skb_list_internal(),
 which can't return NET_RX_SUCCESS vs. NET_RX_DROP, because it's
 handling many skbs which might not all have the same verdict.

When originally doing this work I felt this was OK because
 almost no-one was sensitive to the return value — almost the
 only callers that were were in our own sfc driver, and then
 only for making bogus decisions about interrupt moderation.
Alexander just followed my lead, so don't blame him ;-)

> For some context, I'm consequently mulling over this change in my code,
> since checking for GRO_DROP now constitutes dead code:
Incidentally, it's only dead because dev_gro_receive() can't
 return GRO_DROP either.  If it could, napi_skb_finish()
 would pass that on.  And napi_gro_frags() (which AIUI is the
 better API for some performance reasons that I can't remember)
 can still return GRO_DROP too.

However, I think that incrementing your rx_dropped stat when
 the network stack chose to drop the packet is the wrong
 thing to do anyway (IMHO rx_dropped is for "there was a
 packet on the wire but either the hardware or the driver was
 unable to receive it"), so I'd say go ahead and remove the
 check.

HTH
-ed


Re: [PATCH v2 net-next] net: core: use listified Rx for GRO_NORMAL in napi_gro_receive()

2020-06-24 Thread Jason A. Donenfeld
On Wed, Jun 24, 2020 at 03:06:10PM -0600, Jason A. Donenfeld wrote:
> Hi Alexander,
> 
> This patch introduced a behavior change around GRO_DROP:
> 
> napi_skb_finish used to sometimes return GRO_DROP:
> 
> > -static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
> > +static gro_result_t napi_skb_finish(struct napi_struct *napi,
> > +   struct sk_buff *skb,
> > +   gro_result_t ret)
> >  {
> > switch (ret) {
> > case GRO_NORMAL:
> > -   if (netif_receive_skb_internal(skb))
> > -   ret = GRO_DROP;
> > +   gro_normal_one(napi, skb);
> >
> 
> But under your change, gro_normal_one and the various calls that makes
> never propagates its return value, and so GRO_DROP is never returned to
> the caller, even if something drops it.
> 
> Was this intentional? Or should I start looking into how to restore it?
> 
> Thanks,
> Jason

For some context, I'm consequently mulling over this change in my code,
since checking for GRO_DROP now constitutes dead code:

diff --git a/drivers/net/wireguard/receive.c b/drivers/net/wireguard/receive.c
index 91438144e4f7..9b2ab6fc91cd 100644
--- a/drivers/net/wireguard/receive.c
+++ b/drivers/net/wireguard/receive.c
@@ -414,14 +414,8 @@ static void wg_packet_consume_data_done(struct wg_peer 
*peer,
if (unlikely(routed_peer != peer))
goto dishonest_packet_peer;

-   if (unlikely(napi_gro_receive(>napi, skb) == GRO_DROP)) {
-   ++dev->stats.rx_dropped;
-   net_dbg_ratelimited("%s: Failed to give packet to userspace 
from peer %llu (%pISpfsc)\n",
-   dev->name, peer->internal_id,
-   >endpoint.addr);
-   } else {
-   update_rx_stats(peer, message_data_len(len_before_trim));
-   }
+   napi_gro_receive(>napi, skb);
+   update_rx_stats(peer, message_data_len(len_before_trim));
return;

 dishonest_packet_peer:



Re: [PATCH v2 net-next] net: core: use listified Rx for GRO_NORMAL in napi_gro_receive()

2020-06-24 Thread Jason A. Donenfeld
Hi Alexander,

This patch introduced a behavior change around GRO_DROP:

napi_skb_finish used to sometimes return GRO_DROP:

> -static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
> +static gro_result_t napi_skb_finish(struct napi_struct *napi,
> + struct sk_buff *skb,
> + gro_result_t ret)
>  {
>   switch (ret) {
>   case GRO_NORMAL:
> - if (netif_receive_skb_internal(skb))
> - ret = GRO_DROP;
> + gro_normal_one(napi, skb);
>

But under your change, gro_normal_one and the various calls that makes
never propagates its return value, and so GRO_DROP is never returned to
the caller, even if something drops it.

Was this intentional? Or should I start looking into how to restore it?

Thanks,
Jason


Re: [PATCH v2 net-next] net: core: use listified Rx for GRO_NORMAL in napi_gro_receive()

2019-10-16 Thread Alexander Lobakin

David Miller wrote 16.10.2019 04:16:

From: Alexander Lobakin 
Date: Mon, 14 Oct 2019 11:00:33 +0300


Commit 323ebb61e32b4 ("net: use listified RX for handling GRO_NORMAL
skbs") made use of listified skb processing for the users of
napi_gro_frags().
The same technique can be used in a way more common napi_gro_receive()
to speed up non-merged (GRO_NORMAL) skbs for a wide range of drivers
including gro_cells and mac80211 users.
This slightly changes the return value in cases where skb is being
dropped by the core stack, but it seems to have no impact on related
drivers' functionality.
gro_normal_batch is left untouched as it's very individual for every
single system configuration and might be tuned in manual order to
achieve an optimal performance.

Signed-off-by: Alexander Lobakin 
Acked-by: Edward Cree 


Applied, thank you.


David, Edward, Eric, Ilias,
thank you for your time.

Regards,
ᚷ ᛖ ᚢ ᚦ ᚠ ᚱ


Re: [PATCH v2 net-next] net: core: use listified Rx for GRO_NORMAL in napi_gro_receive()

2019-10-15 Thread David Miller
From: Alexander Lobakin 
Date: Mon, 14 Oct 2019 11:00:33 +0300

> Commit 323ebb61e32b4 ("net: use listified RX for handling GRO_NORMAL
> skbs") made use of listified skb processing for the users of
> napi_gro_frags().
> The same technique can be used in a way more common napi_gro_receive()
> to speed up non-merged (GRO_NORMAL) skbs for a wide range of drivers
> including gro_cells and mac80211 users.
> This slightly changes the return value in cases where skb is being
> dropped by the core stack, but it seems to have no impact on related
> drivers' functionality.
> gro_normal_batch is left untouched as it's very individual for every
> single system configuration and might be tuned in manual order to
> achieve an optimal performance.
> 
> Signed-off-by: Alexander Lobakin 
> Acked-by: Edward Cree 

Applied, thank you.


[PATCH v2 net-next] net: core: use listified Rx for GRO_NORMAL in napi_gro_receive()

2019-10-14 Thread Alexander Lobakin
Commit 323ebb61e32b4 ("net: use listified RX for handling GRO_NORMAL
skbs") made use of listified skb processing for the users of
napi_gro_frags().
The same technique can be used in a way more common napi_gro_receive()
to speed up non-merged (GRO_NORMAL) skbs for a wide range of drivers
including gro_cells and mac80211 users.
This slightly changes the return value in cases where skb is being
dropped by the core stack, but it seems to have no impact on related
drivers' functionality.
gro_normal_batch is left untouched as it's very individual for every
single system configuration and might be tuned in manual order to
achieve an optimal performance.

Signed-off-by: Alexander Lobakin 
Acked-by: Edward Cree 
---
 net/core/dev.c | 49 +
 1 file changed, 25 insertions(+), 24 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 8bc3dce71fc0..74f593986524 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5884,6 +5884,26 @@ struct packet_offload *gro_find_complete_by_type(__be16 
type)
 }
 EXPORT_SYMBOL(gro_find_complete_by_type);
 
+/* Pass the currently batched GRO_NORMAL SKBs up to the stack. */
+static void gro_normal_list(struct napi_struct *napi)
+{
+   if (!napi->rx_count)
+   return;
+   netif_receive_skb_list_internal(>rx_list);
+   INIT_LIST_HEAD(>rx_list);
+   napi->rx_count = 0;
+}
+
+/* Queue one GRO_NORMAL SKB up for list processing. If batch size exceeded,
+ * pass the whole batch up to the stack.
+ */
+static void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb)
+{
+   list_add_tail(>list, >rx_list);
+   if (++napi->rx_count >= gro_normal_batch)
+   gro_normal_list(napi);
+}
+
 static void napi_skb_free_stolen_head(struct sk_buff *skb)
 {
skb_dst_drop(skb);
@@ -5891,12 +5911,13 @@ static void napi_skb_free_stolen_head(struct sk_buff 
*skb)
kmem_cache_free(skbuff_head_cache, skb);
 }
 
-static gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb)
+static gro_result_t napi_skb_finish(struct napi_struct *napi,
+   struct sk_buff *skb,
+   gro_result_t ret)
 {
switch (ret) {
case GRO_NORMAL:
-   if (netif_receive_skb_internal(skb))
-   ret = GRO_DROP;
+   gro_normal_one(napi, skb);
break;
 
case GRO_DROP:
@@ -5928,7 +5949,7 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, 
struct sk_buff *skb)
 
skb_gro_reset_offset(skb);
 
-   ret = napi_skb_finish(dev_gro_receive(napi, skb), skb);
+   ret = napi_skb_finish(napi, skb, dev_gro_receive(napi, skb));
trace_napi_gro_receive_exit(ret);
 
return ret;
@@ -5974,26 +5995,6 @@ struct sk_buff *napi_get_frags(struct napi_struct *napi)
 }
 EXPORT_SYMBOL(napi_get_frags);
 
-/* Pass the currently batched GRO_NORMAL SKBs up to the stack. */
-static void gro_normal_list(struct napi_struct *napi)
-{
-   if (!napi->rx_count)
-   return;
-   netif_receive_skb_list_internal(>rx_list);
-   INIT_LIST_HEAD(>rx_list);
-   napi->rx_count = 0;
-}
-
-/* Queue one GRO_NORMAL SKB up for list processing.  If batch size exceeded,
- * pass the whole batch up to the stack.
- */
-static void gro_normal_one(struct napi_struct *napi, struct sk_buff *skb)
-{
-   list_add_tail(>list, >rx_list);
-   if (++napi->rx_count >= gro_normal_batch)
-   gro_normal_list(napi);
-}
-
 static gro_result_t napi_frags_finish(struct napi_struct *napi,
  struct sk_buff *skb,
  gro_result_t ret)
-- 
2.23.0