* Re: [PATCH] IB/IPoIB: Check the headroom size
From: Honggang LI @ 2017-04-25 10:57 UTC (permalink / raw)
To: Or Gerlitz
Cc: Erez Shitrit, Doug Ledford, Hefty, Sean, Hal Rosenstock,
Paolo Abeni, linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Linux Kernel, Linux Netdev List
In-Reply-To: <CAJ3xEMg4_2ph7QwPsUb-tX-K4d2ppkqz98sPzytsmBCK=29WHw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Apr 25, 2017 at 01:32:59PM +0300, Or Gerlitz wrote:
> On Tue, Apr 25, 2017 at 12:55 PM, Honggang LI <honli-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> > From: Honggang Li <honli-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> >
> > Minimal hard_header_len set by bond_compute_features is ETH_HLEN, which
> > is smaller than IPOIB_HARD_LEN. ipoib_hard_header should check the
> > size of headroom to avoid skb_under_panic.
>
> sounds terrible, ipoib bonding is supported since ~2007, thanks for
> reporting on that.
>
> > [ 122.871493] ipoib_hard_header: skb->head= ffff8808179d9400, skb->data= ffff8808179d9420, skb_headroom= 0x20
> > [ 123.055400] bond0: Releasing backup interface mthca_ib1
> > [ 123.560529] bond_compute_features:1112 bond0 bond_dev->hard_header_len = 14
> > [ 123.568822] CPU: 0 PID: 12336 Comm: ifdown-ib Not tainted 4.9.0-debug #1
>
> did you generate this trace by calling dump_stack or this is existing
> kernel code.
I inserted dump_stack to print this stack for debug.
>
> > Fixes: fc791b633515 ('IB/ipoib: move back IB LL address into the hard header')
>
> this is more of WA to avoid some crash or failure but not fixing the
> actual problem
>
> Erez, can you comment?
>
> Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next] rhashtable: remove insecure_max_entries param
From: Herbert Xu @ 2017-04-25 11:04 UTC (permalink / raw)
To: Florian Westphal; +Cc: netdev, fw
In-Reply-To: <20170425094134.21885-1-fw@strlen.de>
Florian Westphal <fw@strlen.de> wrote:
> no users in the tree, insecure_max_entries is always set to
> ht->p.max_size * 2 in rhtashtable_init().
>
> Replace only spot that uses it with a ht->p.max_size check.
I'd suggest that as this needs to be computed every time we insert
an element that you keep the value in struct rhashtable, but as an
internal value as opposed to a paramter that is set by the user.
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH] IB/IPoIB: Check the headroom size
From: Erez Shitrit @ 2017-04-25 11:11 UTC (permalink / raw)
To: Or Gerlitz
Cc: Honggang LI, Erez Shitrit, Doug Ledford, Hefty, Sean,
Hal Rosenstock, Paolo Abeni,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux Kernel,
Linux Netdev List
In-Reply-To: <CAJ3xEMg4_2ph7QwPsUb-tX-K4d2ppkqz98sPzytsmBCK=29WHw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Apr 25, 2017 at 1:32 PM, Or Gerlitz <gerlitz.or-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Tue, Apr 25, 2017 at 12:55 PM, Honggang LI <honli-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>> From: Honggang Li <honli-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>
>> Minimal hard_header_len set by bond_compute_features is ETH_HLEN, which
>> is smaller than IPOIB_HARD_LEN. ipoib_hard_header should check the
>> size of headroom to avoid skb_under_panic.
>
> sounds terrible, ipoib bonding is supported since ~2007, thanks for
> reporting on that.
>
>> [ 122.871493] ipoib_hard_header: skb->head= ffff8808179d9400, skb->data= ffff8808179d9420, skb_headroom= 0x20
>> [ 123.055400] bond0: Releasing backup interface mthca_ib1
>> [ 123.560529] bond_compute_features:1112 bond0 bond_dev->hard_header_len = 14
>> [ 123.568822] CPU: 0 PID: 12336 Comm: ifdown-ib Not tainted 4.9.0-debug #1
>
> did you generate this trace by calling dump_stack or this is existing
> kernel code.
>
>> Fixes: fc791b633515 ('IB/ipoib: move back IB LL address into the hard header')
>
> this is more of WA to avoid some crash or failure but not fixing the
> actual problem
>
> Erez, can you comment?
We saw that after commit fc791b633515, it happened while removing bond
interface after its slaves (ipoib interface) removed.
At that point the bond interface sets its dev_harheader_len to be as
eth interfaces (14 instead of 24), and if a process which doesn't
aware of the slaves removal or was at the middle of the sending tries
to send (igmp) packet it goes to ipoib with no space in the skb for
it, and here comes the panic.
I agree with you that this fix is w/a, and it is a fix in the data
path for all the packets while the panic is in a control flow. It
probably should be fixed in the bonding driver.
>
> Or.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] IB/IPoIB: Check the headroom size
From: Or Gerlitz @ 2017-04-25 11:14 UTC (permalink / raw)
To: Erez Shitrit
Cc: Honggang LI, Erez Shitrit, Doug Ledford, Hefty, Sean,
Hal Rosenstock, Paolo Abeni,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux Kernel,
Linux Netdev List
In-Reply-To: <CAAk-MO8O19iC2Yn-BMn5pKTAYxaSzGPMyta=fwes3XSvzmz_cQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Apr 25, 2017 at 2:11 PM, Erez Shitrit <erezsh-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org> wrote:
> On Tue, Apr 25, 2017 at 1:32 PM, Or Gerlitz <gerlitz.or-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> On Tue, Apr 25, 2017 at 12:55 PM, Honggang LI <honli-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>> From: Honggang Li <honli-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>>
>>> Minimal hard_header_len set by bond_compute_features is ETH_HLEN, which
>>> is smaller than IPOIB_HARD_LEN. ipoib_hard_header should check the
>>> size of headroom to avoid skb_under_panic.
>>
>> sounds terrible, ipoib bonding is supported since ~2007, thanks for
>> reporting on that.
>>
>>> [ 122.871493] ipoib_hard_header: skb->head= ffff8808179d9400, skb->data= ffff8808179d9420, skb_headroom= 0x20
>>> [ 123.055400] bond0: Releasing backup interface mthca_ib1
>>> [ 123.560529] bond_compute_features:1112 bond0 bond_dev->hard_header_len = 14
>>> [ 123.568822] CPU: 0 PID: 12336 Comm: ifdown-ib Not tainted 4.9.0-debug #1
>>
>> did you generate this trace by calling dump_stack or this is existing
>> kernel code.
>>
>>> Fixes: fc791b633515 ('IB/ipoib: move back IB LL address into the hard header')
>>
>> this is more of WA to avoid some crash or failure but not fixing the
>> actual problem
>>
>> Erez, can you comment?
>
> We saw that after commit fc791b633515, it happened while removing bond
> interface after its slaves (ipoib interface) removed.
> At that point the bond interface sets its dev_harheader_len to be as
> eth interfaces (14 instead of 24), and if a process which doesn't
> aware of the slaves removal or was at the middle of the sending tries
> to send (igmp) packet it goes to ipoib with no space in the skb for
> it, and here comes the panic.
thanks for the info. Is this bug there since ipoib/bonding day one
(and hence my bug...)
or was indeed introduced later? if later, can you explain how
fc791b633515 introduced
that or you only know it by bisection?
> I agree with you that this fix is w/a, and it is a fix in the data
> path for all the packets while the panic is in a control flow. It
> probably should be fixed in the bonding driver.
so what's your suggestion? fc791b633515 is 6m old, and it means the bug
is in stable kernels and probably also in inbox drivers
Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH net-next] rhashtable: remove insecure_max_entries param
From: Florian Westphal @ 2017-04-25 11:23 UTC (permalink / raw)
To: Herbert Xu; +Cc: Florian Westphal, netdev
In-Reply-To: <20170425110415.GA25167@gondor.apana.org.au>
Herbert Xu <herbert@gondor.apana.org.au> wrote:
> Florian Westphal <fw@strlen.de> wrote:
> > no users in the tree, insecure_max_entries is always set to
> > ht->p.max_size * 2 in rhtashtable_init().
> >
> > Replace only spot that uses it with a ht->p.max_size check.
>
> I'd suggest that as this needs to be computed every time we insert
> an element that you keep the value in struct rhashtable, but as an
> internal value as opposed to a paramter that is set by the user.
What extra cost?
The only change is that ht->nelems has to be right-shifted by one,
I don't think that warrants extra space in struct rhashtable, its
already way too large (I think we can reduce its size further).
Thanks,
Florian
^ permalink raw reply
* [PATCH net-next] drivers: net: xgene-v2: Fix error return code in xge_mdio_config()
From: Wei Yongjun @ 2017-04-25 11:36 UTC (permalink / raw)
To: Iyappan Subramanian, Keyur Chudgar; +Cc: Wei Yongjun, netdev
From: Wei Yongjun <weiyongjun1@huawei.com>
Fix to return error code -ENODEV from the no PHY found error
handling case instead of 0, as done elsewhere in this function.
Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
---
drivers/net/ethernet/apm/xgene-v2/mdio.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/apm/xgene-v2/mdio.c b/drivers/net/ethernet/apm/xgene-v2/mdio.c
index a583c6a..f5fe3bb 100644
--- a/drivers/net/ethernet/apm/xgene-v2/mdio.c
+++ b/drivers/net/ethernet/apm/xgene-v2/mdio.c
@@ -135,6 +135,7 @@ int xge_mdio_config(struct net_device *ndev)
phydev = phy_find_first(mdio_bus);
if (!phydev) {
dev_err(dev, "no PHY found\n");
+ ret = -ENODEV;
goto err;
}
phydev = phy_connect(ndev, phydev_name(phydev),
^ permalink raw reply related
* Re: [PATCH] stmmac: Add support for SIMATIC IOT2000 platform
From: Andy Shevchenko @ 2017-04-25 11:40 UTC (permalink / raw)
To: Jan Kiszka
Cc: Giuseppe Cavallaro, Alexandre Torgue, netdev,
Linux Kernel Mailing List, Sascha Weisenberger
In-Reply-To: <42fd4a72-526c-cbd9-52db-9d8b495035ee@siemens.com>
On Tue, Apr 25, 2017 at 1:07 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 2017-04-25 11:46, Andy Shevchenko wrote:
>> On Tue, Apr 25, 2017 at 12:00 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>> On 2017-04-25 09:30, Andy Shevchenko wrote:
>>>> On Tue, Apr 25, 2017 at 8:44 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>>>> On 2017-04-24 23:27, Andy Shevchenko wrote:
>>>>>> On Mon, Apr 24, 2017 at 10:27 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>>>>>> + {
>>>>>>> + .name = "SIMATIC IOT2000",
>>>>>>> + .asset_tag = "6ES7647-0AA00-0YA2",
>>>>>>> + .func = 6,
>>>>>>> + .phy_addr = 1,
>>>>>>> + },
>>>>>>
>>>>>> The below has same definition disregard on asset_tag.
>>>>>>
>>>>>
>>>>> There is a small difference in the asset tag, just not at the last digit
>>>>> where one may expect it, look:
>>>>>
>>>>> ...-0YA2 -> IOT2020
>>>>> ...-1YA2 -> IOT2040
>>>>
>>>> Yes. And how does it change my statement? You may use one record here
>>>> instead of two.
>>>
>>> How? Please be more verbose in your comments.
>>
>> {
>> .name = "SIMATIC IOT2000",
>> .func = 6,
>> .phy_addr = 1,
>> },
>> {
>> .name = "SIMATIC IOT2000",
>> .func = 7,
>> .phy_addr = 1,
>> },
>>
>> That's all what you need.
>
> Nope. Again: the asset tag is the way to tell both apart AND to ensure
> that we do not match on future devices.
One step at a time. We don't care of future devices. When we will have
an issue we will look at it.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH] stmmac: Add support for SIMATIC IOT2000 platform
From: Andy Shevchenko @ 2017-04-25 11:42 UTC (permalink / raw)
To: Jan Kiszka
Cc: Giuseppe Cavallaro, Alexandre Torgue, netdev,
Linux Kernel Mailing List, Sascha Weisenberger
In-Reply-To: <3eae5626-1ef2-03ae-635e-27faed085c68@siemens.com>
On Tue, Apr 25, 2017 at 1:09 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
> On 2017-04-25 12:07, Jan Kiszka wrote:
>> On 2017-04-25 11:46, Andy Shevchenko wrote:
>>> On Tue, Apr 25, 2017 at 12:00 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>>> On 2017-04-25 09:30, Andy Shevchenko wrote:
>>>>> On Tue, Apr 25, 2017 at 8:44 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>>>>> On 2017-04-24 23:27, Andy Shevchenko wrote:
>>>>>>> On Mon, Apr 24, 2017 at 10:27 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>> {
>>> .name = "SIMATIC IOT2000",
>>> .func = 6,
>>> .phy_addr = 1,
>>> },
>>> {
>>> .name = "SIMATIC IOT2000",
>>> .func = 7,
>>> .phy_addr = 1,
>>> },
>>>
>>> That's all what you need.
>>
>> Nope. Again: the asset tag is the way to tell both apart AND to ensure
>> that we do not match on future devices.
> To be more verbose: your version (which is our old one) would even
> enable the second, not connected port on the IOT2020. Incorrectly.
So, name has 2000 for 2020 device? It's clear bug in DMI table you have. :-(
What else do you have in DMI which can be used to distinguish those devices?
> Plus
> the risk to match different future devices.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* Re: [PATCH] IB/IPoIB: Check the headroom size
From: Erez Shitrit @ 2017-04-25 11:43 UTC (permalink / raw)
To: Or Gerlitz
Cc: Honggang LI, Erez Shitrit, Doug Ledford, Hefty, Sean,
Hal Rosenstock, Paolo Abeni,
linux-rdma-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux Kernel,
Linux Netdev List
In-Reply-To: <CAJ3xEMgw=9sj3rdahPEiST_yDfDJPNSZZLRn43tnb3bK4_RPzg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Tue, Apr 25, 2017 at 2:14 PM, Or Gerlitz <gerlitz.or-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> On Tue, Apr 25, 2017 at 2:11 PM, Erez Shitrit <erezsh-LDSdmyG8hGV8YrgS2mwiifqBs+8SCbDb@public.gmane.org> wrote:
>> On Tue, Apr 25, 2017 at 1:32 PM, Or Gerlitz <gerlitz.or-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>> On Tue, Apr 25, 2017 at 12:55 PM, Honggang LI <honli-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>>> From: Honggang Li <honli-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
>>>>
>>>> Minimal hard_header_len set by bond_compute_features is ETH_HLEN, which
>>>> is smaller than IPOIB_HARD_LEN. ipoib_hard_header should check the
>>>> size of headroom to avoid skb_under_panic.
>>>
>>> sounds terrible, ipoib bonding is supported since ~2007, thanks for
>>> reporting on that.
>>>
>>>> [ 122.871493] ipoib_hard_header: skb->head= ffff8808179d9400, skb->data= ffff8808179d9420, skb_headroom= 0x20
>>>> [ 123.055400] bond0: Releasing backup interface mthca_ib1
>>>> [ 123.560529] bond_compute_features:1112 bond0 bond_dev->hard_header_len = 14
>>>> [ 123.568822] CPU: 0 PID: 12336 Comm: ifdown-ib Not tainted 4.9.0-debug #1
>>>
>>> did you generate this trace by calling dump_stack or this is existing
>>> kernel code.
>>>
>>>> Fixes: fc791b633515 ('IB/ipoib: move back IB LL address into the hard header')
>>>
>>> this is more of WA to avoid some crash or failure but not fixing the
>>> actual problem
>>>
>>> Erez, can you comment?
>>
>> We saw that after commit fc791b633515, it happened while removing bond
>> interface after its slaves (ipoib interface) removed.
>> At that point the bond interface sets its dev_harheader_len to be as
>> eth interfaces (14 instead of 24), and if a process which doesn't
>> aware of the slaves removal or was at the middle of the sending tries
>> to send (igmp) packet it goes to ipoib with no space in the skb for
>> it, and here comes the panic.
>
> thanks for the info. Is this bug there since ipoib/bonding day one
> (and hence my bug...)
> or was indeed introduced later? if later, can you explain how
> fc791b633515 introduced
> that or you only know it by bisection?
commit "fc791b633515" changes the size of the dev_hardlen to be 24 and
required 24 extra bytes in the skb, before it was only 4, if skb is
aligned to eth "mode" it already has 14 bytes for hard-header.
So only after that commit we have the issue.
>
>> I agree with you that this fix is w/a, and it is a fix in the data
>> path for all the packets while the panic is in a control flow. It
>> probably should be fixed in the bonding driver.
>
> so what's your suggestion? fc791b633515 is 6m old, and it means the bug
> is in stable kernels and probably also in inbox drivers
>
> Or.
--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next v7 0/3] net sched actions: improve dump performance
From: Jamal Hadi Salim @ 2017-04-25 11:49 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <jhs@mojatatu.com>
changes since v6:
-----------------
1) DaveM:
New rules for netlink messages. From now on we are going to start
checking for bits that are not used and rejecting anything we dont
understand. In the future this is going to require major changes
to user space code (tc etc). This is just a start.
To quote, David:
"
Again, bits you aren't using now, make sure userspace doesn't
set them. And if it does, reject.
"
2) Jiri:
a)Fix the commit message to properly use "Fixes" description
b)Align assignments for nla_policy
Changes since v5:
----------------
0)
Remove use of BIT() because it is kernel specific. Requires a separate
patch (Jiri can submit that in his cleanups)
1)To paraphrase Eric D.
"memcpy(nla_data(count_attr), &cb->args[1], sizeof(u32));
wont work on 64bit BE machines because cb->args[1]
(which is 64 bit is larger in size than sizeof(u32))"
Fixed
2) Jiri Pirko
i) Spotted a bug fix mixed in the patch for wrong TLV
fix. Add patch 1/3 to address this. Make part of this
series because of dependencies.
ii) Rename ACT_LARGE_DUMP_ON -> TCA_FLAG_LARGE_DUMP_ON
iii) Satisfy Jiri's obsession against the noun "tcaa"
a)Rename struct nlattr *tcaa --> struct nlattr *tb
b)Rename TCAA_ACT_XXX -> TCA_ROOT_XXX
Changes since v4:
-----------------
1) Eric D.
pointed out that when all skb space is used up by the dump
there will be no space to insert the TCAA_ACT_COUNT attribute.
2) Jiri:
i) Change:
enum {
TCAA_UNSPEC,
TCAA_ACT_TAB,
TCAA_ACT_FLAGS,
TCAA_ACT_COUNT,
TCAA_ACT_TIME_FILTER,
__TCAA_MAX
};
#define TCAA_MAX (__TCAA_MAX - 1)
#define ACT_LARGE_DUMP_ON (1 << 0)
to:
enum {
TCAA_UNSPEC,
TCAA_ACT_TAB,
#define TCA_ACT_TAB TCAA_ACT_TAB
TCAA_ACT_FLAGS,
TCAA_ACT_COUNT,
__TCAA_MAX,
#define TCAA_MAX (__TCAA_MAX - 1)
};
#define ACT_LARGE_DUMP_ON BIT(0)
Jiri plans to followup with the rest of the code to make the
style consistent.
ii) Rename attribute TCAA_ACT_TIME_FILTER --> TCAA_ACT_TIME_DELTA
iii) Rename variable jiffy_filter --> jiffy_since
iv) Rename msecs_filter --> msecs_since
v) get rid of unused cb->args[0] and rename cb->args[4] to cb->args[0]
Jamal Hadi Salim (3):
net sched actions: User proper root attribute table for actions
net sched actions: dump more than TCA_ACT_MAX_PRIO actions per batch
net sched actions: add time filter for action dumping
include/uapi/linux/rtnetlink.h | 22 ++++++++++++--
net/sched/act_api.c | 66 +++++++++++++++++++++++++++++++++++-------
2 files changed, 75 insertions(+), 13 deletions(-)
--
1.9.1
Jamal Hadi Salim (3):
net sched actions: Use proper root attribute table for actions
net sched actions: dump more than TCA_ACT_MAX_PRIO actions per batch
net sched actions: add time filter for action dumping
include/uapi/linux/rtnetlink.h | 23 ++++++++++--
net/sched/act_api.c | 79 ++++++++++++++++++++++++++++++++++++------
2 files changed, 89 insertions(+), 13 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next v7 1/3] net sched actions: Use proper root attribute table for actions
From: Jamal Hadi Salim @ 2017-04-25 11:49 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <1493120988-11765-1-git-send-email-jhs@emojatatu.com>
From: Jamal Hadi Salim <jhs@mojatatu.com>
Bug fix for an issue which has been around for about a decade.
We got away with it because the enumeration was larger than needed.
Fixes: 7ba699c604ab ("[NET_SCHED]: Convert actions from rtnetlink to new netlink API")
Suggested-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
net/sched/act_api.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 82b1d48..9ce22b7 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -997,7 +997,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
- struct nlattr *tca[TCA_ACT_MAX + 1];
+ struct nlattr *tca[TCAA_MAX + 1];
u32 portid = skb ? NETLINK_CB(skb).portid : 0;
int ret = 0, ovr = 0;
@@ -1005,7 +1005,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
- ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL,
+ ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCAA_MAX, NULL,
extack);
if (ret < 0)
return ret;
--
1.9.1
^ permalink raw reply related
* [PATCH net-next v7 1/3] net sched actions: Use proper root attribute table for actions
From: Jamal Hadi Salim @ 2017-04-25 11:49 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <1493120988-11765-1-git-send-email-jhs@emojatatu.com>
From: Jamal Hadi Salim <jhs@mojatatu.com>
Bug fix for an issue which has been around for about a decade.
We got away with it because the enumeration was larger than needed.
Fixes: 7ba699c604ab ("[NET_SCHED]: Convert actions from rtnetlink to new netlink API")
Suggested-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
net/sched/act_api.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 82b1d48..9ce22b7 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -997,7 +997,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
- struct nlattr *tca[TCA_ACT_MAX + 1];
+ struct nlattr *tca[TCAA_MAX + 1];
u32 portid = skb ? NETLINK_CB(skb).portid : 0;
int ret = 0, ovr = 0;
@@ -1005,7 +1005,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
- ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL,
+ ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCAA_MAX, NULL,
extack);
if (ret < 0)
return ret;
--
1.9.1
^ permalink raw reply related
* [PATCH net-next v7 3/3] net sched actions: add time filter for action dumping
From: Jamal Hadi Salim @ 2017-04-25 11:49 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <1493120988-11765-1-git-send-email-jhs@emojatatu.com>
From: Jamal Hadi Salim <jhs@mojatatu.com>
This adds support for filtering based on time since last used.
When we are dumping a large number of actions it is useful to
have the option of filtering based on when the action was last
used to reduce the amount of data crossing to user space.
With this patch the user space app sets the TCA_ROOT_TIME_DELTA
attribute with the value in milliseconds with "time of interest
since now". The kernel converts this to jiffies and does the
filtering comparison matching entries that have seen activity
since then and returns them to user space.
Old kernels and old tc continue to work in legacy mode since
they dont specify this attribute.
Some example (we have 400 actions bound to 400 filters); at
installation time using hacked tc which sets the time of
interest to 120 seconds:
prompt$ hackedtc actions ls action gact | grep index | wc -l
400
go get some coffee and wait for > 120 seconds and try again:
prompt$ hackedtc actions ls action gact | grep index | wc -l
0
Lets see a filter bound to one of these actions:
..
filter pref 10 u32
filter pref 10 u32 fh 800: ht divisor 1
filter pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 (rule hit 2 success 1)
match 7f000002/ffffffff at 12 (success 1 )
action order 1: gact action pass
random type none pass val 0
index 23 ref 2 bind 1 installed 1145 sec used 802 sec
Action statistics:
Sent 84 bytes 1 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
....
that coffee took long, no? It was good.
Now lets ping -c 1 127.0.0.2, then run the actions again:
prompt$ hackedtc actions ls action gact | grep index | wc -l
1
More details please:
prompt$ hackedtc -s actions ls action gact
action order 0: gact action pass
random type none pass val 0
index 23 ref 2 bind 1 installed 1270 sec used 30 sec
Action statistics:
Sent 168 bytes 2 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
And the filter?
filter pref 10 u32
filter pref 10 u32 fh 800: ht divisor 1
filter pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 (rule hit 4 success 2)
match 7f000002/ffffffff at 12 (success 2 )
action order 1: gact action pass
random type none pass val 0
index 23 ref 2 bind 1 installed 1324 sec used 84 sec
Action statistics:
Sent 168 bytes 2 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
include/uapi/linux/rtnetlink.h | 1 +
net/sched/act_api.c | 22 ++++++++++++++++++++--
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 5875467..39c7499 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -681,6 +681,7 @@ enum {
#define TCA_ACT_TAB TCA_ROOT_TAB
TCA_ROOT_FLAGS,
TCA_ROOT_COUNT,
+ TCA_ROOT_TIME_DELTA, /* in msecs */
__TCA_ROOT_MAX,
#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
};
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 2756213..c0aee2c 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -84,6 +84,7 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
{
int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
u32 act_flags = cb->args[2];
+ unsigned long jiffy_since = cb->args[3];
struct nlattr *nest;
spin_lock_bh(&hinfo->lock);
@@ -101,6 +102,11 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
if (index < s_i)
continue;
+ if (jiffy_since &&
+ time_after(jiffy_since,
+ (unsigned long)p->tcfa_tm.lastuse))
+ continue;
+
nest = nla_nest_start(skb, n_i);
if (nest == NULL)
goto nla_put_failure;
@@ -118,9 +124,11 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
}
}
done:
+ if (index > 0)
+ cb->args[0] = index + 1;
+
spin_unlock_bh(&hinfo->lock);
if (n_i) {
- cb->args[0] += n_i;
if (act_flags & TCA_FLAG_LARGE_DUMP_ON)
cb->args[1] = n_i;
}
@@ -999,7 +1007,8 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
}
static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
- [TCA_ROOT_FLAGS] = { .type = NLA_U32 },
+ [TCA_ROOT_FLAGS] = { .type = NLA_U32 },
+ [TCA_ROOT_TIME_DELTA] = { .type = NLA_U32 },
};
static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
@@ -1099,7 +1108,9 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
struct nlattr *count_attr = NULL;
struct nlattr *tb[TCA_ROOT_MAX + 1];
+ unsigned long jiffy_since = 0;
struct nlattr *kind = NULL;
+ u32 msecs_since = 0;
u32 act_flags = 0;
u32 act_count = 0;
@@ -1124,12 +1135,19 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
if (act_flags && !tca_flags_valid(act_flags))
return -EINVAL;
+ if (tb[TCA_ROOT_TIME_DELTA])
+ msecs_since = nla_get_u32(tb[TCA_ROOT_TIME_DELTA]);
+
nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
cb->nlh->nlmsg_type, sizeof(*t), 0);
if (!nlh)
goto out_module_put;
+ if (msecs_since)
+ jiffy_since = jiffies - msecs_to_jiffies(msecs_since);
+
cb->args[2] = act_flags;
+ cb->args[3] = jiffy_since;
t = nlmsg_data(nlh);
t->tca_family = AF_UNSPEC;
t->tca__pad1 = 0;
--
1.9.1
^ permalink raw reply related
* [PATCH net-next v7 2/3] net sched actions: dump more than TCA_ACT_MAX_PRIO actions per batch
From: Jamal Hadi Salim @ 2017-04-25 11:49 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <1493120988-11765-1-git-send-email-jhs@emojatatu.com>
From: Jamal Hadi Salim <jhs@mojatatu.com>
When you dump hundreds of thousands of actions, getting only 32 per
dump batch even when the socket buffer and memory allocations allow
is inefficient.
With this change, the user will get as many as possibly fitting
within the given constraints available to the kernel.
The top level action TLV space is extended. An attribute
TCA_ROOT_FLAGS is used to carry flags; flag TCA_FLAG_LARGE_DUMP_ON
is set by the user indicating the user is capable of processing
these large dumps. Older user space which doesnt set this flag
doesnt get the large (than 32) batches.
The kernel uses the TCA_ROOT_COUNT attribute to tell the user how many
actions are put in a single batch. As such user space app knows how long
to iterate (independent of the type of action being dumped)
instead of hardcoded maximum of 32.
Some results dumping 1.5M actions, first unpatched tc which the
kernel doesnt help:
prompt$ time -p tc actions ls action gact | grep index | wc -l
1500000
real 1388.43
user 2.07
sys 1386.79
Now lets see a patched tc which sets the correct flags when requesting
a dump:
prompt$ time -p updatedtc actions ls action gact | grep index | wc -l
1500000
real 178.13
user 2.02
sys 176.96
That is about 8x performance improvement for tc which sets its
receive buffer to about 32K.
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
include/uapi/linux/rtnetlink.h | 22 ++++++++++++++--
net/sched/act_api.c | 59 +++++++++++++++++++++++++++++++++++-------
2 files changed, 69 insertions(+), 12 deletions(-)
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index cce0613..5875467 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -674,10 +674,28 @@ struct tcamsg {
unsigned char tca__pad1;
unsigned short tca__pad2;
};
+
+enum {
+ TCA_ROOT_UNSPEC,
+ TCA_ROOT_TAB,
+#define TCA_ACT_TAB TCA_ROOT_TAB
+ TCA_ROOT_FLAGS,
+ TCA_ROOT_COUNT,
+ __TCA_ROOT_MAX,
+#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
+};
+
#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
-#define TCA_ACT_TAB 1 /* attr type must be >=1 */
-#define TCAA_MAX 1
+/* tcamsg flags stored in attribute TCA_ROOT_FLAGS
+ *
+ * TCA_FLAG_LARGE_DUMP_ON user->kernel to request for larger than TCA_ACT_MAX_PRIO
+ * actions in a dump. All dump responses will contain the number of actions
+ * being dumped stored in for user app's consumption in TCA_ROOT_COUNT
+ *
+ */
+#define TCA_FLAG_LARGE_DUMP_ON (1 << 0)
+#define VALID_TCA_FLAGS TCA_FLAG_LARGE_DUMP_ON
/* New extended info filters for IFLA_EXT_MASK */
#define RTEXT_FILTER_VF (1 << 0)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 9ce22b7..2756213 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -83,6 +83,7 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
struct netlink_callback *cb)
{
int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
+ u32 act_flags = cb->args[2];
struct nlattr *nest;
spin_lock_bh(&hinfo->lock);
@@ -111,14 +112,18 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
}
nla_nest_end(skb, nest);
n_i++;
- if (n_i >= TCA_ACT_MAX_PRIO)
+ if (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) &&
+ n_i >= TCA_ACT_MAX_PRIO)
goto done;
}
}
done:
spin_unlock_bh(&hinfo->lock);
- if (n_i)
+ if (n_i) {
cb->args[0] += n_i;
+ if (act_flags & TCA_FLAG_LARGE_DUMP_ON)
+ cb->args[1] = n_i;
+ }
return n_i;
nla_put_failure:
@@ -993,11 +998,15 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
return tcf_add_notify(net, n, &actions, portid);
}
+static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
+ [TCA_ROOT_FLAGS] = { .type = NLA_U32 },
+};
+
static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
- struct nlattr *tca[TCAA_MAX + 1];
+ struct nlattr *tca[TCA_ROOT_MAX + 1];
u32 portid = skb ? NETLINK_CB(skb).portid : 0;
int ret = 0, ovr = 0;
@@ -1005,7 +1014,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
- ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCAA_MAX, NULL,
+ ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ROOT_MAX, NULL,
extack);
if (ret < 0)
return ret;
@@ -1046,16 +1055,12 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
return ret;
}
-static struct nlattr *find_dump_kind(const struct nlmsghdr *n)
+static struct nlattr *find_dump_kind(struct nlattr **nla)
{
struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1];
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
- struct nlattr *nla[TCAA_MAX + 1];
struct nlattr *kind;
- if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX,
- NULL, NULL) < 0)
- return NULL;
tb1 = nla[TCA_ACT_TAB];
if (tb1 == NULL)
return NULL;
@@ -1073,6 +1078,16 @@ static struct nlattr *find_dump_kind(const struct nlmsghdr *n)
return kind;
}
+static inline bool tca_flags_valid(u32 act_flags)
+{
+ u32 invalid_flags_mask = ~VALID_TCA_FLAGS;
+
+ if (act_flags & invalid_flags_mask)
+ return false;
+
+ return true;
+}
+
static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
{
struct net *net = sock_net(skb->sk);
@@ -1082,8 +1097,18 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
struct tc_action_ops *a_o;
int ret = 0;
struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
- struct nlattr *kind = find_dump_kind(cb->nlh);
+ struct nlattr *count_attr = NULL;
+ struct nlattr *tb[TCA_ROOT_MAX + 1];
+ struct nlattr *kind = NULL;
+ u32 act_flags = 0;
+ u32 act_count = 0;
+
+ ret = nlmsg_parse(cb->nlh, sizeof(struct tcamsg), tb, TCA_ROOT_MAX,
+ tcaa_policy, NULL);
+ if (ret < 0)
+ return ret;
+ kind = find_dump_kind(tb);
if (kind == NULL) {
pr_info("tc_dump_action: action bad kind\n");
return 0;
@@ -1093,14 +1118,25 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
if (a_o == NULL)
return 0;
+ if (tb[TCA_ROOT_FLAGS])
+ act_flags = nla_get_u32(tb[TCA_ROOT_FLAGS]);
+
+ if (act_flags && !tca_flags_valid(act_flags))
+ return -EINVAL;
+
nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
cb->nlh->nlmsg_type, sizeof(*t), 0);
if (!nlh)
goto out_module_put;
+
+ cb->args[2] = act_flags;
t = nlmsg_data(nlh);
t->tca_family = AF_UNSPEC;
t->tca__pad1 = 0;
t->tca__pad2 = 0;
+ count_attr = nla_reserve(skb, TCA_ROOT_COUNT, sizeof(u32));
+ if (!count_attr)
+ goto out_module_put;
nest = nla_nest_start(skb, TCA_ACT_TAB);
if (nest == NULL)
@@ -1113,6 +1149,9 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
if (ret > 0) {
nla_nest_end(skb, nest);
ret = skb->len;
+ act_count = cb->args[1];
+ memcpy(nla_data(count_attr), &act_count, sizeof(u32));
+ cb->args[1] = 0;
} else
nlmsg_trim(skb, b);
--
1.9.1
^ permalink raw reply related
* Re: [PATCH net-next v7 0/3] net sched actions: improve dump performance
From: Jamal Hadi Salim @ 2017-04-25 11:52 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev
In-Reply-To: <1493120988-11765-1-git-send-email-jhs@emojatatu.com>
Grr. I gitta git my git-foo right.
Patch 1 repeated twice - I'll send v8.
cheers,
jamal
^ permalink raw reply
* [PATCH net-next v8 0/3] net sched actions: improve dump performance
From: Jamal Hadi Salim @ 2017-04-25 11:54 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
From: Jamal Hadi Salim <jhs@mojatatu.com>
Changes since v7:
-----------------
Jamal:
Patch 1 went out twice. Resend without two copies of patch 1
changes since v6:
-----------------
1) DaveM:
New rules for netlink messages. From now on we are going to start
checking for bits that are not used and rejecting anything we dont
understand. In the future this is going to require major changes
to user space code (tc etc). This is just a start.
To quote, David:
"
Again, bits you aren't using now, make sure userspace doesn't
set them. And if it does, reject.
"
2) Jiri:
a)Fix the commit message to properly use "Fixes" description
b)Align assignments for nla_policy
Changes since v5:
----------------
0)
Remove use of BIT() because it is kernel specific. Requires a separate
patch (Jiri can submit that in his cleanups)
1)To paraphrase Eric D.
"memcpy(nla_data(count_attr), &cb->args[1], sizeof(u32));
wont work on 64bit BE machines because cb->args[1]
(which is 64 bit is larger in size than sizeof(u32))"
Fixed
2) Jiri Pirko
i) Spotted a bug fix mixed in the patch for wrong TLV
fix. Add patch 1/3 to address this. Make part of this
series because of dependencies.
ii) Rename ACT_LARGE_DUMP_ON -> TCA_FLAG_LARGE_DUMP_ON
iii) Satisfy Jiri's obsession against the noun "tcaa"
a)Rename struct nlattr *tcaa --> struct nlattr *tb
b)Rename TCAA_ACT_XXX -> TCA_ROOT_XXX
Changes since v4:
-----------------
1) Eric D.
pointed out that when all skb space is used up by the dump
there will be no space to insert the TCAA_ACT_COUNT attribute.
2) Jiri:
i) Change:
enum {
TCAA_UNSPEC,
TCAA_ACT_TAB,
TCAA_ACT_FLAGS,
TCAA_ACT_COUNT,
TCAA_ACT_TIME_FILTER,
__TCAA_MAX
};
#define TCAA_MAX (__TCAA_MAX - 1)
#define ACT_LARGE_DUMP_ON (1 << 0)
to:
enum {
TCAA_UNSPEC,
TCAA_ACT_TAB,
#define TCA_ACT_TAB TCAA_ACT_TAB
TCAA_ACT_FLAGS,
TCAA_ACT_COUNT,
__TCAA_MAX,
#define TCAA_MAX (__TCAA_MAX - 1)
};
#define ACT_LARGE_DUMP_ON BIT(0)
Jiri plans to followup with the rest of the code to make the
style consistent.
ii) Rename attribute TCAA_ACT_TIME_FILTER --> TCAA_ACT_TIME_DELTA
iii) Rename variable jiffy_filter --> jiffy_since
iv) Rename msecs_filter --> msecs_since
v) get rid of unused cb->args[0] and rename cb->args[4] to cb->args[0]
Jamal Hadi Salim (3):
net sched actions: User proper root attribute table for actions
net sched actions: dump more than TCA_ACT_MAX_PRIO actions per batch
net sched actions: add time filter for action dumping
include/uapi/linux/rtnetlink.h | 22 ++++++++++++--
net/sched/act_api.c | 66 +++++++++++++++++++++++++++++++++++-------
2 files changed, 75 insertions(+), 13 deletions(-)
--
1.9.1
Jamal Hadi Salim (3):
net sched actions: Use proper root attribute table for actions
net sched actions: dump more than TCA_ACT_MAX_PRIO actions per batch
net sched actions: add time filter for action dumping
include/uapi/linux/rtnetlink.h | 23 ++++++++++--
net/sched/act_api.c | 79 ++++++++++++++++++++++++++++++++++++------
2 files changed, 89 insertions(+), 13 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH net-next v8 1/3] net sched actions: Use proper root attribute table for actions
From: Jamal Hadi Salim @ 2017-04-25 11:54 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <1493121247-11863-1-git-send-email-jhs@emojatatu.com>
From: Jamal Hadi Salim <jhs@mojatatu.com>
Bug fix for an issue which has been around for about a decade.
We got away with it because the enumeration was larger than needed.
Fixes: 7ba699c604ab ("[NET_SCHED]: Convert actions from rtnetlink to new netlink API")
Suggested-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
net/sched/act_api.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 82b1d48..9ce22b7 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -997,7 +997,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
- struct nlattr *tca[TCA_ACT_MAX + 1];
+ struct nlattr *tca[TCAA_MAX + 1];
u32 portid = skb ? NETLINK_CB(skb).portid : 0;
int ret = 0, ovr = 0;
@@ -1005,7 +1005,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
- ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL,
+ ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCAA_MAX, NULL,
extack);
if (ret < 0)
return ret;
--
1.9.1
^ permalink raw reply related
* [PATCH net-next v8 2/3] net sched actions: dump more than TCA_ACT_MAX_PRIO actions per batch
From: Jamal Hadi Salim @ 2017-04-25 11:54 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <1493121247-11863-1-git-send-email-jhs@emojatatu.com>
From: Jamal Hadi Salim <jhs@mojatatu.com>
When you dump hundreds of thousands of actions, getting only 32 per
dump batch even when the socket buffer and memory allocations allow
is inefficient.
With this change, the user will get as many as possibly fitting
within the given constraints available to the kernel.
The top level action TLV space is extended. An attribute
TCA_ROOT_FLAGS is used to carry flags; flag TCA_FLAG_LARGE_DUMP_ON
is set by the user indicating the user is capable of processing
these large dumps. Older user space which doesnt set this flag
doesnt get the large (than 32) batches.
The kernel uses the TCA_ROOT_COUNT attribute to tell the user how many
actions are put in a single batch. As such user space app knows how long
to iterate (independent of the type of action being dumped)
instead of hardcoded maximum of 32.
Some results dumping 1.5M actions, first unpatched tc which the
kernel doesnt help:
prompt$ time -p tc actions ls action gact | grep index | wc -l
1500000
real 1388.43
user 2.07
sys 1386.79
Now lets see a patched tc which sets the correct flags when requesting
a dump:
prompt$ time -p updatedtc actions ls action gact | grep index | wc -l
1500000
real 178.13
user 2.02
sys 176.96
That is about 8x performance improvement for tc which sets its
receive buffer to about 32K.
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
include/uapi/linux/rtnetlink.h | 22 ++++++++++++++--
net/sched/act_api.c | 59 +++++++++++++++++++++++++++++++++++-------
2 files changed, 69 insertions(+), 12 deletions(-)
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index cce0613..5875467 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -674,10 +674,28 @@ struct tcamsg {
unsigned char tca__pad1;
unsigned short tca__pad2;
};
+
+enum {
+ TCA_ROOT_UNSPEC,
+ TCA_ROOT_TAB,
+#define TCA_ACT_TAB TCA_ROOT_TAB
+ TCA_ROOT_FLAGS,
+ TCA_ROOT_COUNT,
+ __TCA_ROOT_MAX,
+#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
+};
+
#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
-#define TCA_ACT_TAB 1 /* attr type must be >=1 */
-#define TCAA_MAX 1
+/* tcamsg flags stored in attribute TCA_ROOT_FLAGS
+ *
+ * TCA_FLAG_LARGE_DUMP_ON user->kernel to request for larger than TCA_ACT_MAX_PRIO
+ * actions in a dump. All dump responses will contain the number of actions
+ * being dumped stored in for user app's consumption in TCA_ROOT_COUNT
+ *
+ */
+#define TCA_FLAG_LARGE_DUMP_ON (1 << 0)
+#define VALID_TCA_FLAGS TCA_FLAG_LARGE_DUMP_ON
/* New extended info filters for IFLA_EXT_MASK */
#define RTEXT_FILTER_VF (1 << 0)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 9ce22b7..2756213 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -83,6 +83,7 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
struct netlink_callback *cb)
{
int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
+ u32 act_flags = cb->args[2];
struct nlattr *nest;
spin_lock_bh(&hinfo->lock);
@@ -111,14 +112,18 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
}
nla_nest_end(skb, nest);
n_i++;
- if (n_i >= TCA_ACT_MAX_PRIO)
+ if (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) &&
+ n_i >= TCA_ACT_MAX_PRIO)
goto done;
}
}
done:
spin_unlock_bh(&hinfo->lock);
- if (n_i)
+ if (n_i) {
cb->args[0] += n_i;
+ if (act_flags & TCA_FLAG_LARGE_DUMP_ON)
+ cb->args[1] = n_i;
+ }
return n_i;
nla_put_failure:
@@ -993,11 +998,15 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
return tcf_add_notify(net, n, &actions, portid);
}
+static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
+ [TCA_ROOT_FLAGS] = { .type = NLA_U32 },
+};
+
static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
- struct nlattr *tca[TCAA_MAX + 1];
+ struct nlattr *tca[TCA_ROOT_MAX + 1];
u32 portid = skb ? NETLINK_CB(skb).portid : 0;
int ret = 0, ovr = 0;
@@ -1005,7 +1014,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
- ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCAA_MAX, NULL,
+ ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ROOT_MAX, NULL,
extack);
if (ret < 0)
return ret;
@@ -1046,16 +1055,12 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
return ret;
}
-static struct nlattr *find_dump_kind(const struct nlmsghdr *n)
+static struct nlattr *find_dump_kind(struct nlattr **nla)
{
struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1];
struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
- struct nlattr *nla[TCAA_MAX + 1];
struct nlattr *kind;
- if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX,
- NULL, NULL) < 0)
- return NULL;
tb1 = nla[TCA_ACT_TAB];
if (tb1 == NULL)
return NULL;
@@ -1073,6 +1078,16 @@ static struct nlattr *find_dump_kind(const struct nlmsghdr *n)
return kind;
}
+static inline bool tca_flags_valid(u32 act_flags)
+{
+ u32 invalid_flags_mask = ~VALID_TCA_FLAGS;
+
+ if (act_flags & invalid_flags_mask)
+ return false;
+
+ return true;
+}
+
static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
{
struct net *net = sock_net(skb->sk);
@@ -1082,8 +1097,18 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
struct tc_action_ops *a_o;
int ret = 0;
struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
- struct nlattr *kind = find_dump_kind(cb->nlh);
+ struct nlattr *count_attr = NULL;
+ struct nlattr *tb[TCA_ROOT_MAX + 1];
+ struct nlattr *kind = NULL;
+ u32 act_flags = 0;
+ u32 act_count = 0;
+
+ ret = nlmsg_parse(cb->nlh, sizeof(struct tcamsg), tb, TCA_ROOT_MAX,
+ tcaa_policy, NULL);
+ if (ret < 0)
+ return ret;
+ kind = find_dump_kind(tb);
if (kind == NULL) {
pr_info("tc_dump_action: action bad kind\n");
return 0;
@@ -1093,14 +1118,25 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
if (a_o == NULL)
return 0;
+ if (tb[TCA_ROOT_FLAGS])
+ act_flags = nla_get_u32(tb[TCA_ROOT_FLAGS]);
+
+ if (act_flags && !tca_flags_valid(act_flags))
+ return -EINVAL;
+
nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
cb->nlh->nlmsg_type, sizeof(*t), 0);
if (!nlh)
goto out_module_put;
+
+ cb->args[2] = act_flags;
t = nlmsg_data(nlh);
t->tca_family = AF_UNSPEC;
t->tca__pad1 = 0;
t->tca__pad2 = 0;
+ count_attr = nla_reserve(skb, TCA_ROOT_COUNT, sizeof(u32));
+ if (!count_attr)
+ goto out_module_put;
nest = nla_nest_start(skb, TCA_ACT_TAB);
if (nest == NULL)
@@ -1113,6 +1149,9 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
if (ret > 0) {
nla_nest_end(skb, nest);
ret = skb->len;
+ act_count = cb->args[1];
+ memcpy(nla_data(count_attr), &act_count, sizeof(u32));
+ cb->args[1] = 0;
} else
nlmsg_trim(skb, b);
--
1.9.1
^ permalink raw reply related
* [PATCH net-next v8 3/3] net sched actions: add time filter for action dumping
From: Jamal Hadi Salim @ 2017-04-25 11:54 UTC (permalink / raw)
To: davem; +Cc: jiri, xiyou.wangcong, eric.dumazet, netdev, Jamal Hadi Salim
In-Reply-To: <1493121247-11863-1-git-send-email-jhs@emojatatu.com>
From: Jamal Hadi Salim <jhs@mojatatu.com>
This adds support for filtering based on time since last used.
When we are dumping a large number of actions it is useful to
have the option of filtering based on when the action was last
used to reduce the amount of data crossing to user space.
With this patch the user space app sets the TCA_ROOT_TIME_DELTA
attribute with the value in milliseconds with "time of interest
since now". The kernel converts this to jiffies and does the
filtering comparison matching entries that have seen activity
since then and returns them to user space.
Old kernels and old tc continue to work in legacy mode since
they dont specify this attribute.
Some example (we have 400 actions bound to 400 filters); at
installation time using hacked tc which sets the time of
interest to 120 seconds:
prompt$ hackedtc actions ls action gact | grep index | wc -l
400
go get some coffee and wait for > 120 seconds and try again:
prompt$ hackedtc actions ls action gact | grep index | wc -l
0
Lets see a filter bound to one of these actions:
..
filter pref 10 u32
filter pref 10 u32 fh 800: ht divisor 1
filter pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 (rule hit 2 success 1)
match 7f000002/ffffffff at 12 (success 1 )
action order 1: gact action pass
random type none pass val 0
index 23 ref 2 bind 1 installed 1145 sec used 802 sec
Action statistics:
Sent 84 bytes 1 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
....
that coffee took long, no? It was good.
Now lets ping -c 1 127.0.0.2, then run the actions again:
prompt$ hackedtc actions ls action gact | grep index | wc -l
1
More details please:
prompt$ hackedtc -s actions ls action gact
action order 0: gact action pass
random type none pass val 0
index 23 ref 2 bind 1 installed 1270 sec used 30 sec
Action statistics:
Sent 168 bytes 2 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
And the filter?
filter pref 10 u32
filter pref 10 u32 fh 800: ht divisor 1
filter pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:10 (rule hit 4 success 2)
match 7f000002/ffffffff at 12 (success 2 )
action order 1: gact action pass
random type none pass val 0
index 23 ref 2 bind 1 installed 1324 sec used 84 sec
Action statistics:
Sent 168 bytes 2 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
---
include/uapi/linux/rtnetlink.h | 1 +
net/sched/act_api.c | 22 ++++++++++++++++++++--
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 5875467..39c7499 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -681,6 +681,7 @@ enum {
#define TCA_ACT_TAB TCA_ROOT_TAB
TCA_ROOT_FLAGS,
TCA_ROOT_COUNT,
+ TCA_ROOT_TIME_DELTA, /* in msecs */
__TCA_ROOT_MAX,
#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
};
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 2756213..c0aee2c 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -84,6 +84,7 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
{
int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
u32 act_flags = cb->args[2];
+ unsigned long jiffy_since = cb->args[3];
struct nlattr *nest;
spin_lock_bh(&hinfo->lock);
@@ -101,6 +102,11 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
if (index < s_i)
continue;
+ if (jiffy_since &&
+ time_after(jiffy_since,
+ (unsigned long)p->tcfa_tm.lastuse))
+ continue;
+
nest = nla_nest_start(skb, n_i);
if (nest == NULL)
goto nla_put_failure;
@@ -118,9 +124,11 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
}
}
done:
+ if (index > 0)
+ cb->args[0] = index + 1;
+
spin_unlock_bh(&hinfo->lock);
if (n_i) {
- cb->args[0] += n_i;
if (act_flags & TCA_FLAG_LARGE_DUMP_ON)
cb->args[1] = n_i;
}
@@ -999,7 +1007,8 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
}
static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
- [TCA_ROOT_FLAGS] = { .type = NLA_U32 },
+ [TCA_ROOT_FLAGS] = { .type = NLA_U32 },
+ [TCA_ROOT_TIME_DELTA] = { .type = NLA_U32 },
};
static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
@@ -1099,7 +1108,9 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
struct nlattr *count_attr = NULL;
struct nlattr *tb[TCA_ROOT_MAX + 1];
+ unsigned long jiffy_since = 0;
struct nlattr *kind = NULL;
+ u32 msecs_since = 0;
u32 act_flags = 0;
u32 act_count = 0;
@@ -1124,12 +1135,19 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
if (act_flags && !tca_flags_valid(act_flags))
return -EINVAL;
+ if (tb[TCA_ROOT_TIME_DELTA])
+ msecs_since = nla_get_u32(tb[TCA_ROOT_TIME_DELTA]);
+
nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
cb->nlh->nlmsg_type, sizeof(*t), 0);
if (!nlh)
goto out_module_put;
+ if (msecs_since)
+ jiffy_since = jiffies - msecs_to_jiffies(msecs_since);
+
cb->args[2] = act_flags;
+ cb->args[3] = jiffy_since;
t = nlmsg_data(nlh);
t->tca_family = AF_UNSPEC;
t->tca__pad1 = 0;
--
1.9.1
^ permalink raw reply related
* Re: [PATCH net-next 0/2] flower: add MPLS matching support
From: Simon Horman @ 2017-04-25 11:55 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Jamal Hadi Salim, David Miller, benjamin.lahaise, netdev, bcrl,
Jiri Pirko
In-Reply-To: <20170424190743.4ad24ad1@cakuba.netronome.com>
On Mon, Apr 24, 2017 at 07:07:43PM -0700, Jakub Kicinski wrote:
> On Mon, 24 Apr 2017 22:06:08 -0400, Jamal Hadi Salim wrote:
> > On 17-04-24 10:00 PM, Jamal Hadi Salim wrote:
> > > On 17-04-24 09:48 PM, Jamal Hadi Salim wrote:
> >
> > >
> > > Hrm. maybe I am wrong.
> > > Lets say user sets all of the 8 bits in BOS,
> > > what does setting
> > > key_val->mpls_bos = nla_get_u8 do?
> > >
> > > Same with the 20 bits for the label in the u32
> > > or 3 bit bits in the u8 tc.
> >
> > The label and tc are masked - maybe just the BOS
> > needs something similar?
>
> Indeed, good catch!
I agree something should be done wrt BOS. If the LABEL and TC are to
be left as-is then I think a similar treatment of BOS - that is masking it
- makes sense.
I also agree with statements made earlier in the thread that it is unlikely
that the unused bits of these attributes will be used - as opposed to a
bitmask of flag values which seems ripe for re-use for future flags.
I would like to add to the discussion that I think in future it would
be good to expand the features provided by this patch to support supplying
a mask as part of the match - as flower supports for other fields such
as IP addresses. But I think the current scheme of masking out invalid bits
should also work in conjunction with user-supplied masks.
^ permalink raw reply
* [PATCH net] driver/net: Fix possible memleaks when fail to register_netdevice
From: gfree.wind @ 2017-04-25 12:01 UTC (permalink / raw)
To: jiri, davem, kuznet, jmorris, yoshfuji, kaber, steffen.klassert,
herbert, netdev
Cc: Gao Feng
From: Gao Feng <fgao@ikuai8.com>
These drivers allocate kinds of resources in init routine, and free
some resources in the destructor of net_device. It may cause memleak
when some errors happen after register_netdevice invokes the init
callback. Because only the uninit callback is invoked in the error
handler of register_netdevice, but the destructor not. As a result,
some resources are lost forever.
Now invokes the destructor instead of free_netdev somewhere, and free
the left resources in the newlink func when fail to register_netdevice.
Signed-off-by: Gao Feng <fgao@ikuai8.com>
---
drivers/net/dummy.c | 2 +-
drivers/net/ifb.c | 2 +-
drivers/net/loopback.c | 2 +-
drivers/net/team/team.c | 11 ++++++++++-
drivers/net/veth.c | 4 ++--
net/8021q/vlan_netlink.c | 6 +++++-
net/ipv4/ip_tunnel.c | 9 ++++++++-
net/ipv6/ip6_gre.c | 6 +++++-
net/ipv6/ip6_tunnel.c | 12 ++++++++++--
net/ipv6/ip6_vti.c | 7 ++++++-
net/ipv6/sit.c | 5 ++++-
11 files changed, 53 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 2c80611..55b8a50 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -383,7 +383,7 @@ static int __init dummy_init_one(void)
return 0;
err:
- free_netdev(dev_dummy);
+ dummy_free_netdev(dev_dummy);
return err;
}
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index 312fce7..a298371 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -318,7 +318,7 @@ static int __init ifb_init_one(int index)
return 0;
err:
- free_netdev(dev_ifb);
+ ifb_dev_free(dev_ifb);
return err;
}
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c
index b23b719..c4e1d4c 100644
--- a/drivers/net/loopback.c
+++ b/drivers/net/loopback.c
@@ -208,7 +208,7 @@ static __net_init int loopback_net_init(struct net *net)
out_free_netdev:
- free_netdev(dev);
+ loopback_dev_free(dev);
out:
if (net_eq(net, &init_net))
panic("loopback: Failed to register netdevice: %d\n", err);
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index f8c81f1..0bc80fb 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2109,10 +2109,19 @@ static void team_setup(struct net_device *dev)
static int team_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[])
{
+ int ret;
+
if (tb[IFLA_ADDRESS] == NULL)
eth_hw_addr_random(dev);
- return register_netdevice(dev);
+ ret = register_netdevice(dev);
+ if (ret) {
+ struct team *team = netdev_priv(dev);
+
+ free_percpu(team->pcpu_stats);
+ }
+
+ return ret;
}
static int team_validate(struct nlattr *tb[], struct nlattr *data[])
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 8c39d6d..f60f5ee 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -457,13 +457,13 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
return 0;
err_register_dev:
- /* nothing to do */
+ free_percpu(dev->vstats);
err_configure_peer:
unregister_netdevice(peer);
return err;
err_register_peer:
- free_netdev(peer);
+ veth_dev_free(peer);
return err;
}
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index 1270207..a15826a 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -156,7 +156,11 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev,
if (err < 0)
return err;
- return register_vlan_dev(dev);
+ err = register_vlan_dev(dev);
+ if (err)
+ free_percpu(vlan->vlan_pcpu_stats);
+
+ return err;
}
static inline size_t vlan_qos_map_size(unsigned int n)
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 823abae..4acb296 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -63,6 +63,8 @@
#include <net/ip6_route.h>
#endif
+static void ip_tunnel_dev_free(struct net_device *dev);
+
static unsigned int ip_tunnel_hash(__be32 key, __be32 remote)
{
return hash_32((__force u32)key ^ (__force u32)remote,
@@ -285,7 +287,7 @@ static struct net_device *__ip_tunnel_create(struct net *net,
return dev;
failed_free:
- free_netdev(dev);
+ ip_tunnel_dev_free(dev);
failed:
return ERR_PTR(err);
}
@@ -1099,7 +1101,12 @@ int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
dev->mtu = mtu;
ip_tunnel_add(itn, nt);
+
+ return 0;
out:
+ gro_cells_destroy(&nt->gro_cells);
+ dst_cache_destroy(&nt->dst_cache);
+ free_percpu(dev->tstats);
return err;
}
EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 6fcb7cb..d409ad1 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -77,6 +77,7 @@ struct ip6gre_net {
static void ip6gre_tunnel_setup(struct net_device *dev);
static void ip6gre_tunnel_link(struct ip6gre_net *ign, struct ip6_tnl *t);
static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu);
+static void ip6gre_dev_free(struct net_device *dev);
/* Tunnel hash table */
@@ -351,7 +352,7 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net,
return nt;
failed_free:
- free_netdev(dev);
+ ip6gre_dev_free(dev);
return NULL;
}
@@ -1388,7 +1389,10 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
dev_hold(dev);
ip6gre_tunnel_link(ign, nt);
+ return 0;
out:
+ dst_cache_destroy(&nt->dst_cache);
+ free_percpu(dev->tstats);
return err;
}
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 75fac93..95f512c 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1960,11 +1960,12 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
struct ip6_tnl *nt, *t;
struct ip_tunnel_encap ipencap;
+ int err;
nt = netdev_priv(dev);
if (ip6_tnl_netlink_encap_parms(data, &ipencap)) {
- int err = ip6_tnl_encap_setup(nt, &ipencap);
+ err = ip6_tnl_encap_setup(nt, &ipencap);
if (err < 0)
return err;
@@ -1981,7 +1982,14 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
return -EEXIST;
}
- return ip6_tnl_create2(dev);
+ err = ip6_tnl_create2(dev);
+ if (err) {
+ gro_cells_destroy(&t->gro_cells);
+ dst_cache_destroy(&t->dst_cache);
+ free_percpu(dev->tstats);
+ }
+
+ return err;
}
static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index 3d8a3b6..b201eef 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -940,6 +940,7 @@ static int vti6_newlink(struct net *src_net, struct net_device *dev,
{
struct net *net = dev_net(dev);
struct ip6_tnl *nt;
+ int ret;
nt = netdev_priv(dev);
vti6_netlink_parms(data, &nt->parms);
@@ -949,7 +950,11 @@ static int vti6_newlink(struct net *src_net, struct net_device *dev,
if (vti6_locate(net, &nt->parms, 0))
return -EEXIST;
- return vti6_tnl_create2(dev);
+ ret = vti6_tnl_create2(dev);
+ if (ret)
+ free_percpu(dev->tstats);
+
+ return ret;
}
static void vti6_dellink(struct net_device *dev, struct list_head *head)
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 99853c6..f45dc4a 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1555,8 +1555,11 @@ static int ipip6_newlink(struct net *src_net, struct net_device *dev,
return -EEXIST;
err = ipip6_tunnel_create(dev);
- if (err < 0)
+ if (err < 0) {
+ dst_cache_destroy(&nt->dst_cache);
+ free_percpu(dev->tstats);
return err;
+ }
#ifdef CONFIG_IPV6_SIT_6RD
if (ipip6_netlink_6rd_parms(data, &ip6rd))
--
1.9.1
^ permalink raw reply related
* [PATCH net] net: batman-adv: Fix possible memleaks when fail to register_netdevice
From: gfree.wind @ 2017-04-25 12:03 UTC (permalink / raw)
To: mareklindner, sw, a, davem, b.a.t.m.a.n, netdev; +Cc: Gao Feng
From: Gao Feng <fgao@ikuai8.com>
Because the func batadv_softif_init_late allocate some resources and
it would be invoked in register_netdevice. So we need to invoke the
func batadv_softif_free instead of free_netdev to cleanup when fail
to register_netdevice.
Signed-off-by: Gao Feng <fgao@ikuai8.com>
---
net/batman-adv/soft-interface.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index d042c99..90bf990 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -1011,7 +1011,7 @@ struct net_device *batadv_softif_create(struct net *net, const char *name)
if (ret < 0) {
pr_err("Unable to register the batman interface '%s': %i\n",
name, ret);
- free_netdev(soft_iface);
+ batadv_softif_free(soft_iface);
return NULL;
}
--
1.9.1
^ permalink raw reply related
* Re: [PATCH net-next v8 2/3] net sched actions: dump more than TCA_ACT_MAX_PRIO actions per batch
From: Jiri Pirko @ 2017-04-25 12:13 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: davem, xiyou.wangcong, eric.dumazet, netdev
In-Reply-To: <1493121247-11863-3-git-send-email-jhs@emojatatu.com>
Tue, Apr 25, 2017 at 01:54:06PM CEST, jhs@mojatatu.com wrote:
>From: Jamal Hadi Salim <jhs@mojatatu.com>
>
>When you dump hundreds of thousands of actions, getting only 32 per
>dump batch even when the socket buffer and memory allocations allow
>is inefficient.
>
>With this change, the user will get as many as possibly fitting
>within the given constraints available to the kernel.
>
>The top level action TLV space is extended. An attribute
>TCA_ROOT_FLAGS is used to carry flags; flag TCA_FLAG_LARGE_DUMP_ON
>is set by the user indicating the user is capable of processing
>these large dumps. Older user space which doesnt set this flag
>doesnt get the large (than 32) batches.
>The kernel uses the TCA_ROOT_COUNT attribute to tell the user how many
>actions are put in a single batch. As such user space app knows how long
>to iterate (independent of the type of action being dumped)
>instead of hardcoded maximum of 32.
>
>Some results dumping 1.5M actions, first unpatched tc which the
>kernel doesnt help:
>
>prompt$ time -p tc actions ls action gact | grep index | wc -l
>1500000
>real 1388.43
>user 2.07
>sys 1386.79
>
>Now lets see a patched tc which sets the correct flags when requesting
>a dump:
>
>prompt$ time -p updatedtc actions ls action gact | grep index | wc -l
>1500000
>real 178.13
>user 2.02
>sys 176.96
>
>That is about 8x performance improvement for tc which sets its
>receive buffer to about 32K.
>
>Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
>---
> include/uapi/linux/rtnetlink.h | 22 ++++++++++++++--
> net/sched/act_api.c | 59 +++++++++++++++++++++++++++++++++++-------
> 2 files changed, 69 insertions(+), 12 deletions(-)
>
>diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
>index cce0613..5875467 100644
>--- a/include/uapi/linux/rtnetlink.h
>+++ b/include/uapi/linux/rtnetlink.h
>@@ -674,10 +674,28 @@ struct tcamsg {
> unsigned char tca__pad1;
> unsigned short tca__pad2;
> };
>+
>+enum {
>+ TCA_ROOT_UNSPEC,
>+ TCA_ROOT_TAB,
>+#define TCA_ACT_TAB TCA_ROOT_TAB
>+ TCA_ROOT_FLAGS,
>+ TCA_ROOT_COUNT,
>+ __TCA_ROOT_MAX,
>+#define TCA_ROOT_MAX (__TCA_ROOT_MAX - 1)
>+};
>+
> #define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
> #define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
>-#define TCA_ACT_TAB 1 /* attr type must be >=1 */
>-#define TCAA_MAX 1
>+/* tcamsg flags stored in attribute TCA_ROOT_FLAGS
>+ *
>+ * TCA_FLAG_LARGE_DUMP_ON user->kernel to request for larger than TCA_ACT_MAX_PRIO
>+ * actions in a dump. All dump responses will contain the number of actions
>+ * being dumped stored in for user app's consumption in TCA_ROOT_COUNT
>+ *
>+ */
>+#define TCA_FLAG_LARGE_DUMP_ON (1 << 0)
BIT (I think I mentioned this before)
>+#define VALID_TCA_FLAGS TCA_FLAG_LARGE_DUMP_ON
Again, namespace please. "TCA_ROOT_FLAGS_VALID"
Why is this UAPI?
>
> /* New extended info filters for IFLA_EXT_MASK */
> #define RTEXT_FILTER_VF (1 << 0)
>diff --git a/net/sched/act_api.c b/net/sched/act_api.c
>index 9ce22b7..2756213 100644
>--- a/net/sched/act_api.c
>+++ b/net/sched/act_api.c
>@@ -83,6 +83,7 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
> struct netlink_callback *cb)
> {
> int err = 0, index = -1, i = 0, s_i = 0, n_i = 0;
>+ u32 act_flags = cb->args[2];
> struct nlattr *nest;
>
> spin_lock_bh(&hinfo->lock);
>@@ -111,14 +112,18 @@ static int tcf_dump_walker(struct tcf_hashinfo *hinfo, struct sk_buff *skb,
> }
> nla_nest_end(skb, nest);
> n_i++;
>- if (n_i >= TCA_ACT_MAX_PRIO)
>+ if (!(act_flags & TCA_FLAG_LARGE_DUMP_ON) &&
>+ n_i >= TCA_ACT_MAX_PRIO)
> goto done;
> }
> }
> done:
> spin_unlock_bh(&hinfo->lock);
>- if (n_i)
>+ if (n_i) {
> cb->args[0] += n_i;
>+ if (act_flags & TCA_FLAG_LARGE_DUMP_ON)
>+ cb->args[1] = n_i;
>+ }
> return n_i;
>
> nla_put_failure:
>@@ -993,11 +998,15 @@ static int tcf_action_add(struct net *net, struct nlattr *nla,
> return tcf_add_notify(net, n, &actions, portid);
> }
>
>+static const struct nla_policy tcaa_policy[TCA_ROOT_MAX + 1] = {
>+ [TCA_ROOT_FLAGS] = { .type = NLA_U32 },
>+};
>+
> static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
> struct netlink_ext_ack *extack)
> {
> struct net *net = sock_net(skb->sk);
>- struct nlattr *tca[TCAA_MAX + 1];
>+ struct nlattr *tca[TCA_ROOT_MAX + 1];
> u32 portid = skb ? NETLINK_CB(skb).portid : 0;
> int ret = 0, ovr = 0;
>
>@@ -1005,7 +1014,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
> !netlink_capable(skb, CAP_NET_ADMIN))
> return -EPERM;
>
>- ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCAA_MAX, NULL,
>+ ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ROOT_MAX, NULL,
> extack);
> if (ret < 0)
> return ret;
>@@ -1046,16 +1055,12 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n,
> return ret;
> }
>
>-static struct nlattr *find_dump_kind(const struct nlmsghdr *n)
>+static struct nlattr *find_dump_kind(struct nlattr **nla)
> {
> struct nlattr *tb1, *tb2[TCA_ACT_MAX + 1];
> struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
>- struct nlattr *nla[TCAA_MAX + 1];
> struct nlattr *kind;
>
>- if (nlmsg_parse(n, sizeof(struct tcamsg), nla, TCAA_MAX,
>- NULL, NULL) < 0)
>- return NULL;
> tb1 = nla[TCA_ACT_TAB];
> if (tb1 == NULL)
> return NULL;
>@@ -1073,6 +1078,16 @@ static struct nlattr *find_dump_kind(const struct nlmsghdr *n)
> return kind;
> }
>
>+static inline bool tca_flags_valid(u32 act_flags)
>+{
>+ u32 invalid_flags_mask = ~VALID_TCA_FLAGS;
>+
>+ if (act_flags & invalid_flags_mask)
>+ return false;
I don't see how this resolves anything. VALID_TCA_FLAGS is set in stone
not going to change anytime in future, right? Then the TCA_ROOT_FLAGS
attr will always contain only one flag, right?
Then, I don't see why do we need this dance... u8 flag attr resolves
this in elegant way. I know I sound like a broken record. This is the
last time I'm commenting on this. I give up.
>+
>+ return true;
>+}
>+
> static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
> {
> struct net *net = sock_net(skb->sk);
>@@ -1082,8 +1097,18 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
> struct tc_action_ops *a_o;
> int ret = 0;
> struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
>- struct nlattr *kind = find_dump_kind(cb->nlh);
>+ struct nlattr *count_attr = NULL;
>+ struct nlattr *tb[TCA_ROOT_MAX + 1];
>+ struct nlattr *kind = NULL;
>+ u32 act_flags = 0;
>+ u32 act_count = 0;
>+
>+ ret = nlmsg_parse(cb->nlh, sizeof(struct tcamsg), tb, TCA_ROOT_MAX,
>+ tcaa_policy, NULL);
>+ if (ret < 0)
>+ return ret;
>
>+ kind = find_dump_kind(tb);
> if (kind == NULL) {
> pr_info("tc_dump_action: action bad kind\n");
> return 0;
>@@ -1093,14 +1118,25 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
> if (a_o == NULL)
> return 0;
>
>+ if (tb[TCA_ROOT_FLAGS])
>+ act_flags = nla_get_u32(tb[TCA_ROOT_FLAGS]);
>+
>+ if (act_flags && !tca_flags_valid(act_flags))
>+ return -EINVAL;
>+
> nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
> cb->nlh->nlmsg_type, sizeof(*t), 0);
> if (!nlh)
> goto out_module_put;
>+
>+ cb->args[2] = act_flags;
> t = nlmsg_data(nlh);
> t->tca_family = AF_UNSPEC;
> t->tca__pad1 = 0;
> t->tca__pad2 = 0;
>+ count_attr = nla_reserve(skb, TCA_ROOT_COUNT, sizeof(u32));
>+ if (!count_attr)
>+ goto out_module_put;
>
> nest = nla_nest_start(skb, TCA_ACT_TAB);
> if (nest == NULL)
>@@ -1113,6 +1149,9 @@ static int tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
> if (ret > 0) {
> nla_nest_end(skb, nest);
> ret = skb->len;
>+ act_count = cb->args[1];
>+ memcpy(nla_data(count_attr), &act_count, sizeof(u32));
>+ cb->args[1] = 0;
> } else
> nlmsg_trim(skb, b);
>
>--
>1.9.1
>
^ permalink raw reply
* Re: [PATCH] stmmac: Add support for SIMATIC IOT2000 platform
From: Jan Kiszka @ 2017-04-25 12:15 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Giuseppe Cavallaro, Alexandre Torgue, netdev,
Linux Kernel Mailing List, Sascha Weisenberger
In-Reply-To: <CAHp75Vd=TkJXnDYqctKCzRGvMX_Zt0i5eH8GcBz44e-T93aJ0A@mail.gmail.com>
On 2017-04-25 13:42, Andy Shevchenko wrote:
> On Tue, Apr 25, 2017 at 1:09 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>> On 2017-04-25 12:07, Jan Kiszka wrote:
>>> On 2017-04-25 11:46, Andy Shevchenko wrote:
>>>> On Tue, Apr 25, 2017 at 12:00 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>>>> On 2017-04-25 09:30, Andy Shevchenko wrote:
>>>>>> On Tue, Apr 25, 2017 at 8:44 AM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>>>>>>> On 2017-04-24 23:27, Andy Shevchenko wrote:
>>>>>>>> On Mon, Apr 24, 2017 at 10:27 PM, Jan Kiszka <jan.kiszka@siemens.com> wrote:
>
>>>> {
>>>> .name = "SIMATIC IOT2000",
>>>> .func = 6,
>>>> .phy_addr = 1,
>>>> },
>>>> {
>>>> .name = "SIMATIC IOT2000",
>>>> .func = 7,
>>>> .phy_addr = 1,
>>>> },
>>>>
>>>> That's all what you need.
>>>
>>> Nope. Again: the asset tag is the way to tell both apart AND to ensure
>>> that we do not match on future devices.
>
>> To be more verbose: your version (which is our old one) would even
>> enable the second, not connected port on the IOT2020. Incorrectly.
>
> So, name has 2000 for 2020 device? It's clear bug in DMI table you have. :-(
>
> What else do you have in DMI which can be used to distinguish those devices?
Andy, there are devices out there in the field, if we as engineers like
it or not, that are all called "IOT2000" although they are sightly
different inside. This patch accounts for that. And it does that even
without adding "platform_data" hacks like in other patches of mine. ;)
Jan
--
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux
^ permalink raw reply
* [PATCH 1/3] can: usb: Add support of PCAN-Chip USB stamp module
From: Marc Kleine-Budde @ 2017-04-25 12:16 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, Stephane Grosjean, Marc Kleine-Budde
In-Reply-To: <20170425121645.9946-1-mkl@pengutronix.de>
From: Stephane Grosjean <s.grosjean@peak-system.com>
This patch adds the support of the PCAN-Chip USB, a stamp module for
customer hardware designs, which communicates via USB 2.0 with the
hardware. The integrated CAN controller supports the protocols CAN 2.0 A/B
as well as CAN FD. The physical CAN connection is determined by external
wiring. The Stamp module with its single-sided mounting and plated
half-holes is suitable for automatic assembly.
Note that the chip is equipped with the same logic than the PCAN-USB FD.
Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/usb/Kconfig | 1 +
drivers/net/can/usb/peak_usb/pcan_usb_core.c | 2 +
drivers/net/can/usb/peak_usb/pcan_usb_core.h | 2 +
drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 72 ++++++++++++++++++++++++++++
4 files changed, 77 insertions(+)
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig
index 8483a40e7e9e..3f8adc366af4 100644
--- a/drivers/net/can/usb/Kconfig
+++ b/drivers/net/can/usb/Kconfig
@@ -72,6 +72,7 @@ config CAN_PEAK_USB
PCAN-USB Pro dual CAN 2.0b channels USB adapter
PCAN-USB FD single CAN-FD channel USB adapter
PCAN-USB Pro FD dual CAN-FD channels USB adapter
+ PCAN-Chip USB CAN-FD to USB stamp module
(see also http://www.peak-system.com).
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 0b0302af3bd2..57913dbbae0a 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -39,6 +39,7 @@ static struct usb_device_id peak_usb_table[] = {
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPRO_PRODUCT_ID)},
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBFD_PRODUCT_ID)},
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPROFD_PRODUCT_ID)},
+ {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBCHIP_PRODUCT_ID)},
{USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBX6_PRODUCT_ID)},
{} /* Terminating entry */
};
@@ -51,6 +52,7 @@ static const struct peak_usb_adapter *const peak_usb_adapters_list[] = {
&pcan_usb_pro,
&pcan_usb_fd,
&pcan_usb_pro_fd,
+ &pcan_usb_chip,
&pcan_usb_x6,
};
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
index 3cbfb069893d..c01316cac354 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.h
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h
@@ -27,6 +27,7 @@
#define PCAN_USBPRO_PRODUCT_ID 0x000d
#define PCAN_USBPROFD_PRODUCT_ID 0x0011
#define PCAN_USBFD_PRODUCT_ID 0x0012
+#define PCAN_USBCHIP_PRODUCT_ID 0x0013
#define PCAN_USBX6_PRODUCT_ID 0x0014
#define PCAN_USB_DRIVER_NAME "peak_usb"
@@ -90,6 +91,7 @@ struct peak_usb_adapter {
extern const struct peak_usb_adapter pcan_usb;
extern const struct peak_usb_adapter pcan_usb_pro;
extern const struct peak_usb_adapter pcan_usb_fd;
+extern const struct peak_usb_adapter pcan_usb_chip;
extern const struct peak_usb_adapter pcan_usb_pro_fd;
extern const struct peak_usb_adapter pcan_usb_x6;
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 304732550f0a..528d3bb4917f 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -1061,6 +1061,78 @@ const struct peak_usb_adapter pcan_usb_fd = {
.do_get_berr_counter = pcan_usb_fd_get_berr_counter,
};
+/* describes the PCAN-CHIP USB */
+static const struct can_bittiming_const pcan_usb_chip_const = {
+ .name = "pcan_chip_usb",
+ .tseg1_min = 1,
+ .tseg1_max = (1 << PUCAN_TSLOW_TSGEG1_BITS),
+ .tseg2_min = 1,
+ .tseg2_max = (1 << PUCAN_TSLOW_TSGEG2_BITS),
+ .sjw_max = (1 << PUCAN_TSLOW_SJW_BITS),
+ .brp_min = 1,
+ .brp_max = (1 << PUCAN_TSLOW_BRP_BITS),
+ .brp_inc = 1,
+};
+
+static const struct can_bittiming_const pcan_usb_chip_data_const = {
+ .name = "pcan_chip_usb",
+ .tseg1_min = 1,
+ .tseg1_max = (1 << PUCAN_TFAST_TSGEG1_BITS),
+ .tseg2_min = 1,
+ .tseg2_max = (1 << PUCAN_TFAST_TSGEG2_BITS),
+ .sjw_max = (1 << PUCAN_TFAST_SJW_BITS),
+ .brp_min = 1,
+ .brp_max = (1 << PUCAN_TFAST_BRP_BITS),
+ .brp_inc = 1,
+};
+
+const struct peak_usb_adapter pcan_usb_chip = {
+ .name = "PCAN-Chip USB",
+ .device_id = PCAN_USBCHIP_PRODUCT_ID,
+ .ctrl_count = PCAN_USBFD_CHANNEL_COUNT,
+ .ctrlmode_supported = CAN_CTRLMODE_FD |
+ CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_LISTENONLY,
+ .clock = {
+ .freq = PCAN_UFD_CRYSTAL_HZ,
+ },
+ .bittiming_const = &pcan_usb_chip_const,
+ .data_bittiming_const = &pcan_usb_chip_data_const,
+
+ /* size of device private data */
+ .sizeof_dev_private = sizeof(struct pcan_usb_fd_device),
+
+ /* timestamps usage */
+ .ts_used_bits = 32,
+ .ts_period = 1000000, /* calibration period in ts. */
+ .us_per_ts_scale = 1, /* us = (ts * scale) >> shift */
+ .us_per_ts_shift = 0,
+
+ /* give here messages in/out endpoints */
+ .ep_msg_in = PCAN_USBPRO_EP_MSGIN,
+ .ep_msg_out = {PCAN_USBPRO_EP_MSGOUT_0},
+
+ /* size of rx/tx usb buffers */
+ .rx_buffer_size = PCAN_UFD_RX_BUFFER_SIZE,
+ .tx_buffer_size = PCAN_UFD_TX_BUFFER_SIZE,
+
+ /* device callbacks */
+ .intf_probe = pcan_usb_pro_probe, /* same as PCAN-USB Pro */
+ .dev_init = pcan_usb_fd_init,
+
+ .dev_exit = pcan_usb_fd_exit,
+ .dev_free = pcan_usb_fd_free,
+ .dev_set_bus = pcan_usb_fd_set_bus,
+ .dev_set_bittiming = pcan_usb_fd_set_bittiming_slow,
+ .dev_set_data_bittiming = pcan_usb_fd_set_bittiming_fast,
+ .dev_decode_buf = pcan_usb_fd_decode_buf,
+ .dev_start = pcan_usb_fd_start,
+ .dev_stop = pcan_usb_fd_stop,
+ .dev_restart_async = pcan_usb_fd_restart_async,
+ .dev_encode_msg = pcan_usb_fd_encode_msg,
+
+ .do_get_berr_counter = pcan_usb_fd_get_berr_counter,
+};
+
/* describes the PCAN-USB Pro FD adapter */
static const struct can_bittiming_const pcan_usb_pro_fd_const = {
.name = "pcan_usb_pro_fd",
--
2.11.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox