Netdev List
 help / color / mirror / Atom feed
* [PATCH 3/6] gtp: unify genl_find_pdp and prepare for per socket lookup
From: Andreas Schultz @ 2017-01-30 16:31 UTC (permalink / raw)
  To: Pablo Neira; +Cc: netdev, Harald Welte, Lionel Gauthier, openbsc
In-Reply-To: <20170130163200.17070-1-aschultz@tpip.net>

This unifies duplicate code into a helper. It also prepares the
groundwork to add a lookup version that uses the socket to find
attache pdp contexts.

Signed-off-by: Andreas Schultz <aschultz@tpip.net>
---
 drivers/net/gtp.c | 120 +++++++++++++++++++++++-------------------------------
 1 file changed, 51 insertions(+), 69 deletions(-)

diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index c96c71f..6b7a3c2 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -1027,47 +1027,62 @@ static int gtp_genl_new_pdp(struct sk_buff *skb, struct genl_info *info)
 	return err;
 }
 
+static struct pdp_ctx *gtp_genl_find_pdp_by_link(struct sk_buff *skb,
+						 struct genl_info *info)
+{
+	struct gtp_dev *gtp;
+
+	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
+	if (!gtp)
+		return ERR_PTR(-ENODEV);
+
+	if (info->attrs[GTPA_MS_ADDRESS]) {
+		__be32 ip = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
+
+		return ipv4_pdp_find(gtp, ip);
+	} else if (info->attrs[GTPA_VERSION]) {
+		u32 gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
+
+		if (gtp_version == GTP_V0 && info->attrs[GTPA_TID])
+			return gtp0_pdp_find(gtp, nla_get_u64(
+						     info->attrs[GTPA_TID]));
+		else if (gtp_version == GTP_V1 && info->attrs[GTPA_I_TEI])
+			return gtp1_pdp_find(gtp, nla_get_u32(
+						     info->attrs[GTPA_I_TEI]));
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static struct pdp_ctx *gtp_genl_find_pdp(struct sk_buff *skb,
+					 struct genl_info *info)
+{
+	struct pdp_ctx *pctx;
+
+	if (info->attrs[GTPA_LINK])
+		pctx = gtp_genl_find_pdp_by_link(skb, info);
+	else
+		pctx = ERR_PTR(-EINVAL);
+
+	if (!pctx)
+		pctx = ERR_PTR(-ENOENT);
+
+	return pctx;
+}
+
 static int gtp_genl_del_pdp(struct sk_buff *skb, struct genl_info *info)
 {
 	struct pdp_ctx *pctx;
-	struct gtp_dev *gtp;
 	int err = 0;
 
-	if (!info->attrs[GTPA_VERSION] ||
-	    !info->attrs[GTPA_LINK])
+	if (!info->attrs[GTPA_VERSION])
 		return -EINVAL;
 
 	rcu_read_lock();
 
-	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
-	if (!gtp) {
-		err = -ENODEV;
-		goto out_unlock;
-	}
-
-	switch (nla_get_u32(info->attrs[GTPA_VERSION])) {
-	case GTP_V0:
-		if (!info->attrs[GTPA_TID]) {
-			err = -EINVAL;
-			goto out_unlock;
-		}
-		pctx = gtp0_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_TID]));
-		break;
-	case GTP_V1:
-		if (!info->attrs[GTPA_I_TEI]) {
-			err = -EINVAL;
-			goto out_unlock;
-		}
-		pctx = gtp1_pdp_find(gtp, nla_get_u64(info->attrs[GTPA_I_TEI]));
-		break;
-
-	default:
-		err = -EINVAL;
-		goto out_unlock;
-	}
-
-	if (!pctx) {
-		err = -ENOENT;
+	pctx = gtp_genl_find_pdp(skb, info);
+	if (IS_ERR(pctx)) {
+		err = PTR_ERR(pctx);
 		goto out_unlock;
 	}
 
@@ -1129,49 +1144,16 @@ static int gtp_genl_get_pdp(struct sk_buff *skb, struct genl_info *info)
 {
 	struct pdp_ctx *pctx = NULL;
 	struct sk_buff *skb2;
-	struct gtp_dev *gtp;
-	u32 gtp_version;
 	int err;
 
-	if (!info->attrs[GTPA_VERSION] ||
-	    !info->attrs[GTPA_LINK])
+	if (!info->attrs[GTPA_VERSION])
 		return -EINVAL;
 
-	gtp_version = nla_get_u32(info->attrs[GTPA_VERSION]);
-	switch (gtp_version) {
-	case GTP_V0:
-	case GTP_V1:
-		break;
-	default:
-		return -EINVAL;
-	}
-
 	rcu_read_lock();
 
-	gtp = gtp_genl_find_dev(sock_net(skb->sk), info->attrs);
-	if (!gtp) {
-		err = -ENODEV;
-		goto err_unlock;
-	}
-
-	if (gtp_version == GTP_V0 &&
-	    info->attrs[GTPA_TID]) {
-		u64 tid = nla_get_u64(info->attrs[GTPA_TID]);
-
-		pctx = gtp0_pdp_find(gtp, tid);
-	} else if (gtp_version == GTP_V1 &&
-		 info->attrs[GTPA_I_TEI]) {
-		u32 tid = nla_get_u32(info->attrs[GTPA_I_TEI]);
-
-		pctx = gtp1_pdp_find(gtp, tid);
-	} else if (info->attrs[GTPA_MS_ADDRESS]) {
-		__be32 ip = nla_get_be32(info->attrs[GTPA_MS_ADDRESS]);
-
-		pctx = ipv4_pdp_find(gtp, ip);
-	}
-
-	if (pctx == NULL) {
-		err = -ENOENT;
+	pctx = gtp_genl_find_pdp(skb, info);
+	if (IS_ERR(pctx)) {
+		err = PTR_ERR(pctx);
 		goto err_unlock;
 	}
 
-- 
2.10.2

^ permalink raw reply related

* Re: [PATCH 0/6 v3] kvmalloc
From: Daniel Borkmann @ 2017-01-30 16:45 UTC (permalink / raw)
  To: Michal Hocko
  Cc: Alexei Starovoitov, Andrew Morton, Vlastimil Babka, Mel Gorman,
	Johannes Weiner, linux-mm, LKML, netdev@vger.kernel.org,
	marcelo.leitner
In-Reply-To: <20170130162822.GC4664@dhcp22.suse.cz>

On 01/30/2017 05:28 PM, Michal Hocko wrote:
> On Mon 30-01-17 17:15:08, Daniel Borkmann wrote:
>> On 01/30/2017 08:56 AM, Michal Hocko wrote:
>>> On Fri 27-01-17 21:12:26, Daniel Borkmann wrote:
>>>> On 01/27/2017 11:05 AM, Michal Hocko wrote:
>>>>> On Thu 26-01-17 21:34:04, Daniel Borkmann wrote:
>>> [...]
>>>>>> So to answer your second email with the bpf and netfilter hunks, why
>>>>>> not replacing them with kvmalloc() and __GFP_NORETRY flag and add that
>>>>>> big fat FIXME comment above there, saying explicitly that __GFP_NORETRY
>>>>>> is not harmful though has only /partial/ effect right now and that full
>>>>>> support needs to be implemented in future. That would still be better
>>>>>> that not having it, imo, and the FIXME would make expectations clear
>>>>>> to anyone reading that code.
>>>>>
>>>>> Well, we can do that, I just would like to prevent from this (ab)use
>>>>> if there is no _real_ and _sensible_ usecase for it. Having a real bug
>>>>
>>>> Understandable.
>>>>
>>>>> report or a fallback mechanism you are mentioning above would justify
>>>>> the (ab)use IMHO. But that abuse would be documented properly and have a
>>>>> real reason to exist. That sounds like a better approach to me.
>>>>>
>>>>> But if you absolutely _insist_ I can change that.
>>>>
>>>> Yeah, please do (with a big FIXME comment as mentioned), this originally
>>>> came from a real bug report. Anyway, feel free to add my Acked-by then.
>>>
>>> Thanks! I will repost the whole series today.
>>
>> Looks like I got only Cc'ed on the cover letter of your v3 from today
>> (should have been v4 actually?).
>
> Yes
>
>> Anyway, I looked up the last patch
>> on lkml [1] and it seems you forgot the __GFP_NORETRY we talked about?
>
> I misread your response. I thought you were OK with the FIXME
> explanation.
>
>> At least that was what was discussed above (insisting on __GFP_NORETRY
>> plus FIXME comment) for providing my Acked-by then. Can you still fix
>> that up in a final respin?
>
> I will probably just drop that last patch instead. I am not convinced
> that we should bend the new API over and let people mimic that
> throughout the code. I have just seen too many examples of this pattern
> already.
>
> I would also like to prevent the next rebase, unless there any issues
> with some patches of course.

Ok, I'm fine with that as well.

Thanks,
Daniel

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply

* Re: [PATCH net-next 1/4] mlx5: Make building eswitch configurable
From: Alexei Starovoitov @ 2017-01-30 16:45 UTC (permalink / raw)
  To: Saeed Mahameed
  Cc: Tom Herbert, Or Gerlitz, Saeed Mahameed, David Miller,
	Linux Netdev List, Kernel Team
In-Reply-To: <CALzJLG9OksXW5JAZiPoSfKtTF_z8Te9UDP9bm_XhXAp-FwmwEw@mail.gmail.com>

On 1/29/17 1:11 AM, Saeed Mahameed wrote:
>
> ConnectX4/5 and hopefully so on .. provide three different isolated
> steering layers:
>
> 3. vport layer: avaialbe for any PF/VF vport nic driver instance
> (netdevice), it allows vlan/mac filtering
>   ,RSS hashing and n-tuple steering (for both encapsulated and
> nonencapsulated traffic) and RFS steering. ( the code above only
> writes flow entries of a PF/VF to its own vport flow tables, there is
> another mechanism to propagate l2 steering rules down to eswitch from
> the vport layer.
>
> 2. eswitch layer: Available for PFs only with
> HCA_CAP.vport_group_manager capability set.
> it allows steering between PF and different VFs on the same host (vlan
> mac steering and ACL filters in sriov legacy mode, and fancy n-tuple
> steering and offloads for switchdev mode - eswitch_offloads.c - )
> if this table is not create the default is pass-throu traffic to PF
>
> 1. L2 table: Available for PFs only with HCA_CAP.vport_group_manager
> capability set.
> needed for MH configurations and only PF is allowed and should write
> "request UC MAC - set_l2_table_entry" on behalf of the PF itself and
> it's own VFs.
>
> - On a bare metal machine only layer 3 is required (all traffic is
> passed to the PF vport).
> - On a MH configuration layer 3 and 1 are required.
> - On a SRIOV configuration layer 3 and 2 are required.
> - On MH with SRIOV all layers are required.
>
> in the driver, eswitch and L2 layers are handled by PF@eswitch.c.
>
> So for your question:
>
> PF always init_eswitch ( no eswitch -sriov- tables are created), and
> the eswitch will start listening for vport_change_events.
>
> A PF/VF or netdev vport instance on any steering changes updates
> should call  mlx5e_vport_context_update[1]
>
> vport_context_update is A FW command that will store the current
> UC/MC/VLAN list and promiscuity info of a vport.
>
> The FW will generate an event to the PF driver eswitch manager (vport
> manager) mlx5_eswitch_vport_event [2], and the PF eswitch will call
> set_l2_table_entry for each UC mac on each vport change event of any
> vport (including its own vport), in case of SRIOV is enabled it will
> update eswitch tables as well.
>
> To simplify my answer the function calls are:
> Vport VF/PF netdevice:
> mlx5e_set_rx_mode_work
>      mlx5e_vport_context_update
>         mlx5e_vport_context_update_addr_list  --> FW event will be
> generated to the PF esiwtch manager
>
> PF eswitch manager(eswitch.c) on a vport change FW event:
> mlx5_eswitch_vport_event
>        esw_vport_change_handler
>             esw_vport_change_handle_locked
>                     esw_apply_vport_addr_list
>                                esw_add_uc_addr
>                                       set_l2_table_entry --> this will
> update the l2 table in case MH is enabled.

all makes sense. To test this logic I added printk-s
to above functions, but I only see:
# ip link set eth0 addr 24:8a:07:47:2b:6e
[  148.861914] mlx5e_vport_context_update_addr_list: is_uc 1 err 0
[  148.875152] mlx5e_vport_context_update_addr_list: is_uc 0 err 0

MLX5_EVENT_TYPE_NIC_VPORT_CHANGE doesn't come into mlx5_eq_int().
Yet nic seems to work fine. Packets come and go.

broken firmware or expected behavior?

# ethtool -i eth0
driver: mlx5_core
version: 3.0-1 (January 2015)
firmware-version: 14.16.2024

^ permalink raw reply

* Re: [PATCH v2] xen-netfront: Fix Rx stall during network stress and OOM
From: Vineeth Remanan Pillai @ 2017-01-30 16:47 UTC (permalink / raw)
  To: Boris Ostrovsky, linux-kernel
  Cc: netdev, Paul Durrant, Wei Liu, David Miller, xen-devel
In-Reply-To: <38ccfaea-0a65-a6f3-c19a-e6f9c0d4ef76@oracle.com>


On 01/29/2017 03:09 PM, Boris Ostrovsky wrote:
>
> There are couple of problems with this patch.
> 1. The 'if' clause now evaluates to true on pretty much every call to 
> xennet_alloc_rx_buffers().
Thanks for catching this. In my testing I did not notice this - mostly 
because of the nature of the workload in my testing.

> 2. It tickles a latent bug during resume where the timer triggers 
> before we re-connect. The trouble is that we now try to dereference 
> queue->rx.sring which is NULL since we disconnect in 
> netfront_resume(). (Curiously, I only observe it with 32-bit guests)
I think we may hit this bug after removing the timer as well. We call 
RING_PUSH_REQUESTS_AND_CHECK_NOTIFY soon after, which also dereference 
queue->rx.sring.

Thanks,
Vineeth


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply

* Re: [PATCH net-next v3 0/4] net: ipv6: Improve user experience with multipath routes
From: Nicolas Dichtel @ 2017-01-30 17:03 UTC (permalink / raw)
  To: David Ahern, Roopa Prabhu; +Cc: netdev
In-Reply-To: <0e9b2b4e-fc48-e21d-7b1f-3df45992e5e3@cumulusnetworks.com>

Le 30/01/2017 à 16:23, David Ahern a écrit :
> On 1/30/17 4:07 AM, Nicolas Dichtel wrote:
>> Le 29/01/2017 à 19:02, David Ahern a écrit :
>> [snip]
>>> Data centers are moving to L3, and multipath is a big part of that. Anyone who looks at ip -6 route enough knows it gets painful mentally pulling the individual routes into a single one.
>> I agree, but it's only an iproute2 problem. iproute2 could group routes to have
>> a better output, there is no need to have a kernel patch for this ;-)
>>
> 
> iproute2 is not the only rtnetlink user. The comment above uses ip show as an example. libnl has a workaround for IPv6 to update route objects versus replacing them - unnecessary complexity that does not need to replicated to iproute2, Quagga/FRR or python libraries implementing rtnetlink. Really, RTA_MULTIPATH support in notifications should have been added when multipath support was added to the IPv6. Patch 3 is mostly a refactoring of rt6_fill_node to fill in nexthop information. This could have been done 4+ years ago when RTA_MULTIPATH route adds was added to the stack.
> 
Like I said, I fully agree that RTA_MULTIPATH is better for the dump. For the
notifications, I'm not convinced. I did not this 4 years ago on purpose ;-)

I don't think that ipv4 is the right reference because the implementation is
really different. ipv6 is more flexible and this implies differences in the
notifications.

^ permalink raw reply

* [PATCH] ethtool: Add support for 2500baseT/5000baseT link modes
From: Pavel Belous @ 2017-01-30 17:03 UTC (permalink / raw)
  To: linville; +Cc: netdev

This patch introduce ethtool support for 2500BaseT and 5000BaseT link modes
from new IEEE 802.3bz standard.

ethtool-copy.h file sync with net.

Signed-off-by: Pavel Belous <pavel.s.belous@gmail.com>
---
 ethtool-copy.h | 4 +++-
 ethtool.8.in   | 4 +++-
 ethtool.c      | 6 ++++++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/ethtool-copy.h b/ethtool-copy.h
index 3d299e3..06fc04c 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -1382,6 +1382,8 @@ enum ethtool_link_mode_bit_indices {
 	ETHTOOL_LINK_MODE_10000baseLR_Full_BIT	= 44,
 	ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT	= 45,
 	ETHTOOL_LINK_MODE_10000baseER_Full_BIT	= 46,
+	ETHTOOL_LINK_MODE_2500baseT_Full_BIT = 47,
+	ETHTOOL_LINK_MODE_5000baseT_Full_BIT = 48,
 
 
 	/* Last allowed bit for __ETHTOOL_LINK_MODE_LEGACY_MASK is bit
@@ -1391,7 +1393,7 @@ enum ethtool_link_mode_bit_indices {
 	 */
 
 	__ETHTOOL_LINK_MODE_LAST
-	  = ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
+	  = ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
 };
 
 #define __ETHTOOL_LINK_MODE_LEGACY_MASK(base_name)	\
diff --git a/ethtool.8.in b/ethtool.8.in
index 5c36c06..1e564ae 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -588,7 +588,9 @@ lB	l	lB.
 0x020	1000baseT Full
 0x20000	1000baseKX Full
 0x20000000000	1000baseX Full
-0x8000	2500baseX Full	(not supported by IEEE standards)
+0x800000000000  2500baseT Full
+0x8000	2500baseX Full	(not supported by IEEE standards)'
+0x1000000000000  5000baseT Full
 0x1000	10000baseT Full
 0x40000	10000baseKX4 Full
 0x80000	10000baseKR Full
diff --git a/ethtool.c b/ethtool.c
index 7af039e..031afe8 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -529,6 +529,8 @@ static void init_global_link_mode_masks(void)
 		ETHTOOL_LINK_MODE_10000baseLR_Full_BIT,
 		ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
 		ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
+		ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+		ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
 	};
 	static const enum ethtool_link_mode_bit_indices
 		additional_advertised_flags_bits[] = {
@@ -681,6 +683,10 @@ static void dump_link_caps(const char *prefix, const char *an_prefix,
 		  "10000baseLRM/Full" },
 		{ 0, ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
 		  "10000baseER/Full" },
+                { 0, ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
+                  "2500baseT/Full" },
+                { 0, ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
+                  "5000baseT/Full" },
 	};
 	int indent;
 	int did1, new_line_pend, i;
-- 
2.7.4

^ permalink raw reply related

* Re: [PATCH v2] xen-netfront: Fix Rx stall during network stress and OOM
From: Boris Ostrovsky @ 2017-01-30 17:06 UTC (permalink / raw)
  To: Vineeth Remanan Pillai, linux-kernel
  Cc: netdev, Paul Durrant, Wei Liu, David Miller, xen-devel
In-Reply-To: <989bd104-13a9-f25f-b857-24ec49781f9c@amazon.com>

On 01/30/2017 11:47 AM, Vineeth Remanan Pillai wrote:
>
>> 2. It tickles a latent bug during resume where the timer triggers
>> before we re-connect. The trouble is that we now try to dereference
>> queue->rx.sring which is NULL since we disconnect in
>> netfront_resume(). (Curiously, I only observe it with 32-bit guests)
> I think we may hit this bug after removing the timer as well. We call
> RING_PUSH_REQUESTS_AND_CHECK_NOTIFY soon after, which also dereference
> queue->rx.sring.


If the timer is deleted in xennet_disconnect_backend() then why would
anyone be pushing anything to the backend after that?

-boris

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply

* RE: [patch net-next v2 2/4] net/sched: Introduce sample tc action
From: Yotam Gigi @ 2017-01-30 16:49 UTC (permalink / raw)
  To: Cong Wang, Jiri Pirko
  Cc: Linux Kernel Network Developers, David Miller, Ido Schimmel,
	Elad Raz, Nogah Frankel, Or Gerlitz, Jamal Hadi Salim,
	geert+renesas@glider.be, Stephen Hemminger, Guenter Roeck,
	Roopa Prabhu, John Fastabend, Simon Horman, Roman Mashak
In-Reply-To: <CAM_iQpUHrhkVtgrA37btQ9sn0UPeYgkqnRx=3HZoLan-soT8hg@mail.gmail.com>

>-----Original Message-----
>From: Yotam Gigi
>Sent: Friday, January 27, 2017 8:09 AM
>To: 'Cong Wang' <xiyou.wangcong@gmail.com>; Jiri Pirko <jiri@resnulli.us>
>Cc: Linux Kernel Network Developers <netdev@vger.kernel.org>; David Miller
><davem@davemloft.net>; Ido Schimmel <idosch@mellanox.com>; Elad Raz
><eladr@mellanox.com>; Nogah Frankel <nogahf@mellanox.com>; Or Gerlitz
><ogerlitz@mellanox.com>; Jamal Hadi Salim <jhs@mojatatu.com>;
>geert+renesas@glider.be; Stephen Hemminger <stephen@networkplumber.org>;
>Guenter Roeck <linux@roeck-us.net>; Roopa Prabhu
><roopa@cumulusnetworks.com>; John Fastabend <john.fastabend@gmail.com>;
>Simon Horman <simon.horman@netronome.com>; Roman Mashak
><mrv@mojatatu.com>
>Subject: RE: [patch net-next v2 2/4] net/sched: Introduce sample tc action
>
>>-----Original Message-----
>>From: Cong Wang [mailto:xiyou.wangcong@gmail.com]
>>Sent: Thursday, January 26, 2017 1:30 AM
>>To: Jiri Pirko <jiri@resnulli.us>
>>Cc: Linux Kernel Network Developers <netdev@vger.kernel.org>; David Miller
>><davem@davemloft.net>; Yotam Gigi <yotamg@mellanox.com>; Ido Schimmel
>><idosch@mellanox.com>; Elad Raz <eladr@mellanox.com>; Nogah Frankel
>><nogahf@mellanox.com>; Or Gerlitz <ogerlitz@mellanox.com>; Jamal Hadi Salim
>><jhs@mojatatu.com>; geert+renesas@glider.be; Stephen Hemminger
>><stephen@networkplumber.org>; Guenter Roeck <linux@roeck-us.net>; Roopa
>>Prabhu <roopa@cumulusnetworks.com>; John Fastabend
>><john.fastabend@gmail.com>; Simon Horman
><simon.horman@netronome.com>;
>>Roman Mashak <mrv@mojatatu.com>
>>Subject: Re: [patch net-next v2 2/4] net/sched: Introduce sample tc action
>>
>>On Mon, Jan 23, 2017 at 2:07 AM, Jiri Pirko <jiri@resnulli.us> wrote:
>>> +
>>> +static int tcf_sample_init(struct net *net, struct nlattr *nla,
>>> +                          struct nlattr *est, struct tc_action **a, int ovr,
>>> +                          int bind)
>>> +{
>>> +       struct tc_action_net *tn = net_generic(net, sample_net_id);
>>> +       struct nlattr *tb[TCA_SAMPLE_MAX + 1];
>>> +       struct psample_group *psample_group;
>>> +       struct tc_sample *parm;
>>> +       struct tcf_sample *s;
>>> +       bool exists = false;
>>> +       int ret;
>>> +
>>> +       if (!nla)
>>> +               return -EINVAL;
>>> +       ret = nla_parse_nested(tb, TCA_SAMPLE_MAX, nla, sample_policy);
>>> +       if (ret < 0)
>>> +               return ret;
>>> +       if (!tb[TCA_SAMPLE_PARMS] || !tb[TCA_SAMPLE_RATE] ||
>>> +           !tb[TCA_SAMPLE_PSAMPLE_GROUP])
>>> +               return -EINVAL;
>>> +
>>> +       parm = nla_data(tb[TCA_SAMPLE_PARMS]);
>>> +
>>> +       exists = tcf_hash_check(tn, parm->index, a, bind);
>>> +       if (exists && bind)
>>> +               return 0;
>>> +
>>> +       if (!exists) {
>>> +               ret = tcf_hash_create(tn, parm->index, est, a,
>>> +                                     &act_sample_ops, bind, false);
>>> +               if (ret)
>>> +                       return ret;
>>> +               ret = ACT_P_CREATED;
>>> +       } else {
>>> +               tcf_hash_release(*a, bind);
>>> +               if (!ovr)
>>> +                       return -EEXIST;
>>> +       }
>>> +       s = to_sample(*a);
>>> +
>>> +       ASSERT_RTNL();
>>
>>Copy-n-paste from mirred aciton? This is not needed for you, mirred
>>needs it because of target netdevice.
>
>Ho, you are right. I will remove it.
>
>>
>>
>>> +       s->tcf_action = parm->action;
>>> +       s->rate = nla_get_u32(tb[TCA_SAMPLE_RATE]);
>>> +       s->psample_group_num =
>>nla_get_u32(tb[TCA_SAMPLE_PSAMPLE_GROUP]);
>>> +       psample_group = psample_group_get(net, s->psample_group_num);
>>> +       if (!psample_group)
>>> +               return -ENOMEM;
>>
>>I don't think you can just return here, needs tcf_hash_cleanup() for create
>>case, right?
>
>Will fix.
>
>>
>>
>>> +       RCU_INIT_POINTER(s->psample_group, psample_group);
>>> +
>>> +       if (tb[TCA_SAMPLE_TRUNC_SIZE]) {
>>> +               s->truncate = true;
>>> +               s->trunc_size = nla_get_u32(tb[TCA_SAMPLE_TRUNC_SIZE]);
>>> +       }
>>
>>
>>Do you need tcf_lock here if RCU only protects ->psample_group??
>>
>
>You are right. I need to protect in case of update.

Cong, after some thinking I think I don't really need the tcf_lock here. I
don't really care if the truncate, trunc_size, rate and tcf_action are
consistent among themselves - the only parameter that I care about is the
psample_group pointer, and it is protected via RCU. As far as I see, there is
no need to lock here.

I do need to take the tcf_lock to protect the statistics update in the 
tcf_sample_act code, as far as I see.

Am I missing something?

>
>I will send a fixup patch in the following days. Thanks!
>
>>
>>> +
>>> +       if (ret == ACT_P_CREATED)
>>> +               tcf_hash_insert(tn, *a);
>>> +       return ret;
>>> +}
>>> +
>>
>>
>>Thanks.

^ permalink raw reply

* Re: [PATCH v2] xen-netfront: Fix Rx stall during network stress and OOM
From: Vineeth Remanan Pillai @ 2017-01-30 17:13 UTC (permalink / raw)
  To: Boris Ostrovsky
  Cc: linux-kernel, David Miller, netdev, Wei Liu, Paul Durrant,
	xen-devel
In-Reply-To: <30069778-9509-8112-5089-2eea7b679236@oracle.com>


On 01/30/2017 09:06 AM, Boris Ostrovsky wrote:
> On 01/30/2017 11:47 AM, Vineeth Remanan Pillai wrote:
>
>>> 2. It tickles a latent bug during resume where the timer triggers
>>> before we re-connect. The trouble is that we now try to dereference
>>> queue->rx.sring which is NULL since we disconnect in
>>> netfront_resume(). (Curiously, I only observe it with 32-bit guests)
>> I think we may hit this bug after removing the timer as well. We call
>> RING_PUSH_REQUESTS_AND_CHECK_NOTIFY soon after, which also dereference
>> queue->rx.sring.
> If the timer is deleted in xennet_disconnect_backend() then why would
> anyone be pushing anything to the backend after that?
Sorry, I got the ordering wrong. Thanks for the clarification..

Thanks,
Vineeth

^ permalink raw reply

* Re: [PATCH net] packet: call fanout_release, while UNREGISTERING a netdev
From: Eric Dumazet @ 2017-01-30 17:26 UTC (permalink / raw)
  To: David Miller; +Cc: anoob.soman, netdev
In-Reply-To: <20161006.205052.1380596858044266995.davem@davemloft.net>

On Thu, 2016-10-06 at 20:50 -0400, David Miller wrote:
> From: Anoob Soman <anoob.soman@citrix.com>
> Date: Wed, 5 Oct 2016 15:12:54 +0100
> 
> > If a socket has FANOUT sockopt set, a new proto_hook is registered
> > as part of fanout_add(). When processing a NETDEV_UNREGISTER event in
> > af_packet, __fanout_unlink is called for all sockets, but prot_hook which was
> > registered as part of fanout_add is not removed. Call fanout_release, on a
> > NETDEV_UNREGISTER, which removes prot_hook and removes fanout from the
> > fanout_list.
> > 
> > This fixes BUG_ON(!list_empty(&dev->ptype_specific)) in netdev_run_todo()
> > 
> > Signed-off-by: Anoob Soman <anoob.soman@citrix.com>
> 
> Applied and queued up for -stable, thanks.

This commit (6664498280cf "packet: call fanout_release, while
UNREGISTERING a netdev")
looks buggy :

We end up calling fanout_release() while holding a spinlock
( spin_lock(&po->bind_lock); )

But fanout_release() grabs a mutex ( mutex_lock(&fanout_mutex) ), and
this is absolutely not valid while holding a spinlock.

Anoob, can you cook a fix, I guess you have a way to reproduce the thing
that wanted a kernel patch ?

(Please build your test kernel with CONFIG_LOCKDEP=y)

Thanks.

^ permalink raw reply

* Re: [PATCH net] mlx4: xdp_prog becomes inactive after ethtool '-L' or '-G'
From: Tariq Toukan @ 2017-01-30 17:18 UTC (permalink / raw)
  To: Martin KaFai Lau, netdev
  Cc: Brenden Blanco, Saeed Mahameed, Tariq Toukan, Kernel Team
In-Reply-To: <1485589251-3896393-1-git-send-email-kafai@fb.com>

Hi Martin,

Thanks for your patch.

It looks good to me, in general.
I just have one small comment below.

On 28/01/2017 9:40 AM, Martin KaFai Lau wrote:
> If the rx-queues ever get re-initialized (e.g. by changing the
> number of rx-queues with ethtool -L), the existing xdp_prog becomes
> inactive.
>
> The bug is that the xdp_prog ptr has not been carried over from
> the old rx-queues to the new rx-queues
>
> Fixes: 47a38e155037 ("net/mlx4_en: add support for fast rx drop bpf program")
> Signed-off-by: Martin KaFai Lau <kafai@fb.com>
> ---
...
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index 761f8b12399c..f4179086b3c6 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -2184,23 +2184,57 @@ static void mlx4_en_update_priv(struct mlx4_en_priv *dst,
>   
>   int mlx4_en_try_alloc_resources(struct mlx4_en_priv *priv,
>   				struct mlx4_en_priv *tmp,
> -				struct mlx4_en_port_profile *prof)
> +				struct mlx4_en_port_profile *prof,
> +				bool carry_xdp_prog)
>   {
> -	int t;
> +	struct bpf_prog *xdp_prog = NULL;
> +	int err;
> +	int i;
>   
>   	mlx4_en_copy_priv(tmp, priv, prof);
>   
> +	if (carry_xdp_prog) {
> +		/* All rx_rings has the same xdp_prog.  Pick the first one */
> +		xdp_prog = rcu_dereference_protected(
> +			priv->rx_ring[0]->xdp_prog,
> +			lockdep_is_held(&priv->mdev->state_lock));
> +
> +		if (xdp_prog) {
> +			xdp_prog = bpf_prog_add(xdp_prog, tmp->rx_ring_num);
> +			if (IS_ERR(xdp_prog)) {
> +				err = PTR_ERR(xdp_prog);
> +				xdp_prog = NULL;
> +				goto err_free;
> +			}
> +		}
> +	}
Why do you prefer dealing with xdp_prog in two stages? You can handle it 
all at once, after "mlx4_en_alloc_resources()" succeeds.
> +
>   	if (mlx4_en_alloc_resources(tmp)) {
>   		en_warn(priv,
>   			"%s: Resource allocation failed, using previous configuration\n",
>   			__func__);
> -		for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++) {
> -			kfree(tmp->tx_ring[t]);
> -			kfree(tmp->tx_cq[t]);
> -		}
> -		return -ENOMEM;
> +		err = -ENOMEM;
> +		goto err_free;
> +	}
> +
> +	if (xdp_prog) {
> +		for (i = 0; i < tmp->rx_ring_num; i++)
> +			rcu_assign_pointer(tmp->rx_ring[i]->xdp_prog,
> +					   xdp_prog);
>   	}
> +
>   	return 0;
> +
> +err_free:
> +	if (xdp_prog)
> +		bpf_prog_sub(xdp_prog, tmp->rx_ring_num);
> +
> +	for (i = 0; i < MLX4_EN_NUM_TX_TYPES; i++) {
> +		kfree(tmp->tx_ring[i]);
> +		kfree(tmp->tx_cq[i]);
> +	}
> +
> +	return err;
>   }
>   
>   void mlx4_en_safe_replace_resources(struct mlx4_en_priv *priv,
>
Regards,
Tariq Toukan.

^ permalink raw reply

* [PATCH] xen-netfront: Delete rx_refill_timer in xennet_disconnect_backend()
From: Boris Ostrovsky @ 2017-01-30 17:45 UTC (permalink / raw)
  To: jgross
  Cc: wei.liu2, netdev, linux-kernel, stable, vineethp, xen-devel,
	Boris Ostrovsky, paul.durrant

rx_refill_timer should be deleted as soon as we disconnect from the
backend since otherwise it is possible for the timer to go off before
we get to xennet_destroy_queues(). If this happens we may dereference
queue->rx.sring which is set to NULL in xennet_disconnect_backend().

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
CC: stable@vger.kernel.org
---
 drivers/net/xen-netfront.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 8315fe7..722fe9f 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1379,6 +1379,8 @@ static void xennet_disconnect_backend(struct netfront_info *info)
 	for (i = 0; i < num_queues && info->queues; ++i) {
 		struct netfront_queue *queue = &info->queues[i];
 
+		del_timer_sync(&queue->rx_refill_timer);
+
 		if (queue->tx_irq && (queue->tx_irq == queue->rx_irq))
 			unbind_from_irqhandler(queue->tx_irq, queue);
 		if (queue->tx_irq && (queue->tx_irq != queue->rx_irq)) {
@@ -1733,7 +1735,6 @@ static void xennet_destroy_queues(struct netfront_info *info)
 
 		if (netif_running(info->netdev))
 			napi_disable(&queue->napi);
-		del_timer_sync(&queue->rx_refill_timer);
 		netif_napi_del(&queue->napi);
 	}
 
-- 
1.8.3.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related

* Re: [PATCH 2/6] wl1251: Use request_firmware_prefer_user() for loading NVS calibration data
From: Tony Lindgren @ 2017-01-30 17:53 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Kalle Valo, Pali Rohár, Arend Van Spriel, Ming Lei,
	Luis R. Rodriguez, Greg Kroah-Hartman, David Gnedt, Michal Kazior,
	Daniel Wagner, Sebastian Reichel, Ivaylo Dimitrov, Aaro Koskinen,
	Grazvydas Ignotas, linux-kernel, linux-wireless, netdev
In-Reply-To: <20170127194012.GE20571@amd>

* Pavel Machek <pavel@ucw.cz> [170127 11:41]:
> On Fri 2017-01-27 17:23:07, Kalle Valo wrote:
> > Pali Rohár <pali.rohar@gmail.com> writes:
> > 
> > > On Friday 27 January 2017 14:26:22 Kalle Valo wrote:
> > >> Pali Rohár <pali.rohar@gmail.com> writes:
> > >> 
> > >> > 2) It was already tested that example NVS data can be used for N900 e.g.
> > >> > for SSH connection. If real correct data are not available it is better
> > >> > to use at least those example (and probably log warning message) so user
> > >> > can connect via SSH and start investigating where is problem.
> > >> 
> > >> I disagree. Allowing default calibration data to be used can be
> > >> unnoticed by user and left her wondering why wifi works so badly.
> > >
> > > So there are only two options:
> > >
> > > 1) Disallow it and so these users will have non-working wifi.
> > >
> > > 2) Allow those data to be used as fallback mechanism.
> > >
> > > And personally I'm against 1) because it will break wifi support for
> > > *all* Nokia N900 devices right now.
> > 
> > All two of them? :)
> 
> Umm. You clearly want a flock of angry penguins at your doorsteps :-).

Well this silly issue of symlinking and renaming nvs files in a standard
Linux distro was also hitting me on various devices with wl12xx/wl18xx
trying to use the same rootfs.

Why don't we just set a custom compatible property for n900 that then
picks up some other nvs file instead of the default?

Regards,

Tony

^ permalink raw reply

* [PATCH net-next v3 1/4] net: dsa: Hook {get,set}_rxnfc ethtool operations
From: Florian Fainelli @ 2017-01-30 17:48 UTC (permalink / raw)
  To: netdev; +Cc: davem, andrew, vivien.didelot, cphealy, Florian Fainelli
In-Reply-To: <20170130174843.29497-1-f.fainelli@gmail.com>

In preparation for adding support for CFP/TCAMP in the bcm_sf2 driver add the
plumbing to call into driver specific {get,set}_rxnfc operations.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 include/net/dsa.h |  8 ++++++++
 net/dsa/slave.c   | 26 ++++++++++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index b951e2ebda75..d5d618c3de64 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -377,6 +377,14 @@ struct dsa_switch_ops {
 	int	(*port_mdb_dump)(struct dsa_switch *ds, int port,
 				 struct switchdev_obj_port_mdb *mdb,
 				 int (*cb)(struct switchdev_obj *obj));
+
+	/*
+	 * RXNFC
+	 */
+	int	(*get_rxnfc)(struct dsa_switch *ds, int port,
+			     struct ethtool_rxnfc *nfc, u32 *rule_locs);
+	int	(*set_rxnfc)(struct dsa_switch *ds, int port,
+			     struct ethtool_rxnfc *nfc);
 };
 
 struct dsa_switch_driver {
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 08725286f79d..6881889e1a9b 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1002,6 +1002,30 @@ void dsa_cpu_port_ethtool_init(struct ethtool_ops *ops)
 	ops->get_strings = dsa_cpu_port_get_strings;
 }
 
+static int dsa_slave_get_rxnfc(struct net_device *dev,
+			       struct ethtool_rxnfc *nfc, u32 *rule_locs)
+{
+	struct dsa_slave_priv *p = netdev_priv(dev);
+	struct dsa_switch *ds = p->dp->ds;
+
+	if (!ds->ops->get_rxnfc)
+		return -EOPNOTSUPP;
+
+	return ds->ops->get_rxnfc(ds, p->dp->index, nfc, rule_locs);
+}
+
+static int dsa_slave_set_rxnfc(struct net_device *dev,
+			       struct ethtool_rxnfc *nfc)
+{
+	struct dsa_slave_priv *p = netdev_priv(dev);
+	struct dsa_switch *ds = p->dp->ds;
+
+	if (!ds->ops->set_rxnfc)
+		return -EOPNOTSUPP;
+
+	return ds->ops->set_rxnfc(ds, p->dp->index, nfc);
+}
+
 static const struct ethtool_ops dsa_slave_ethtool_ops = {
 	.get_drvinfo		= dsa_slave_get_drvinfo,
 	.get_regs_len		= dsa_slave_get_regs_len,
@@ -1020,6 +1044,8 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
 	.get_eee		= dsa_slave_get_eee,
 	.get_link_ksettings	= dsa_slave_get_link_ksettings,
 	.set_link_ksettings	= dsa_slave_set_link_ksettings,
+	.get_rxnfc		= dsa_slave_get_rxnfc,
+	.set_rxnfc		= dsa_slave_set_rxnfc,
 };
 
 static const struct net_device_ops dsa_slave_netdev_ops = {
-- 
2.9.3

^ permalink raw reply related

* [PATCH net-next v3 3/4] net: dsa: bcm_sf2: Add CFP registers definitions
From: Florian Fainelli @ 2017-01-30 17:48 UTC (permalink / raw)
  To: netdev; +Cc: davem, andrew, vivien.didelot, cphealy, Florian Fainelli
In-Reply-To: <20170130174843.29497-1-f.fainelli@gmail.com>

Add Compact Field Processor definitions for the Broadcom Starfighter 2
and compatible versions of the switch.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/bcm_sf2_regs.h | 146 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 146 insertions(+)

diff --git a/drivers/net/dsa/bcm_sf2_regs.h b/drivers/net/dsa/bcm_sf2_regs.h
index 6b63c00928ba..26052450091e 100644
--- a/drivers/net/dsa/bcm_sf2_regs.h
+++ b/drivers/net/dsa/bcm_sf2_regs.h
@@ -255,4 +255,150 @@ enum bcm_sf2_reg_offs {
 #define CORE_EEE_EN_CTRL		0x24800
 #define CORE_EEE_LPI_INDICATE		0x24810
 
+#define CORE_CFP_ACC			0x28000
+#define  OP_STR_DONE			(1 << 0)
+#define  OP_SEL_SHIFT			1
+#define  OP_SEL_READ			(1 << OP_SEL_SHIFT)
+#define  OP_SEL_WRITE			(2 << OP_SEL_SHIFT)
+#define  OP_SEL_SEARCH			(4 << OP_SEL_SHIFT)
+#define  OP_SEL_MASK			(7 << OP_SEL_SHIFT)
+#define  CFP_RAM_CLEAR			(1 << 4)
+#define  RAM_SEL_SHIFT			10
+#define  TCAM_SEL			(1 << RAM_SEL_SHIFT)
+#define  ACT_POL_RAM			(2 << RAM_SEL_SHIFT)
+#define  RATE_METER_RAM			(4 << RAM_SEL_SHIFT)
+#define  GREEN_STAT_RAM			(8 << RAM_SEL_SHIFT)
+#define  YELLOW_STAT_RAM		(16 << RAM_SEL_SHIFT)
+#define  RED_STAT_RAM			(24 << RAM_SEL_SHIFT)
+#define  RAM_SEL_MASK			(0x1f << RAM_SEL_SHIFT)
+#define  TCAM_RESET			(1 << 15)
+#define  XCESS_ADDR_SHIFT		16
+#define  XCESS_ADDR_MASK		0xff
+#define  SEARCH_STS			(1 << 27)
+#define  RD_STS_SHIFT			28
+#define  RD_STS_TCAM			(1 << RD_STS_SHIFT)
+#define  RD_STS_ACT_POL_RAM		(2 << RD_STS_SHIFT)
+#define  RD_STS_RATE_METER_RAM		(4 << RD_STS_SHIFT)
+#define  RD_STS_STAT_RAM		(8 << RD_STS_SHIFT)
+
+#define CORE_CFP_RATE_METER_GLOBAL_CTL	0x28010
+
+#define CORE_CFP_DATA_PORT_0		0x28040
+#define CORE_CFP_DATA_PORT(x)		(CORE_CFP_DATA_PORT_0 + \
+					(x) * 0x10)
+
+/* UDF_DATA7 */
+#define L3_FRAMING_SHIFT		24
+#define L3_FRAMING_MASK			(0x3 << L3_FRAMING_SHIFT)
+#define IPPROTO_SHIFT			8
+#define IPPROTO_MASK			(0xff << IPPROTO_SHIFT)
+#define IP_FRAG				(1 << 7)
+
+/* UDF_DATA0 */
+#define  SLICE_VALID			3
+#define  SLICE_NUM_SHIFT		2
+#define  SLICE_NUM(x)			((x) << SLICE_NUM_SHIFT)
+
+#define CORE_CFP_MASK_PORT_0		0x280c0
+
+#define CORE_CFP_MASK_PORT(x)		(CORE_CFP_MASK_PORT_0 + \
+					(x) * 0x10)
+
+#define CORE_ACT_POL_DATA0		0x28140
+#define  VLAN_BYP			(1 << 0)
+#define  EAP_BYP			(1 << 1)
+#define  STP_BYP			(1 << 2)
+#define  REASON_CODE_SHIFT		3
+#define  REASON_CODE_MASK		0x3f
+#define  LOOP_BK_EN			(1 << 9)
+#define  NEW_TC_SHIFT			10
+#define  NEW_TC_MASK			0x7
+#define  CHANGE_TC			(1 << 13)
+#define  DST_MAP_IB_SHIFT		14
+#define  DST_MAP_IB_MASK		0x1ff
+#define  CHANGE_FWRD_MAP_IB_SHIFT	24
+#define  CHANGE_FWRD_MAP_IB_MASK	0x3
+#define  CHANGE_FWRD_MAP_IB_NO_DEST	(0 << CHANGE_FWRD_MAP_IB_SHIFT)
+#define  CHANGE_FWRD_MAP_IB_REM_ARL	(1 << CHANGE_FWRD_MAP_IB_SHIFT)
+#define  CHANGE_FWRD_MAP_IB_REP_ARL	(2 << CHANGE_FWRD_MAP_IB_SHIFT)
+#define  CHANGE_FWRD_MAP_IB_ADD_DST	(3 << CHANGE_FWRD_MAP_IB_SHIFT)
+#define  NEW_DSCP_IB_SHIFT		26
+#define  NEW_DSCP_IB_MASK		0x3f
+
+#define CORE_ACT_POL_DATA1		0x28150
+#define  CHANGE_DSCP_IB			(1 << 0)
+#define  DST_MAP_OB_SHIFT		1
+#define  DST_MAP_OB_MASK		0x3ff
+#define  CHANGE_FWRD_MAP_OB_SHIT	11
+#define  CHANGE_FWRD_MAP_OB_MASK	0x3
+#define  NEW_DSCP_OB_SHIFT		13
+#define  NEW_DSCP_OB_MASK		0x3f
+#define  CHANGE_DSCP_OB			(1 << 19)
+#define  CHAIN_ID_SHIFT			20
+#define  CHAIN_ID_MASK			0xff
+#define  CHANGE_COLOR			(1 << 28)
+#define  NEW_COLOR_SHIFT		29
+#define  NEW_COLOR_MASK			0x3
+#define  NEW_COLOR_GREEN		(0 << NEW_COLOR_SHIFT)
+#define  NEW_COLOR_YELLOW		(1 << NEW_COLOR_SHIFT)
+#define  NEW_COLOR_RED			(2 << NEW_COLOR_SHIFT)
+#define  RED_DEFAULT			(1 << 31)
+
+#define CORE_ACT_POL_DATA2		0x28160
+#define  MAC_LIMIT_BYPASS		(1 << 0)
+#define  CHANGE_TC_O			(1 << 1)
+#define  NEW_TC_O_SHIFT			2
+#define  NEW_TC_O_MASK			0x7
+#define  SPCP_RMK_DISABLE		(1 << 5)
+#define  CPCP_RMK_DISABLE		(1 << 6)
+#define  DEI_RMK_DISABLE		(1 << 7)
+
+#define CORE_RATE_METER0		0x28180
+#define  COLOR_MODE			(1 << 0)
+#define  POLICER_ACTION			(1 << 1)
+#define  COUPLING_FLAG			(1 << 2)
+#define  POLICER_MODE_SHIFT		3
+#define  POLICER_MODE_MASK		0x3
+#define  POLICER_MODE_RFC2698		(0 << POLICER_MODE_SHIFT)
+#define  POLICER_MODE_RFC4115		(1 << POLICER_MODE_SHIFT)
+#define  POLICER_MODE_MEF		(2 << POLICER_MODE_SHIFT)
+#define  POLICER_MODE_DISABLE		(3 << POLICER_MODE_SHIFT)
+
+#define CORE_RATE_METER1		0x28190
+#define  EIR_TK_BKT_MASK		0x7fffff
+
+#define CORE_RATE_METER2		0x281a0
+#define  EIR_BKT_SIZE_MASK		0xfffff
+
+#define CORE_RATE_METER3		0x281b0
+#define  EIR_REF_CNT_MASK		0x7ffff
+
+#define CORE_RATE_METER4		0x281c0
+#define  CIR_TK_BKT_MASK		0x7fffff
+
+#define CORE_RATE_METER5		0x281d0
+#define  CIR_BKT_SIZE_MASK		0xfffff
+
+#define CORE_RATE_METER6		0x281e0
+#define  CIR_REF_CNT_MASK		0x7ffff
+
+#define CORE_CFP_CTL_REG		0x28400
+#define  CFP_EN_MAP_MASK		0x1ff
+
+/* IPv4 slices, 3 of them */
+#define CORE_UDF_0_A_0_8_PORT_0		0x28440
+#define  CFG_UDF_OFFSET_MASK		0x1f
+#define  CFG_UDF_OFFSET_BASE_SHIFT	5
+#define  CFG_UDF_SOF			(0 << CFG_UDF_OFFSET_BASE_SHIFT)
+#define  CFG_UDF_EOL2			(2 << CFG_UDF_OFFSET_BASE_SHIFT)
+#define  CFG_UDF_EOL3			(3 << CFG_UDF_OFFSET_BASE_SHIFT)
+
+/* Number of slices for IPv4, IPv6 and non-IP */
+#define UDF_NUM_SLICES			9
+
+/* Spacing between different slices */
+#define UDF_SLICE_OFFSET		0x40
+
+#define CFP_NUM_RULES			256
+
 #endif /* __BCM_SF2_REGS_H */
-- 
2.9.3

^ permalink raw reply related

* Re: [PATCH net-next v2 1/2] qed: Add infrastructure for PTP support.
From: Mintz, Yuval @ 2017-01-30 18:00 UTC (permalink / raw)
  To: Richard Cochran
  Cc: davem@davemloft.net, netdev@vger.kernel.org, Kalluru, Sudarsana
In-Reply-To: <20170130132619.GA4854@localhost.localdomain>

> > I might have gotten it all wrong, but I was under the assumption that time-
> > stamped packets are periodic, and that the interval between two isn't
> > going to be so small.

> That is an incorrect assumption.  Consider the Delay_Req packets
> arriving on a port in the MASTER state.

Right; I was ignore that, thinking only on the clients.

> > Is so, how does having a couple of additional instructions in between
> > jeopardizes the next time stamp?

> It is not just about the few instructions, but there is also
> preemption possible.

I believe qede would only call this under spinlock, so that's probably
not an issue.
Regardless, that's no reason not to change the behavior.

Thanks.
     

^ permalink raw reply

* Re: [PATCH 2/6] wl1251: Use request_firmware_prefer_user() for loading NVS calibration data
From: Pali Rohár @ 2017-01-30 18:03 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Pavel Machek, Kalle Valo, Arend Van Spriel, Ming Lei,
	Luis R. Rodriguez, Greg Kroah-Hartman, David Gnedt, Michal Kazior,
	Daniel Wagner, Sebastian Reichel, Ivaylo Dimitrov, Aaro Koskinen,
	Grazvydas Ignotas, linux-kernel, linux-wireless, netdev
In-Reply-To: <20170130175309.GY7403@atomide.com>

[-- Attachment #1: Type: Text/Plain, Size: 1925 bytes --]

On Monday 30 January 2017 18:53:09 Tony Lindgren wrote:
> * Pavel Machek <pavel@ucw.cz> [170127 11:41]:
> > On Fri 2017-01-27 17:23:07, Kalle Valo wrote:
> > > Pali Rohár <pali.rohar@gmail.com> writes:
> > > > On Friday 27 January 2017 14:26:22 Kalle Valo wrote:
> > > >> Pali Rohár <pali.rohar@gmail.com> writes:
> > > >> > 2) It was already tested that example NVS data can be used
> > > >> > for N900 e.g. for SSH connection. If real correct data are
> > > >> > not available it is better to use at least those example
> > > >> > (and probably log warning message) so user can connect via
> > > >> > SSH and start investigating where is problem.
> > > >> 
> > > >> I disagree. Allowing default calibration data to be used can
> > > >> be unnoticed by user and left her wondering why wifi works so
> > > >> badly.
> > > > 
> > > > So there are only two options:
> > > > 
> > > > 1) Disallow it and so these users will have non-working wifi.
> > > > 
> > > > 2) Allow those data to be used as fallback mechanism.
> > > > 
> > > > And personally I'm against 1) because it will break wifi
> > > > support for *all* Nokia N900 devices right now.
> > > 
> > > All two of them? :)
> > 
> > Umm. You clearly want a flock of angry penguins at your doorsteps
> > :-).
> 
> Well this silly issue of symlinking and renaming nvs files in a
> standard Linux distro was also hitting me on various devices with
> wl12xx/wl18xx trying to use the same rootfs.

wl12xx/wl18xx have probably exactly same problem as wl1251.

> Why don't we just set a custom compatible property for n900 that then
> picks up some other nvs file instead of the default?

But that still does not solve this problem correctly. Every n900 device 
have different NVS file. If we allow to load firmware directly from VFS 
without userspace helper we would see again same problem.

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* Re: [PATCH] xen-netfront: Delete rx_refill_timer in xennet_disconnect_backend()
From: Eric Dumazet @ 2017-01-30 18:07 UTC (permalink / raw)
  To: Boris Ostrovsky
  Cc: jgross, xen-devel, netdev, linux-kernel, vineethp, wei.liu2,
	paul.durrant, stable
In-Reply-To: <1485798346-4425-1-git-send-email-boris.ostrovsky@oracle.com>

On Mon, 2017-01-30 at 12:45 -0500, Boris Ostrovsky wrote:
> rx_refill_timer should be deleted as soon as we disconnect from the
> backend since otherwise it is possible for the timer to go off before
> we get to xennet_destroy_queues(). If this happens we may dereference
> queue->rx.sring which is set to NULL in xennet_disconnect_backend().
> 
> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> CC: stable@vger.kernel.org
> ---
>  drivers/net/xen-netfront.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
> index 8315fe7..722fe9f 100644
> --- a/drivers/net/xen-netfront.c
> +++ b/drivers/net/xen-netfront.c
> @@ -1379,6 +1379,8 @@ static void xennet_disconnect_backend(struct netfront_info *info)
>  	for (i = 0; i < num_queues && info->queues; ++i) {
>  		struct netfront_queue *queue = &info->queues[i];
>  
> +		del_timer_sync(&queue->rx_refill_timer);
> +

If napi_disable() was not called before this del_timer_sync(), another
RX might come here and rearm rx_refill_timer.

>  		if (queue->tx_irq && (queue->tx_irq == queue->rx_irq))
>  			unbind_from_irqhandler(queue->tx_irq, queue);
>  		if (queue->tx_irq && (queue->tx_irq != queue->rx_irq)) {
> @@ -1733,7 +1735,6 @@ static void xennet_destroy_queues(struct netfront_info *info)
>  
>  		if (netif_running(info->netdev))
>  			napi_disable(&queue->napi);
> -		del_timer_sync(&queue->rx_refill_timer);
>  		netif_napi_del(&queue->napi);
>  	}
>  

^ permalink raw reply

* Re: [PATCH net-next v2 2/2] qede: Add driver support for PTP.
From: Mintz, Yuval @ 2017-01-30 17:55 UTC (permalink / raw)
  To: David Laight, 'Richard Cochran', Kalluru, Sudarsana
  Cc: davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6DB0273BA8@AcuExch.aculab.com>

> How many different implementations of 'ops->adjfreq' are there?
> If there is only one you don't need an indirect call.

There's only one implementation. But qed publishes its functions to
qede [and other modules] by structs of operations and not by
exporting symbols directly, and I don't see a reason to change that
paradigm here.
[Although I might be mistaken about that last bit]
     

^ permalink raw reply

* Re: [RFC PATCH 1/2] af_packet: direct dma for packet ineterface
From: Jesper Dangaard Brouer @ 2017-01-30 18:16 UTC (permalink / raw)
  To: John Fastabend
  Cc: bjorn.topel, jasowang, ast, alexander.duyck, john.r.fastabend,
	netdev, brouer
In-Reply-To: <20170127213344.14162.59976.stgit@john-Precision-Tower-5810>

On Fri, 27 Jan 2017 13:33:44 -0800 John Fastabend <john.fastabend@gmail.com> wrote:

> This adds ndo ops for upper layer objects to request direct DMA from
> the network interface into memory "slots". The slots must be DMA'able
> memory given by a page/offset/size vector in a packet_ring_buffer
> structure.
> 
> The PF_PACKET socket interface can use these ndo_ops to do zerocopy
> RX from the network device into memory mapped userspace memory. For
> this to work drivers encode the correct descriptor blocks and headers
> so that existing PF_PACKET applications work without any modification.
> This only supports the V2 header formats for now. And works by mapping
> a ring of the network device to these slots. Originally I used V2
> header formats but this does complicate the driver a bit.
> 
> V3 header formats added bulk polling via socket calls and timers
> used in the polling interface to return every n milliseconds. Currently,
> I don't see any way to support this in hardware because we can't
> know if the hardware is in the middle of a DMA operation or not
> on a slot. So when a timer fires I don't know how to advance the
> descriptor ring leaving empty descriptors similar to how the software
> ring works. The easiest (best?) route is to simply not support this.

>From a performance pov bulking is essential. Systems like netmap that
also depend on transferring control between kernel and userspace,
report[1] that they need at least bulking size 8, to amortize the overhead.

[1] Figure 7, page 10, http://info.iet.unipi.it/~luigi/papers/20120503-netmap-atc12.pdf


> It might be worth creating a new v4 header that is simple for drivers
> to support direct DMA ops with. I can imagine using the xdp_buff
> structure as a header for example. Thoughts?

Likely, but I would like that we do a measurement based approach.  Lets
benchmark with this V2 header format, and see how far we are from
target, and see what lights-up in perf report and if it is something we
can address.


> The ndo operations and new socket option PACKET_RX_DIRECT work by
> giving a queue_index to run the direct dma operations over. Once
> setsockopt returns successfully the indicated queue is mapped
> directly to the requesting application and can not be used for
> other purposes. Also any kernel layers such as tc will be bypassed
> and need to be implemented in the hardware via some other mechanism
> such as tc offload or other offload interfaces.

Will this also need to bypass XDP too?

E.g. how will you support XDP_TX?  AFAIK you cannot remove/detach a
packet with this solution (and place it on a TX queue and wait for DMA
TX completion).


> Users steer traffic to the selected queue using flow director,
> tc offload infrastructure or via macvlan offload.
> 
> The new socket option added to PF_PACKET is called PACKET_RX_DIRECT.
> It takes a single unsigned int value specifying the queue index,
> 
>      setsockopt(sock, SOL_PACKET, PACKET_RX_DIRECT,
> 		&queue_index, sizeof(queue_index));
> 
> Implementing busy_poll support will allow userspace to kick the
> drivers receive routine if needed. This work is TBD.
> 
> To test this I hacked a hardcoded test into  the tool psock_tpacket
> in the selftests kernel directory here:
> 
>      ./tools/testing/selftests/net/psock_tpacket.c
> 
> Running this tool opens a socket and listens for packets over
> the PACKET_RX_DIRECT enabled socket. Obviously it needs to be
> reworked to enable all the older tests and not hardcode my
> interface before it actually gets released.
> 
> In general this is a rough patch to explore the interface and
> put something concrete up for debate. The patch does not handle
> all the error cases correctly and needs to be cleaned up.
> 
> Known Limitations (TBD):
> 
>      (1) Users are required to match the number of rx ring
>          slots with ethtool to the number requested by the
>          setsockopt PF_PACKET layout. In the future we could
>          possibly do this automatically.
> 
>      (2) Users need to configure Flow director or setup_tc
>          to steer traffic to the correct queues. I don't believe
>          this needs to be changed it seems to be a good mechanism
>          for driving directed dma.
> 
>      (3) Not supporting timestamps or priv space yet, pushing
> 	 a v4 packet header would resolve this nicely.
> 
>      (5) Only RX supported so far. TX already supports direct DMA
>          interface but uses skbs which is really not needed. In
>          the TX_RING case we can optimize this path as well.
> 
> To support TX case we can do a similar "slots" mechanism and
> kick operation. The kick could be a busy_poll like operation
> but on the TX side. The flow would be user space loads up
> n number of slots with packets, kicks tx busy poll bit, the
> driver sends packets, and finally when xmit is complete
> clears header bits to give slots back. When we have qdisc
> bypass set today we already bypass the entire stack so no
> paticular reason to use skb's in this case. Using xdp_buff
> as a v4 packet header would also allow us to consolidate
> driver code.
> 
> To be done:
> 
>      (1) More testing and performance analysis
>      (2) Busy polling sockets
>      (3) Implement v4 xdp_buff headers for analysis
>      (4) performance testing :/ hopefully it looks good.

Guess, I don't understand the details of the af_packet versions well
enough, but can you explain to me, how userspace knows what slots it
can read/fetch, and how it marks when it is complete/finished so the
kernel knows it can reuse this slot?

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* [PATCH net-next v3 2/4] net: dsa: bcm_sf2: Configure traffic classes to queue mapping
From: Florian Fainelli @ 2017-01-30 17:48 UTC (permalink / raw)
  To: netdev; +Cc: davem, andrew, vivien.didelot, cphealy, Florian Fainelli
In-Reply-To: <20170130174843.29497-1-f.fainelli@gmail.com>

By default, all traffic goes to queue 0, re-configure the traffic
classes to quality of service mapping such that priority X maps to queue
X, where X is from 0 through 7.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/bcm_sf2.c      | 9 +++++++++
 drivers/net/dsa/bcm_sf2_regs.h | 4 ++++
 2 files changed, 13 insertions(+)

diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 8eecfd227e06..637072da3acf 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -229,6 +229,7 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
 {
 	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
 	s8 cpu_port = ds->dst[ds->index].cpu_port;
+	unsigned int i;
 	u32 reg;
 
 	/* Clear the memory power down */
@@ -240,6 +241,14 @@ static int bcm_sf2_port_setup(struct dsa_switch *ds, int port,
 	if (priv->brcm_tag_mask & BIT(port))
 		bcm_sf2_brcm_hdr_setup(priv, port);
 
+	/* Configure Traffic Class to QoS mapping, allow each priority to map
+	 * to a different queue number
+	 */
+	reg = core_readl(priv, CORE_PORT_TC2_QOS_MAP_PORT(port));
+	for (i = 0; i < 8; i++)
+		reg |= i << (PRT_TO_QID_SHIFT * i);
+	core_writel(priv, reg, CORE_PORT_TC2_QOS_MAP_PORT(port));
+
 	/* Clear the Rx and Tx disable bits and set to no spanning tree */
 	core_writel(priv, 0, CORE_G_PCTL_PORT(port));
 
diff --git a/drivers/net/dsa/bcm_sf2_regs.h b/drivers/net/dsa/bcm_sf2_regs.h
index 3b33b8010cc8..6b63c00928ba 100644
--- a/drivers/net/dsa/bcm_sf2_regs.h
+++ b/drivers/net/dsa/bcm_sf2_regs.h
@@ -238,6 +238,10 @@ enum bcm_sf2_reg_offs {
 #define  P_TXQ_PSM_VDD(x)		(P_TXQ_PSM_VDD_MASK << \
 					((x) * P_TXQ_PSM_VDD_SHIFT))
 
+#define CORE_PORT_TC2_QOS_MAP_PORT(x)	(0xc1c0 + ((x) * 0x10))
+#define  PRT_TO_QID_MASK		0x3
+#define  PRT_TO_QID_SHIFT		3
+
 #define CORE_PORT_VLAN_CTL_PORT(x)	(0xc400 + ((x) * 0x8))
 #define  PORT_VLAN_CTRL_MASK		0x1ff
 
-- 
2.9.3

^ permalink raw reply related

* [PATCH net-next v3 4/4] net: dsa: bcm_sf2: Add support for ethtool::rxnfc
From: Florian Fainelli @ 2017-01-30 17:48 UTC (permalink / raw)
  To: netdev; +Cc: davem, andrew, vivien.didelot, cphealy, Florian Fainelli
In-Reply-To: <20170130174843.29497-1-f.fainelli@gmail.com>

Add support for configuring classification rules using the
ethtool::rxnfc API.  This is useful to program the switch's CFP/TCAM to
redirect specific packets to specific ports/queues for instance. For
now, we allow any kind of IPv4 5-tuple matching.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/Makefile      |   1 +
 drivers/net/dsa/bcm_sf2.c     |  14 +
 drivers/net/dsa/bcm_sf2.h     |  17 ++
 drivers/net/dsa/bcm_sf2_cfp.c | 613 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 645 insertions(+)
 create mode 100644 drivers/net/dsa/bcm_sf2_cfp.c

diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index 8346e4f9737a..da9893478e21 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
 obj-$(CONFIG_NET_DSA_BCM_SF2)	+= bcm_sf2.o
+bcm_sf2-objs			+= bcm_sf2_cfp.o
 obj-$(CONFIG_NET_DSA_QCA8K)	+= qca8k.o
 
 obj-y				+= b53/
diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
index 637072da3acf..be282b430c50 100644
--- a/drivers/net/dsa/bcm_sf2.c
+++ b/drivers/net/dsa/bcm_sf2.c
@@ -1045,6 +1045,8 @@ static const struct dsa_switch_ops bcm_sf2_ops = {
 	.port_fdb_dump		= b53_fdb_dump,
 	.port_fdb_add		= b53_fdb_add,
 	.port_fdb_del		= b53_fdb_del,
+	.get_rxnfc		= bcm_sf2_get_rxnfc,
+	.set_rxnfc		= bcm_sf2_set_rxnfc,
 };
 
 struct bcm_sf2_of_data {
@@ -1168,6 +1170,12 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
 
 	spin_lock_init(&priv->indir_lock);
 	mutex_init(&priv->stats_mutex);
+	mutex_init(&priv->cfp.lock);
+
+	/* CFP rule #0 cannot be used for specific classifications, flag it as
+	 * permanently used
+	 */
+	set_bit(0, priv->cfp.used);
 
 	bcm_sf2_identify_ports(priv, dn->child);
 
@@ -1197,6 +1205,12 @@ static int bcm_sf2_sw_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	ret = bcm_sf2_cfp_rst(priv);
+	if (ret) {
+		pr_err("failed to reset CFP\n");
+		goto out_mdio;
+	}
+
 	/* Disable all interrupts and request them */
 	bcm_sf2_intr_disable(priv);
 
diff --git a/drivers/net/dsa/bcm_sf2.h b/drivers/net/dsa/bcm_sf2.h
index 6e1f74e4d471..7d3030e04f11 100644
--- a/drivers/net/dsa/bcm_sf2.h
+++ b/drivers/net/dsa/bcm_sf2.h
@@ -52,6 +52,13 @@ struct bcm_sf2_port_status {
 	struct ethtool_eee eee;
 };
 
+struct bcm_sf2_cfp_priv {
+	/* Mutex protecting concurrent accesses to the CFP registers */
+	struct mutex lock;
+	DECLARE_BITMAP(used, CFP_NUM_RULES);
+	unsigned int rules_cnt;
+};
+
 struct bcm_sf2_priv {
 	/* Base registers, keep those in order with BCM_SF2_REGS_NAME */
 	void __iomem			*core;
@@ -103,6 +110,9 @@ struct bcm_sf2_priv {
 
 	/* Bitmask of ports needing BRCM tags */
 	unsigned int			brcm_tag_mask;
+
+	/* CFP rules context */
+	struct bcm_sf2_cfp_priv		cfp;
 };
 
 static inline struct bcm_sf2_priv *bcm_sf2_to_priv(struct dsa_switch *ds)
@@ -197,4 +207,11 @@ SF2_IO_MACRO(acb);
 SWITCH_INTR_L2(0);
 SWITCH_INTR_L2(1);
 
+/* RXNFC */
+int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
+		      struct ethtool_rxnfc *nfc, u32 *rule_locs);
+int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port,
+		      struct ethtool_rxnfc *nfc);
+int bcm_sf2_cfp_rst(struct bcm_sf2_priv *priv);
+
 #endif /* __BCM_SF2_H */
diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
new file mode 100644
index 000000000000..c71be3e0dc2d
--- /dev/null
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -0,0 +1,613 @@
+/*
+ * Broadcom Starfighter 2 DSA switch CFP support
+ *
+ * Copyright (C) 2016, Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/list.h>
+#include <net/dsa.h>
+#include <linux/ethtool.h>
+#include <linux/if_ether.h>
+#include <linux/in.h>
+#include <linux/bitmap.h>
+
+#include "bcm_sf2.h"
+#include "bcm_sf2_regs.h"
+
+struct cfp_udf_layout {
+	u8 slices[UDF_NUM_SLICES];
+	u32 mask_value;
+
+};
+
+/* UDF slices layout for a TCPv4/UDPv4 specification */
+static const struct cfp_udf_layout udf_tcpip4_layout = {
+	.slices = {
+		/* End of L2, byte offset 12, src IP[0:15] */
+		CFG_UDF_EOL2 | 6,
+		/* End of L2, byte offset 14, src IP[16:31] */
+		CFG_UDF_EOL2 | 7,
+		/* End of L2, byte offset 16, dst IP[0:15] */
+		CFG_UDF_EOL2 | 8,
+		/* End of L2, byte offset 18, dst IP[16:31] */
+		CFG_UDF_EOL2 | 9,
+		/* End of L3, byte offset 0, src port */
+		CFG_UDF_EOL3 | 0,
+		/* End of L3, byte offset 2, dst port */
+		CFG_UDF_EOL3 | 1,
+		0, 0, 0
+	},
+	.mask_value = L3_FRAMING_MASK | IPPROTO_MASK | IP_FRAG,
+};
+
+static inline unsigned int bcm_sf2_get_num_udf_slices(const u8 *layout)
+{
+	unsigned int i, count = 0;
+
+	for (i = 0; i < UDF_NUM_SLICES; i++) {
+		if (layout[i] != 0)
+			count++;
+	}
+
+	return count;
+}
+
+static void bcm_sf2_cfp_udf_set(struct bcm_sf2_priv *priv,
+				unsigned int slice_num,
+				const u8 *layout)
+{
+	u32 offset = CORE_UDF_0_A_0_8_PORT_0 + slice_num * UDF_SLICE_OFFSET;
+	unsigned int i;
+
+	for (i = 0; i < UDF_NUM_SLICES; i++)
+		core_writel(priv, layout[i], offset + i * 4);
+}
+
+static int bcm_sf2_cfp_op(struct bcm_sf2_priv *priv, unsigned int op)
+{
+	unsigned int timeout = 1000;
+	u32 reg;
+
+	reg = core_readl(priv, CORE_CFP_ACC);
+	reg &= ~(OP_SEL_MASK | RAM_SEL_MASK);
+	reg |= OP_STR_DONE | op;
+	core_writel(priv, reg, CORE_CFP_ACC);
+
+	do {
+		reg = core_readl(priv, CORE_CFP_ACC);
+		if (!(reg & OP_STR_DONE))
+			break;
+
+		cpu_relax();
+	} while (timeout--);
+
+	if (!timeout)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+
+static inline void bcm_sf2_cfp_rule_addr_set(struct bcm_sf2_priv *priv,
+					     unsigned int addr)
+{
+	u32 reg;
+
+	WARN_ON(addr >= CFP_NUM_RULES);
+
+	reg = core_readl(priv, CORE_CFP_ACC);
+	reg &= ~(XCESS_ADDR_MASK << XCESS_ADDR_SHIFT);
+	reg |= addr << XCESS_ADDR_SHIFT;
+	core_writel(priv, reg, CORE_CFP_ACC);
+}
+
+static inline unsigned int bcm_sf2_cfp_rule_size(struct bcm_sf2_priv *priv)
+{
+	/* Entry #0 is reserved */
+	return CFP_NUM_RULES - 1;
+}
+
+static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port,
+				struct ethtool_rx_flow_spec *fs)
+{
+	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
+	struct ethtool_tcpip4_spec *v4_spec;
+	const struct cfp_udf_layout *layout;
+	unsigned int slice_num, rule_index;
+	unsigned int queue_num, port_num;
+	u8 ip_proto, ip_frag;
+	u8 num_udf;
+	u32 reg;
+	int ret;
+
+	/* Check for unsupported extensions */
+	if ((fs->flow_type & FLOW_EXT) &&
+	    (fs->m_ext.vlan_etype || fs->m_ext.data[1]))
+		return -EINVAL;
+
+	if (fs->location != RX_CLS_LOC_ANY &&
+	    test_bit(fs->location, priv->cfp.used))
+		return -EBUSY;
+
+	if (fs->location != RX_CLS_LOC_ANY &&
+	    fs->location > bcm_sf2_cfp_rule_size(priv))
+		return -EINVAL;
+
+	ip_frag = be32_to_cpu(fs->m_ext.data[0]);
+
+	/* We do not support discarding packets, check that the
+	 * destination port is enabled and that we are within the
+	 * number of ports supported by the switch
+	 */
+	port_num = fs->ring_cookie / 8;
+
+	if (fs->ring_cookie == RX_CLS_FLOW_DISC ||
+	    !(BIT(port_num) & ds->enabled_port_mask) ||
+	    port_num >= priv->hw_params.num_ports)
+		return -EINVAL;
+
+	switch (fs->flow_type & ~FLOW_EXT) {
+	case TCP_V4_FLOW:
+		ip_proto = IPPROTO_TCP;
+		v4_spec = &fs->h_u.tcp_ip4_spec;
+		break;
+	case UDP_V4_FLOW:
+		ip_proto = IPPROTO_UDP;
+		v4_spec = &fs->h_u.udp_ip4_spec;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* We only use one UDF slice for now */
+	slice_num = 1;
+	layout = &udf_tcpip4_layout;
+	num_udf = bcm_sf2_get_num_udf_slices(layout->slices);
+
+	/* Apply the UDF layout for this filter */
+	bcm_sf2_cfp_udf_set(priv, slice_num, layout->slices);
+
+	/* Apply to all packets received through this port */
+	core_writel(priv, BIT(port), CORE_CFP_DATA_PORT(7));
+
+	/* S-Tag status		[31:30]
+	 * C-Tag status		[29:28]
+	 * L2 framing		[27:26]
+	 * L3 framing		[25:24]
+	 * IP ToS		[23:16]
+	 * IP proto		[15:08]
+	 * IP Fragm		[7]
+	 * Non 1st frag		[6]
+	 * IP Authen		[5]
+	 * TTL range		[4:3]
+	 * PPPoE session	[2]
+	 * Reserved		[1]
+	 * UDF_Valid[8]		[0]
+	 */
+	core_writel(priv, v4_spec->tos << 16 | ip_proto << 8 | ip_frag << 7,
+		    CORE_CFP_DATA_PORT(6));
+
+	/* UDF_Valid[7:0]	[31:24]
+	 * S-Tag		[23:8]
+	 * C-Tag		[7:0]
+	 */
+	core_writel(priv, GENMASK(num_udf - 1, 0) << 24, CORE_CFP_DATA_PORT(5));
+
+	/* C-Tag		[31:24]
+	 * UDF_n_A8		[23:8]
+	 * UDF_n_A7		[7:0]
+	 */
+	core_writel(priv, 0, CORE_CFP_DATA_PORT(4));
+
+	/* UDF_n_A7		[31:24]
+	 * UDF_n_A6		[23:8]
+	 * UDF_n_A5		[7:0]
+	 */
+	core_writel(priv, be16_to_cpu(v4_spec->pdst) >> 8,
+		    CORE_CFP_DATA_PORT(3));
+
+	/* UDF_n_A5		[31:24]
+	 * UDF_n_A4		[23:8]
+	 * UDF_n_A3		[7:0]
+	 */
+	reg = (be16_to_cpu(v4_spec->pdst) & 0xff) << 24 |
+	      (u32)be16_to_cpu(v4_spec->psrc) << 8 |
+	      (be32_to_cpu(v4_spec->ip4dst) & 0x0000ff00) >> 8;
+	core_writel(priv, reg, CORE_CFP_DATA_PORT(2));
+
+	/* UDF_n_A3		[31:24]
+	 * UDF_n_A2		[23:8]
+	 * UDF_n_A1		[7:0]
+	 */
+	reg = (u32)(be32_to_cpu(v4_spec->ip4dst) & 0xff) << 24 |
+	      (u32)(be32_to_cpu(v4_spec->ip4dst) >> 16) << 8 |
+	      (be32_to_cpu(v4_spec->ip4src) & 0x0000ff00) >> 8;
+	core_writel(priv, reg, CORE_CFP_DATA_PORT(1));
+
+	/* UDF_n_A1		[31:24]
+	 * UDF_n_A0		[23:8]
+	 * Reserved		[7:4]
+	 * Slice ID		[3:2]
+	 * Slice valid		[1:0]
+	 */
+	reg = (u32)(be32_to_cpu(v4_spec->ip4src) & 0xff) << 24 |
+	      (u32)(be32_to_cpu(v4_spec->ip4src) >> 16) << 8 |
+	      SLICE_NUM(slice_num) | SLICE_VALID;
+	core_writel(priv, reg, CORE_CFP_DATA_PORT(0));
+
+	/* Source port map match */
+	core_writel(priv, 0xff, CORE_CFP_MASK_PORT(7));
+
+	/* Mask with the specific layout for IPv4 packets */
+	core_writel(priv, layout->mask_value, CORE_CFP_MASK_PORT(6));
+
+	/* Mask all but valid UDFs */
+	core_writel(priv, GENMASK(num_udf - 1, 0) << 24, CORE_CFP_MASK_PORT(5));
+
+	/* Mask all */
+	core_writel(priv, 0, CORE_CFP_MASK_PORT(4));
+
+	/* All other UDFs should be matched with the filter */
+	core_writel(priv, 0xff, CORE_CFP_MASK_PORT(3));
+	core_writel(priv, 0xffffffff, CORE_CFP_MASK_PORT(2));
+	core_writel(priv, 0xffffffff, CORE_CFP_MASK_PORT(1));
+	core_writel(priv, 0xffffff0f, CORE_CFP_MASK_PORT(0));
+
+	/* Locate the first rule available */
+	if (fs->location == RX_CLS_LOC_ANY)
+		rule_index = find_first_zero_bit(priv->cfp.used,
+						 bcm_sf2_cfp_rule_size(priv));
+	else
+		rule_index = fs->location;
+
+	/* Insert into TCAM now */
+	bcm_sf2_cfp_rule_addr_set(priv, rule_index);
+
+	ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL);
+	if (ret) {
+		pr_err("TCAM entry at addr %d failed\n", rule_index);
+		return ret;
+	}
+
+	/* Replace ARL derived destination with DST_MAP derived, define
+	 * which port and queue this should be forwarded to.
+	 *
+	 * We have a small oddity where Port 6 just does not have a
+	 * valid bit here (so we subtract by one).
+	 */
+	queue_num = fs->ring_cookie % 8;
+	if (port_num >= 7)
+		port_num -= 1;
+
+	reg = CHANGE_FWRD_MAP_IB_REP_ARL | BIT(port_num + DST_MAP_IB_SHIFT) |
+		CHANGE_TC | queue_num << NEW_TC_SHIFT;
+
+	core_writel(priv, reg, CORE_ACT_POL_DATA0);
+
+	/* Set classification ID that needs to be put in Broadcom tag */
+	core_writel(priv, rule_index << CHAIN_ID_SHIFT,
+		    CORE_ACT_POL_DATA1);
+
+	core_writel(priv, 0, CORE_ACT_POL_DATA2);
+
+	/* Configure policer RAM now */
+	ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | ACT_POL_RAM);
+	if (ret) {
+		pr_err("Policer entry at %d failed\n", rule_index);
+		return ret;
+	}
+
+	/* Disable the policer */
+	core_writel(priv, POLICER_MODE_DISABLE, CORE_RATE_METER0);
+
+	/* Now the rate meter */
+	ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | RATE_METER_RAM);
+	if (ret) {
+		pr_err("Meter entry at %d failed\n", rule_index);
+		return ret;
+	}
+
+	/* Turn on CFP for this rule now */
+	reg = core_readl(priv, CORE_CFP_CTL_REG);
+	reg |= BIT(port);
+	core_writel(priv, reg, CORE_CFP_CTL_REG);
+
+	/* Flag the rule as being used and return it */
+	set_bit(rule_index, priv->cfp.used);
+	fs->location = rule_index;
+
+	return 0;
+}
+
+static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port,
+				u32 loc)
+{
+	int ret;
+	u32 reg;
+
+	/* Refuse deletion of unused rules, and the default reserved rule */
+	if (!test_bit(loc, priv->cfp.used) || loc == 0)
+		return -EINVAL;
+
+	/* Indicate which rule we want to read */
+	bcm_sf2_cfp_rule_addr_set(priv, loc);
+
+	ret =  bcm_sf2_cfp_op(priv, OP_SEL_READ | TCAM_SEL);
+	if (ret)
+		return ret;
+
+	/* Clear its valid bits */
+	reg = core_readl(priv, CORE_CFP_DATA_PORT(0));
+	reg &= ~SLICE_VALID;
+	core_writel(priv, reg, CORE_CFP_DATA_PORT(0));
+
+	/* Write back this entry into the TCAM now */
+	ret = bcm_sf2_cfp_op(priv, OP_SEL_WRITE | TCAM_SEL);
+	if (ret)
+		return ret;
+
+	clear_bit(loc, priv->cfp.used);
+
+	return 0;
+}
+
+static void bcm_sf2_invert_masks(struct ethtool_rx_flow_spec *flow)
+{
+	unsigned int i;
+
+	for (i = 0; i < sizeof(flow->m_u); i++)
+		flow->m_u.hdata[i] ^= 0xff;
+
+	flow->m_ext.vlan_etype ^= cpu_to_be16(~0);
+	flow->m_ext.vlan_tci ^= cpu_to_be16(~0);
+	flow->m_ext.data[0] ^= cpu_to_be32(~0);
+	flow->m_ext.data[1] ^= cpu_to_be32(~0);
+}
+
+static int bcm_sf2_cfp_rule_get(struct bcm_sf2_priv *priv, int port,
+				struct ethtool_rxnfc *nfc, bool search)
+{
+	struct ethtool_tcpip4_spec *v4_spec;
+	unsigned int queue_num;
+	u16 src_dst_port;
+	u32 reg, ipv4;
+	int ret;
+
+	if (!search) {
+		bcm_sf2_cfp_rule_addr_set(priv, nfc->fs.location);
+
+		ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | ACT_POL_RAM);
+		if (ret)
+			return ret;
+
+		reg = core_readl(priv, CORE_ACT_POL_DATA0);
+
+		ret = bcm_sf2_cfp_op(priv, OP_SEL_READ | TCAM_SEL);
+		if (ret)
+			return ret;
+	} else {
+		reg = core_readl(priv, CORE_ACT_POL_DATA0);
+	}
+
+	/* Extract the destination port */
+	nfc->fs.ring_cookie = fls((reg >> DST_MAP_IB_SHIFT) &
+				  DST_MAP_IB_MASK) - 1;
+
+	/* There is no Port 6, so we compensate for that here */
+	if (nfc->fs.ring_cookie >= 6)
+		nfc->fs.ring_cookie++;
+	nfc->fs.ring_cookie *= 8;
+
+	/* Extract the destination queue */
+	queue_num = (reg >> NEW_TC_SHIFT) & NEW_TC_MASK;
+	nfc->fs.ring_cookie += queue_num;
+
+	/* Extract the IP protocol */
+	reg = core_readl(priv, CORE_CFP_DATA_PORT(6));
+	switch ((reg & IPPROTO_MASK) >> IPPROTO_SHIFT) {
+	case IPPROTO_TCP:
+		nfc->fs.flow_type = TCP_V4_FLOW;
+		v4_spec = &nfc->fs.h_u.tcp_ip4_spec;
+		break;
+	case IPPROTO_UDP:
+		nfc->fs.flow_type = UDP_V4_FLOW;
+		v4_spec = &nfc->fs.h_u.udp_ip4_spec;
+		break;
+	default:
+		/* Clear to exit the search process */
+		if (search)
+			core_readl(priv, CORE_CFP_DATA_PORT(7));
+		return -EINVAL;
+	}
+
+	v4_spec->tos = (reg >> 16) & IPPROTO_MASK;
+	nfc->fs.m_ext.data[0] = cpu_to_be32((reg >> 7) & 1);
+
+	reg = core_readl(priv, CORE_CFP_DATA_PORT(3));
+	/* src port [15:8] */
+	src_dst_port = reg << 8;
+
+	reg = core_readl(priv, CORE_CFP_DATA_PORT(2));
+	/* src port [7:0] */
+	src_dst_port |= (reg >> 24);
+
+	v4_spec->pdst = cpu_to_be16(src_dst_port);
+	nfc->fs.m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0);
+	v4_spec->psrc = cpu_to_be16((u16)(reg >> 8));
+	nfc->fs.m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0);
+
+	/* IPv4 dst [15:8] */
+	ipv4 = (u16)(reg & 0xff) << 8;
+	reg = core_readl(priv, CORE_CFP_DATA_PORT(1));
+	/* IPv4 dst [31:16] */
+	ipv4 |= (u32)((reg >> 8) & 0xffffff) << 16;
+	/* IPv4 dst [7:0] */
+	ipv4 |= (reg >> 24) & 0xff;
+	v4_spec->ip4dst = cpu_to_be32(ipv4);
+	nfc->fs.m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0);
+
+	/* IPv4 src [15:8] */
+	ipv4 = (u16)(reg & 0xff) << 8;
+	reg = core_readl(priv, CORE_CFP_DATA_PORT(0));
+
+	if (!(reg & SLICE_VALID))
+		return -EINVAL;
+
+	/* IPv4 src [7:0] */
+	ipv4 |= (reg >> 24) & 0xff;
+	/* IPv4 src [31:16] */
+	ipv4 |= ((reg >> 8) & 0xffffff) << 16;
+	v4_spec->ip4src = cpu_to_be32(ipv4);
+	nfc->fs.m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0);
+
+	/* Read last to avoid next entry clobbering the results during search
+	 * operations
+	 */
+	reg = core_readl(priv, CORE_CFP_DATA_PORT(7));
+	if (!(reg & 1 << port))
+		return -EINVAL;
+
+	bcm_sf2_invert_masks(&nfc->fs);
+
+	/* Put the TCAM size here */
+	nfc->data = bcm_sf2_cfp_rule_size(priv);
+
+	return 0;
+}
+
+/* We implement the search doing a TCAM search operation */
+static int bcm_sf2_cfp_rule_get_all(struct bcm_sf2_priv *priv,
+				    int port, struct ethtool_rxnfc *nfc,
+				    u32 *rule_locs)
+{
+	unsigned int index = 1, rules_cnt = 0;
+	int ret;
+	u32 reg;
+
+	/* Do not poll on OP_STR_DONE to be self-clearing for search
+	 * operations, we cannot use bcm_sf2_cfp_op here because it completes
+	 * on clearing OP_STR_DONE which won't clear until the entire search
+	 * operation is over.
+	 */
+	reg = core_readl(priv, CORE_CFP_ACC);
+	reg &= ~(XCESS_ADDR_MASK << XCESS_ADDR_SHIFT);
+	reg |= index << XCESS_ADDR_SHIFT;
+	reg &= ~(OP_SEL_MASK | RAM_SEL_MASK);
+	reg |= OP_SEL_SEARCH | TCAM_SEL | OP_STR_DONE;
+	core_writel(priv, reg, CORE_CFP_ACC);
+
+	do {
+		/* Wait for results to be ready */
+		reg = core_readl(priv, CORE_CFP_ACC);
+
+		/* Extract the address we are searching */
+		index = reg >> XCESS_ADDR_SHIFT;
+		index &= XCESS_ADDR_MASK;
+
+		/* We have a valid search result, so flag it accordingly */
+		if (reg & SEARCH_STS) {
+			ret = bcm_sf2_cfp_rule_get(priv, port, nfc, true);
+			if (ret)
+				continue;
+
+			rule_locs[rules_cnt] = index;
+			rules_cnt++;
+		}
+
+		/* Search is over break out */
+		if (!(reg & OP_STR_DONE))
+			break;
+
+	} while (index < CFP_NUM_RULES);
+
+	/* Put the TCAM size here */
+	nfc->data = bcm_sf2_cfp_rule_size(priv);
+	nfc->rule_cnt = rules_cnt;
+
+	return 0;
+}
+
+int bcm_sf2_get_rxnfc(struct dsa_switch *ds, int port,
+		      struct ethtool_rxnfc *nfc, u32 *rule_locs)
+{
+	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
+	int ret = 0;
+
+	mutex_lock(&priv->cfp.lock);
+
+	switch (nfc->cmd) {
+	case ETHTOOL_GRXCLSRLCNT:
+		/* Subtract the default, unusable rule */
+		nfc->rule_cnt = bitmap_weight(priv->cfp.used,
+					      CFP_NUM_RULES) - 1;
+		/* We support specifying rule locations */
+		nfc->data |= RX_CLS_LOC_SPECIAL;
+		break;
+	case ETHTOOL_GRXCLSRULE:
+		ret = bcm_sf2_cfp_rule_get(priv, port, nfc, false);
+		break;
+	case ETHTOOL_GRXCLSRLALL:
+		ret = bcm_sf2_cfp_rule_get_all(priv, port, nfc, rule_locs);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	mutex_unlock(&priv->cfp.lock);
+
+	return ret;
+}
+
+int bcm_sf2_set_rxnfc(struct dsa_switch *ds, int port,
+		      struct ethtool_rxnfc *nfc)
+{
+	struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
+	int ret = 0;
+
+	mutex_lock(&priv->cfp.lock);
+
+	switch (nfc->cmd) {
+	case ETHTOOL_SRXCLSRLINS:
+		ret = bcm_sf2_cfp_rule_set(ds, port, &nfc->fs);
+		break;
+
+	case ETHTOOL_SRXCLSRLDEL:
+		ret = bcm_sf2_cfp_rule_del(priv, port, nfc->fs.location);
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	}
+
+	mutex_unlock(&priv->cfp.lock);
+
+	return ret;
+}
+
+int bcm_sf2_cfp_rst(struct bcm_sf2_priv *priv)
+{
+	unsigned int timeout = 1000;
+	u32 reg;
+
+	reg = core_readl(priv, CORE_CFP_ACC);
+	reg |= TCAM_RESET;
+	core_writel(priv, reg, CORE_CFP_ACC);
+
+	do {
+		reg = core_readl(priv, CORE_CFP_ACC);
+		if (!(reg & TCAM_RESET))
+			break;
+
+		cpu_relax();
+	} while (timeout--);
+
+	if (!timeout)
+		return -ETIMEDOUT;
+
+	return 0;
+}
-- 
2.9.3

^ permalink raw reply related

* Re: [PATCH net] packet: call fanout_release, while UNREGISTERING a netdev
From: Anoob Soman @ 2017-01-30 18:19 UTC (permalink / raw)
  To: Eric Dumazet, David Miller; +Cc: netdev
In-Reply-To: <1485797189.6360.98.camel@edumazet-glaptop3.roam.corp.google.com>



On 30/01/17 17:26, Eric Dumazet wrote:
> On Thu, 2016-10-06 at 20:50 -0400, David Miller wrote:
>> From: Anoob Soman <anoob.soman@citrix.com>
>> Date: Wed, 5 Oct 2016 15:12:54 +0100
>>
>>> If a socket has FANOUT sockopt set, a new proto_hook is registered
>>> as part of fanout_add(). When processing a NETDEV_UNREGISTER event in
>>> af_packet, __fanout_unlink is called for all sockets, but prot_hook which was
>>> registered as part of fanout_add is not removed. Call fanout_release, on a
>>> NETDEV_UNREGISTER, which removes prot_hook and removes fanout from the
>>> fanout_list.
>>>
>>> This fixes BUG_ON(!list_empty(&dev->ptype_specific)) in netdev_run_todo()
>>>
>>> Signed-off-by: Anoob Soman <anoob.soman@citrix.com>
>> Applied and queued up for -stable, thanks.
> This commit (6664498280cf "packet: call fanout_release, while
> UNREGISTERING a netdev")
> looks buggy :
>
> We end up calling fanout_release() while holding a spinlock
> ( spin_lock(&po->bind_lock); )
>
> But fanout_release() grabs a mutex ( mutex_lock(&fanout_mutex) ), and
> this is absolutely not valid while holding a spinlock.
Yes correct, that is wrong.

>
> Anoob, can you cook a fix, I guess you have a way to reproduce the thing
> that wanted a kernel patch ?
>
> (Please build your test kernel with CONFIG_LOCKDEP=y)
Sure, I am planning to move fanout_release(sk) after 
spin_unlock(bond_lock). Something like this.
                                 }
                                 if (msg == NETDEV_UNREGISTER) {
                                         packet_cached_dev_reset(po);
-                                       fanout_release(sk);
                                         po->ifindex = -1;
                                         if (po->prot_hook.dev)
dev_put(po->prot_hook.dev);
                                         po->prot_hook.dev = NULL;
                                 }
                                 spin_unlock(&po->bind_lock);
+                               if (msg == NETDEV_UNREGISTER) {
+                                       fanout_release(sk);
+                               }
                         }
                         break;

I will quickly test it out.

> Thanks.
>
>

^ permalink raw reply

* [PATCH net-next v3 0/4] net: dsa: bcm_sf2: CFP support
From: Florian Fainelli @ 2017-01-30 17:48 UTC (permalink / raw)
  To: netdev; +Cc: davem, andrew, vivien.didelot, cphealy, Florian Fainelli

Hi all,

This patch series adds support for the Broadcom Compact Field Processor (CFP)
which is a classification and matching engine built into most Broadcom switches.

We support that using ethtool::rxnfc because it allows all known uses cases from
the users I support to work, and more importantly, it allows the selection of a
target rule index, which is later used by e.g: offloading hardware, this is an
essential feature that I could not find being supported with cls_* for instance.

Thanks!

Changes in v3:

- rebased against latest net-next/master after Vivien's changes

Changes in v2:

- fixed modular builds reported by kbuild test robot

Florian Fainelli (4):
  net: dsa: Hook {get,set}_rxnfc ethtool operations
  net: dsa: bcm_sf2: Configure traffic classes to queue mapping
  net: dsa: bcm_sf2: Add CFP registers definitions
  net: dsa: bcm_sf2: Add support for ethtool::rxnfc

 drivers/net/dsa/Makefile       |   1 +
 drivers/net/dsa/bcm_sf2.c      |  23 ++
 drivers/net/dsa/bcm_sf2.h      |  17 ++
 drivers/net/dsa/bcm_sf2_cfp.c  | 613 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/bcm_sf2_regs.h | 150 ++++++++++
 include/net/dsa.h              |   8 +
 net/dsa/slave.c                |  26 ++
 7 files changed, 838 insertions(+)
 create mode 100644 drivers/net/dsa/bcm_sf2_cfp.c

-- 
2.9.3

^ permalink raw reply

* Re: [PATCH] xen-netfront: Delete rx_refill_timer in xennet_disconnect_backend()
From: Boris Ostrovsky @ 2017-01-30 18:23 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: jgross, xen-devel, netdev, linux-kernel, vineethp, wei.liu2,
	paul.durrant, stable
In-Reply-To: <1485799651.6360.101.camel@edumazet-glaptop3.roam.corp.google.com>

On 01/30/2017 01:07 PM, Eric Dumazet wrote:
> On Mon, 2017-01-30 at 12:45 -0500, Boris Ostrovsky wrote:
>> rx_refill_timer should be deleted as soon as we disconnect from the
>> backend since otherwise it is possible for the timer to go off before
>> we get to xennet_destroy_queues(). If this happens we may dereference
>> queue->rx.sring which is set to NULL in xennet_disconnect_backend().
>>
>> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
>> CC: stable@vger.kernel.org
>> ---
>>  drivers/net/xen-netfront.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
>> index 8315fe7..722fe9f 100644
>> --- a/drivers/net/xen-netfront.c
>> +++ b/drivers/net/xen-netfront.c
>> @@ -1379,6 +1379,8 @@ static void xennet_disconnect_backend(struct netfront_info *info)
>>  	for (i = 0; i < num_queues && info->queues; ++i) {
>>  		struct netfront_queue *queue = &info->queues[i];
>>  
>> +		del_timer_sync(&queue->rx_refill_timer);
>> +
> If napi_disable() was not called before this del_timer_sync(), another
> RX might come here and rearm rx_refill_timer.

We do netif_carrier_off() first thing in xennet_disconnect_backend() and
the only place where the timer is rearmed is xennet_alloc_rx_buffers(),
which is guarded by netif_carrier_ok() check.

-boris


>
>>  		if (queue->tx_irq && (queue->tx_irq == queue->rx_irq))
>>  			unbind_from_irqhandler(queue->tx_irq, queue);
>>  		if (queue->tx_irq && (queue->tx_irq != queue->rx_irq)) {
>> @@ -1733,7 +1735,6 @@ static void xennet_destroy_queues(struct netfront_info *info)
>>  
>>  		if (netif_running(info->netdev))
>>  			napi_disable(&queue->napi);
>> -		del_timer_sync(&queue->rx_refill_timer);
>>  		netif_napi_del(&queue->napi);
>>  	}
>>  
>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox