* Re: [PATCH net-next] net: ethernet: ti: cpsw: replace unnecessarily macroses on functions
From: Joe Perches @ 2018-07-27 20:04 UTC (permalink / raw)
To: Ivan Khoronzhuk
Cc: grygorii.strashko, davem, linux-omap, netdev, linux-kernel
In-Reply-To: <20180727193641.GA2619@khorivan>
On Fri, 2018-07-27 at 22:36 +0300, Ivan Khoronzhuk wrote:
> On Fri, Jul 27, 2018 at 12:21:07PM -0700, Joe Perches wrote:
> > On Fri, 2018-07-27 at 22:13 +0300, Ivan Khoronzhuk wrote:
> > > Replace ugly macroses on functions.
> >
> > Careful, see below.
> >
> > > diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
> >
> > []
> > > @@ -565,40 +565,40 @@ static const struct cpsw_stats cpsw_gstrings_ch_stats[] = {
> > > (func)(slave++, ##arg); \
> > > } while (0)
> > >
> > > -#define cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb) \
> > > - do { \
> > > - if (!cpsw->data.dual_emac) \
> > > - break; \
> > > - if (CPDMA_RX_SOURCE_PORT(status) == 1) { \
> > > - ndev = cpsw->slaves[0].ndev; \
> > > - skb->dev = ndev; \
> > > - } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \
> > > - ndev = cpsw->slaves[1].ndev; \
> > > - skb->dev = ndev; \
> > > - } \
> > > - } while (0)
> > > -#define cpsw_add_mcast(cpsw, priv, addr) \
> > > - do { \
> > > - if (cpsw->data.dual_emac) { \
> > > - struct cpsw_slave *slave = cpsw->slaves + \
> > > - priv->emac_port; \
> > > - int slave_port = cpsw_get_slave_port( \
> > > - slave->slave_num); \
> > > - cpsw_ale_add_mcast(cpsw->ale, addr, \
> > > - 1 << slave_port | ALE_PORT_HOST, \
> > > - ALE_VLAN, slave->port_vlan, 0); \
> > > - } else { \
> > > - cpsw_ale_add_mcast(cpsw->ale, addr, \
> > > - ALE_ALL_PORTS, \
> > > - 0, 0, 0); \
> > > - } \
> > > - } while (0)
> > > -
> > > static inline int cpsw_get_slave_port(u32 slave_num)
> > > {
> > > return slave_num + 1;
> > > }
> > >
> > > +static inline void cpsw_src_port_detect(struct cpsw_common *cpsw, int status,
> > > + struct sk_buff *skb)
> > > +{
> > > + if (!cpsw->data.dual_emac)
> > > + return;
> > > +
> > > + if (CPDMA_RX_SOURCE_PORT(status) == 1)
> > > + skb->dev = cpsw->slaves[0].ndev;
> > > + else if (CPDMA_RX_SOURCE_PORT(status) == 2)
> > > + skb->dev = cpsw->slaves[1].ndev;
> > > +}
> >
> > perhaps better as a switch/case
>
> not better, it's shorter.
True for the source code but it compiles to more object code.
$ cat foo.c
struct cpsw_common {
struct {
int dual_emac;
} data;
struct {
int ndev;
} slaves[2];
};
struct sk_buff {
int dev;
};
#define CPDMA_RX_SOURCE_PORT(__status__) ((__status__ >> 16) & 0x7)
#if defined SWITCH
void foo(struct cpsw_common *cpsw, int status, struct sk_buff *skb)
{
if (!cpsw->data.dual_emac)
return;
switch (CPDMA_RX_SOURCE_PORT(status)) {
case 1:
skb->dev = cpsw->slaves[0].ndev;
break;
case 2:
skb->dev = cpsw->slaves[1].ndev;
break;
}
}
#else
void foo(struct cpsw_common *cpsw, int status, struct sk_buff *skb)
{
if (!cpsw->data.dual_emac)
return;
if (CPDMA_RX_SOURCE_PORT(status) == 1)
skb->dev = cpsw->slaves[0].ndev;
else if (CPDMA_RX_SOURCE_PORT(status) == 2)
skb->dev = cpsw->slaves[1].ndev;
}
#endif
$ gcc -c -O2 -DSWITCH foo.c
$ size foo.o
text data bss dec hex filename
94 0 0 94 5e foo.o
$ objdump -d foo.o
foo.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <foo>:
0: 8b 07 mov (%rdi),%eax
2: 85 c0 test %eax,%eax
4: 74 15 je 1b <foo+0x1b>
6: c1 fe 10 sar $0x10,%esi
9: 83 e6 07 and $0x7,%esi
c: 83 fe 01 cmp $0x1,%esi
f: 74 17 je 28 <foo+0x28>
11: 83 fe 02 cmp $0x2,%esi
14: 75 0a jne 20 <foo+0x20>
16: 8b 47 08 mov 0x8(%rdi),%eax
19: 89 02 mov %eax,(%rdx)
1b: f3 c3 repz retq
1d: 0f 1f 00 nopl (%rax)
20: f3 c3 repz retq
22: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
28: 8b 47 04 mov 0x4(%rdi),%eax
2b: 89 02 mov %eax,(%rdx)
2d: c3 retq
$ gcc -c -O2 foo.c
$ size foo.o
text data bss dec hex filename
102 0 0 102 66 foo.o
$ objdump -d foo.o
foo.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <foo>:
0: 8b 07 mov (%rdi),%eax
2: 85 c0 test %eax,%eax
4: 74 10 je 16 <foo+0x16>
6: c1 fe 10 sar $0x10,%esi
9: 83 e6 07 and $0x7,%esi
c: 83 fe 01 cmp $0x1,%esi
f: 74 0f je 20 <foo+0x20>
11: 83 fe 02 cmp $0x2,%esi
14: 74 1a je 30 <foo+0x30>
16: f3 c3 repz retq
18: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
1f: 00
20: 8b 47 04 mov 0x4(%rdi),%eax
23: 89 02 mov %eax,(%rdx)
25: c3 retq
26: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
2d: 00 00 00
30: 8b 47 08 mov 0x8(%rdi),%eax
33: 89 02 mov %eax,(%rdx)
35: c3 retq
^ permalink raw reply
* Re: [PATCH] perf build: Build error in libbpf missing initialization
From: Jakub Kicinski @ 2018-07-27 19:56 UTC (permalink / raw)
To: Daniel Borkmann
Cc: Thomas Richter, ast, netdev, linux-kernel, heiko.carstens,
brueckner, schwidefsky
In-Reply-To: <c8409ab8-69df-17f4-9da3-610c60143d9a@iogearbox.net>
On Fri, 27 Jul 2018 21:31:01 +0200, Daniel Borkmann wrote:
> On 07/27/2018 07:59 PM, Jakub Kicinski wrote:
> > On Fri, 27 Jul 2018 10:21:26 +0200, Thomas Richter wrote:
> >> In linux-next tree compiling the perf tool with additional make flags
> >> "EXTRA_CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -O2"
> >> causes a compiler error. It is the warning
> >> 'variable may be used uninitialized'
> >> which is treated as error:
> >>
> >> I compile it using a FEDORA 28 installation, my gcc compiler version:
> >> gcc (GCC) 8.0.1 20180324 (Red Hat 8.0.1-0.20)
> >>
> >> The file that causes the error is tools/lib/bpf/libbpf.c
> >>
> >> Here is the error message:
> >>
> >> [root@p23lp27] # make V=1 EXTRA_CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -O2"
> >> [...]
> >> Makefile.config:849: No openjdk development package found, please
> >> install JDK package, e.g. openjdk-8-jdk, java-1.8.0-openjdk-devel
> >> Warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h'
> >> differs from latest version at 'include/uapi/linux/if_link.h'
> >> CC libbpf.o
> >> libbpf.c: In function ‘bpf_perf_event_read_simple’:
> >> libbpf.c:2342:6: error: ‘ret’ may be used uninitialized in this
> >> function [-Werror=maybe-uninitialized]
> >> int ret;
> >> ^
> >> cc1: all warnings being treated as errors
> >> mv: cannot stat './.libbpf.o.tmp': No such file or directory
> >> /home6/tmricht/linux-next/tools/build/Makefile.build:96: recipe for target 'libbpf.o' failed
> >>
> >> Fix this warning and add an addition check at the beginning
> >> of the while loop.
> >>
> >> Cc: Alexei Starovoitov <ast@kernel.org>
> >> Cc: Daniel Borkmann <daniel@iogearbox.net>
> >>
> >> Suggested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> >> Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
> >
> > Ah, you already sent this, LGTM, thanks Thomas!
> >
> >> tools/lib/bpf/libbpf.c | 2 ++
> >> 1 file changed, 2 insertions(+)
> >>
> >> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> >> index 73465caa33ba..66965ca96113 100644
> >> --- a/tools/lib/bpf/libbpf.c
> >> +++ b/tools/lib/bpf/libbpf.c
> >> @@ -2349,6 +2349,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
> >>
> >> begin = base + data_tail % size;
> >> end = base + data_head % size;
> >> + if (begin == end)
> >> + return LIBBPF_PERF_EVENT_ERROR;
> >>
> >> while (begin != end) {
> >> struct perf_event_header *ehdr;
>
> One question though, any objections to go for something like the below instead?
> I doubt we ever hit this in a 'normal' situation, and given we already test for
> the begin and end anyway, we could just avoid the extra test altogether. I could
> change it to the below if you're good as well (no need to resend anything):
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index d881d37..1aafdbe 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -2273,8 +2273,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
> volatile struct perf_event_mmap_page *header = mem;
> __u64 data_tail = header->data_tail;
> __u64 data_head = header->data_head;
> + int ret = LIBBPF_PERF_EVENT_ERROR;
> void *base, *begin, *end;
> - int ret;
>
> asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */
> if (data_head == data_tail)
No real objection, although as a matter of personal taste I'm not a big
fan of initializing err/ret variables unless the code is explicitly
structured to make use of it. Here it looks slightly more like
silencing a compiler warning, hence my preference to address the actual
cause of the warning rather than catch all. I guess one could argue
the other way, i.e. if the loop never run (and therefore ret was not
overwritten) there must be *some* error. I like verbose/explicit code I
guess..
Up to you :)
^ permalink raw reply
* Re: [PATCH net-next] net: ethernet: ti: cpsw: replace unnecessarily macroses on functions
From: Ivan Khoronzhuk @ 2018-07-27 19:52 UTC (permalink / raw)
To: Joe Perches, grygorii.strashko, davem, linux-omap, netdev,
linux-kernel
In-Reply-To: <20180727193641.GA2619@khorivan>
On Fri, Jul 27, 2018 at 10:36:43PM +0300, Ivan Khoronzhuk wrote:
>On Fri, Jul 27, 2018 at 12:21:07PM -0700, Joe Perches wrote:
>>On Fri, 2018-07-27 at 22:13 +0300, Ivan Khoronzhuk wrote:
>>>Replace ugly macroses on functions.
>>
>>Careful, see below.
>>
>>>diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
>>[]
>>>@@ -565,40 +565,40 @@ static const struct cpsw_stats cpsw_gstrings_ch_stats[] = {
>>> (func)(slave++, ##arg); \
>>> } while (0)
>>>
>>>-#define cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb) \
>>>- do { \
>>>- if (!cpsw->data.dual_emac) \
>>>- break; \
>>>- if (CPDMA_RX_SOURCE_PORT(status) == 1) { \
>>>- ndev = cpsw->slaves[0].ndev; \
>>>- skb->dev = ndev; \
>>>- } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \
>>>- ndev = cpsw->slaves[1].ndev; \
>>>- skb->dev = ndev; \
>>>- } \
>>>- } while (0)
>>>-#define cpsw_add_mcast(cpsw, priv, addr) \
>>>- do { \
>>>- if (cpsw->data.dual_emac) { \
>>>- struct cpsw_slave *slave = cpsw->slaves + \
>>>- priv->emac_port; \
>>>- int slave_port = cpsw_get_slave_port( \
>>>- slave->slave_num); \
>>>- cpsw_ale_add_mcast(cpsw->ale, addr, \
>>>- 1 << slave_port | ALE_PORT_HOST, \
>>>- ALE_VLAN, slave->port_vlan, 0); \
>>>- } else { \
>>>- cpsw_ale_add_mcast(cpsw->ale, addr, \
>>>- ALE_ALL_PORTS, \
>>>- 0, 0, 0); \
>>>- } \
>>>- } while (0)
>>>-
>>> static inline int cpsw_get_slave_port(u32 slave_num)
>>> {
>>> return slave_num + 1;
>>> }
>>>
>>>+static inline void cpsw_src_port_detect(struct cpsw_common *cpsw, int status,
>>>+ struct sk_buff *skb)
>>>+{
>>>+ if (!cpsw->data.dual_emac)
>>>+ return;
>>>+
>>>+ if (CPDMA_RX_SOURCE_PORT(status) == 1)
>>>+ skb->dev = cpsw->slaves[0].ndev;
>>>+ else if (CPDMA_RX_SOURCE_PORT(status) == 2)
>>>+ skb->dev = cpsw->slaves[1].ndev;
>>>+}
>>
>>perhaps better as a switch/case
>not better, it's shorter.
>
>>
>>>+
>>>+static void cpsw_add_mcast(struct cpsw_priv *priv, u8 *addr)
>>>+{
>>>+ struct cpsw_common *cpsw = priv->cpsw;
>>>+
>>>+ if (cpsw->data.dual_emac) {
>>>+ struct cpsw_slave *slave = cpsw->slaves + priv->emac_port;
>>>+ int slave_port = cpsw_get_slave_port(slave->slave_num);
>>>+
>>>+ cpsw_ale_add_mcast(cpsw->ale, addr,
>>>+ 1 << slave_port | ALE_PORT_HOST,
>>>+ ALE_VLAN, slave->port_vlan, 0);
>>>+ return;
>>>+ }
>>>+
>>>+ cpsw_ale_add_mcast(cpsw->ale, addr, ALE_ALL_PORTS, 0, 0, 0);
>>>+}
>>>+
>>> static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
>>> {
>>> struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
>>>@@ -706,7 +706,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
>>>
>>> /* program multicast address list into ALE register */
>>> netdev_for_each_mc_addr(ha, ndev) {
>>>- cpsw_add_mcast(cpsw, priv, (u8 *)ha->addr);
>>>+ cpsw_add_mcast(priv, (u8 *)ha->addr);
>>> }
>>> }
>>> }
>>>@@ -801,7 +801,8 @@ static void cpsw_rx_handler(void *token, int len, int status)
>>> int ret = 0;
>>> struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
>>>
>>>- cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb);
>>>+ cpsw_src_port_detect(cpsw, status, skb);
>>>+ ndev = skb->dev;
>>
>>This is not the same code as the new function
>>is not guaranteed to succeed or set skb->dev.
>Guaranteed by above skb->dev is initialized already.
>The function reflects previous macro.
>
>Even more, seems that here is duplication of ndev=skb->dev;
>It should be removed at init ), even if it 100% is optimized by complier.
>So guaranteed a little more then needed ), will send v2 with removed
>ndev = skb->dev at init if no objection.
But no, not duplicates.
It's used to get cpsw. So everyting is fine.
Patch should go as is.
>
>>
>>> if (unlikely(status < 0) || unlikely(!netif_running(ndev))) {
>>> /* In dual emac mode check for all interfaces */
>
>--
>Regards,
>Ivan Khoronzhuk
--
Regards,
Ivan Khoronzhuk
^ permalink raw reply
* Re: [PATCH net-next] net: ethernet: ti: cpsw: replace unnecessarily macroses on functions
From: Ivan Khoronzhuk @ 2018-07-27 19:36 UTC (permalink / raw)
To: Joe Perches; +Cc: grygorii.strashko, davem, linux-omap, netdev, linux-kernel
In-Reply-To: <98a6d1cd4d313512d66ced3fc25f438449b3c310.camel@perches.com>
On Fri, Jul 27, 2018 at 12:21:07PM -0700, Joe Perches wrote:
>On Fri, 2018-07-27 at 22:13 +0300, Ivan Khoronzhuk wrote:
>> Replace ugly macroses on functions.
>
>Careful, see below.
>
>> diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
>[]
>> @@ -565,40 +565,40 @@ static const struct cpsw_stats cpsw_gstrings_ch_stats[] = {
>> (func)(slave++, ##arg); \
>> } while (0)
>>
>> -#define cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb) \
>> - do { \
>> - if (!cpsw->data.dual_emac) \
>> - break; \
>> - if (CPDMA_RX_SOURCE_PORT(status) == 1) { \
>> - ndev = cpsw->slaves[0].ndev; \
>> - skb->dev = ndev; \
>> - } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \
>> - ndev = cpsw->slaves[1].ndev; \
>> - skb->dev = ndev; \
>> - } \
>> - } while (0)
>> -#define cpsw_add_mcast(cpsw, priv, addr) \
>> - do { \
>> - if (cpsw->data.dual_emac) { \
>> - struct cpsw_slave *slave = cpsw->slaves + \
>> - priv->emac_port; \
>> - int slave_port = cpsw_get_slave_port( \
>> - slave->slave_num); \
>> - cpsw_ale_add_mcast(cpsw->ale, addr, \
>> - 1 << slave_port | ALE_PORT_HOST, \
>> - ALE_VLAN, slave->port_vlan, 0); \
>> - } else { \
>> - cpsw_ale_add_mcast(cpsw->ale, addr, \
>> - ALE_ALL_PORTS, \
>> - 0, 0, 0); \
>> - } \
>> - } while (0)
>> -
>> static inline int cpsw_get_slave_port(u32 slave_num)
>> {
>> return slave_num + 1;
>> }
>>
>> +static inline void cpsw_src_port_detect(struct cpsw_common *cpsw, int status,
>> + struct sk_buff *skb)
>> +{
>> + if (!cpsw->data.dual_emac)
>> + return;
>> +
>> + if (CPDMA_RX_SOURCE_PORT(status) == 1)
>> + skb->dev = cpsw->slaves[0].ndev;
>> + else if (CPDMA_RX_SOURCE_PORT(status) == 2)
>> + skb->dev = cpsw->slaves[1].ndev;
>> +}
>
>perhaps better as a switch/case
not better, it's shorter.
>
>> +
>> +static void cpsw_add_mcast(struct cpsw_priv *priv, u8 *addr)
>> +{
>> + struct cpsw_common *cpsw = priv->cpsw;
>> +
>> + if (cpsw->data.dual_emac) {
>> + struct cpsw_slave *slave = cpsw->slaves + priv->emac_port;
>> + int slave_port = cpsw_get_slave_port(slave->slave_num);
>> +
>> + cpsw_ale_add_mcast(cpsw->ale, addr,
>> + 1 << slave_port | ALE_PORT_HOST,
>> + ALE_VLAN, slave->port_vlan, 0);
>> + return;
>> + }
>> +
>> + cpsw_ale_add_mcast(cpsw->ale, addr, ALE_ALL_PORTS, 0, 0, 0);
>> +}
>> +
>> static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
>> {
>> struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
>> @@ -706,7 +706,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
>>
>> /* program multicast address list into ALE register */
>> netdev_for_each_mc_addr(ha, ndev) {
>> - cpsw_add_mcast(cpsw, priv, (u8 *)ha->addr);
>> + cpsw_add_mcast(priv, (u8 *)ha->addr);
>> }
>> }
>> }
>> @@ -801,7 +801,8 @@ static void cpsw_rx_handler(void *token, int len, int status)
>> int ret = 0;
>> struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
>>
>> - cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb);
>> + cpsw_src_port_detect(cpsw, status, skb);
>> + ndev = skb->dev;
>
>This is not the same code as the new function
>is not guaranteed to succeed or set skb->dev.
Guaranteed by above skb->dev is initialized already.
The function reflects previous macro.
Even more, seems that here is duplication of ndev=skb->dev;
It should be removed at init ), even if it 100% is optimized by complier.
So guaranteed a little more then needed ), will send v2 with removed
ndev = skb->dev at init if no objection.
>
>> if (unlikely(status < 0) || unlikely(!netif_running(ndev))) {
>> /* In dual emac mode check for all interfaces */
--
Regards,
Ivan Khoronzhuk
^ permalink raw reply
* Re: [PATCH] perf build: Build error in libbpf missing initialization
From: Daniel Borkmann @ 2018-07-27 19:31 UTC (permalink / raw)
To: Jakub Kicinski, Thomas Richter
Cc: ast, netdev, linux-kernel, heiko.carstens, brueckner, schwidefsky
In-Reply-To: <20180727105923.2d5da6aa@cakuba.netronome.com>
On 07/27/2018 07:59 PM, Jakub Kicinski wrote:
> On Fri, 27 Jul 2018 10:21:26 +0200, Thomas Richter wrote:
>> In linux-next tree compiling the perf tool with additional make flags
>> "EXTRA_CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -O2"
>> causes a compiler error. It is the warning
>> 'variable may be used uninitialized'
>> which is treated as error:
>>
>> I compile it using a FEDORA 28 installation, my gcc compiler version:
>> gcc (GCC) 8.0.1 20180324 (Red Hat 8.0.1-0.20)
>>
>> The file that causes the error is tools/lib/bpf/libbpf.c
>>
>> Here is the error message:
>>
>> [root@p23lp27] # make V=1 EXTRA_CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -O2"
>> [...]
>> Makefile.config:849: No openjdk development package found, please
>> install JDK package, e.g. openjdk-8-jdk, java-1.8.0-openjdk-devel
>> Warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h'
>> differs from latest version at 'include/uapi/linux/if_link.h'
>> CC libbpf.o
>> libbpf.c: In function ‘bpf_perf_event_read_simple’:
>> libbpf.c:2342:6: error: ‘ret’ may be used uninitialized in this
>> function [-Werror=maybe-uninitialized]
>> int ret;
>> ^
>> cc1: all warnings being treated as errors
>> mv: cannot stat './.libbpf.o.tmp': No such file or directory
>> /home6/tmricht/linux-next/tools/build/Makefile.build:96: recipe for target 'libbpf.o' failed
>>
>> Fix this warning and add an addition check at the beginning
>> of the while loop.
>>
>> Cc: Alexei Starovoitov <ast@kernel.org>
>> Cc: Daniel Borkmann <daniel@iogearbox.net>
>>
>> Suggested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
>> Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
>
> Ah, you already sent this, LGTM, thanks Thomas!
>
>> tools/lib/bpf/libbpf.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
>> index 73465caa33ba..66965ca96113 100644
>> --- a/tools/lib/bpf/libbpf.c
>> +++ b/tools/lib/bpf/libbpf.c
>> @@ -2349,6 +2349,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
>>
>> begin = base + data_tail % size;
>> end = base + data_head % size;
>> + if (begin == end)
>> + return LIBBPF_PERF_EVENT_ERROR;
>>
>> while (begin != end) {
>> struct perf_event_header *ehdr;
One question though, any objections to go for something like the below instead?
I doubt we ever hit this in a 'normal' situation, and given we already test for
the begin and end anyway, we could just avoid the extra test altogether. I could
change it to the below if you're good as well (no need to resend anything):
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index d881d37..1aafdbe 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -2273,8 +2273,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
volatile struct perf_event_mmap_page *header = mem;
__u64 data_tail = header->data_tail;
__u64 data_head = header->data_head;
+ int ret = LIBBPF_PERF_EVENT_ERROR;
void *base, *begin, *end;
- int ret;
asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */
if (data_head == data_tail)
Thanks,
Daniel
^ permalink raw reply related
* Re: [PATCH v2] perf build: Build error in libbpf with EXTRA_CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -O2"
From: Jakub Kicinski @ 2018-07-27 17:57 UTC (permalink / raw)
To: Thomas-Mich Richter
Cc: Daniel Borkmann, ast, netdev, linux-kernel, heiko.carstens,
brueckner, schwidefsky, wangnan0
In-Reply-To: <325e3d58-89fb-1b50-8865-22c6f372671a@linux.ibm.com>
On Fri, 27 Jul 2018 09:22:03 +0200, Thomas-Mich Richter wrote:
> On 07/27/2018 04:16 AM, Daniel Borkmann wrote:
> > On 07/26/2018 03:48 AM, Jakub Kicinski wrote:
> >> On Wed, 25 Jul 2018 09:21:26 +0200, Thomas Richter wrote:
> >>> commit a5b8bd47dcc57 ("bpf tools: Collect eBPF programs from their own sections")
> >>
> >> Hmm.. are you sure it's not 531b014e7a2f ("tools: bpf: make use of
> >> reallocarray") that caused the issue? That commit made us switch from
> >> XSI-compliant to GNU-specific strerror_r() implementation..
> >>
> >> /me checks
> >>
> >> Yes it looks like 531b014e7a2f~ builds just fine.
> >>
> >> Daniel, did you try to apply v1 to the bpf tree? Perhaps there is a
> >> confusion about the trees here, if this is caused by my recent change
> >> it's a bpf-next material. strerror() works, but strerror_r() seems
> >> nicer, so perhaps we could keep it if the patch worked in bpf-next?
> >
> > Yeah indeed, the issue is only in bpf-next. When I compile libbpf from
> > bpf tree with the below flags then it's all good>
> > Agree that we should rather use strerror_r() given this is a library.
>
> Are you sure to stick with strerror_r? I ask because it is the only
> occurence of strerror_r in this file. All other error messages use strerror
> as in:
> pr_warning("failed to create map (name: '%s'): %s\n",
> map->name,
> strerror(errno));
>
>
> $ fgrep strerror tools/lib/bpf/libbpf.c
> strerror(errno));
> issue I try to solve---> strerror_r(-err, errmsg, sizeof(errmsg));
> map->name, strerror(errno), errno);
> strerror(errno));
> pr_warning("load bpf program failed: %s\n", strerror(errno));
> pr_warning("failed to statfs %s: %s\n", dir, strerror(errno));
> pr_warning("failed to pin program: %s\n", strerror(errno));
> pr_warning("failed to mkdir %s: %s\n", path, strerror(-err));
> pr_warning("failed to pin map: %s\n", strerror(errno));
> $
>
> The next issue with strerror_r is to assign the return value to a variable.
> Then we end up with variable set but not used:
> libbpf.c: In function ‘bpf_object__elf_collect’:
> libbpf.c:809:35: error: variable ‘cp’ set but not used [-Werror=unused-but-set-variable]
> char errmsg[STRERR_BUFSIZE], *cp;
> ^
> cc1: all warnings being treated as errors
The GNU-specific strerror_r() returns a pointer to a string containing
the error message. This may be either a pointer to a string that the
function stores in buf, or a pointer to some (immutable) static string
(in which case buf is unused). If the function stores a string in buf,
then at most buflen bytes are stored (the string may be truncated if
buflen is too small and errnum is unknown). The string always includes
a terminating null byte ('\0').
IOW you gotta use the return value.
> Here is the source:
> if (err) {
> char errmsg[STRERR_BUFSIZE], *cp;
>
> cp = strerror_r(-err, errmsg, sizeof(errmsg));
> pr_warning("failed to alloc program %s (%s): %s",
> name, obj->path, errmsg);
> }
>
> To fix this requires something like:
> pr_warning("failed to alloc program %s (%s): %s",
> name, obj->path, cp);
This looks correct.
> And after pr_warning() is done, the local array errmsg is deleted.
>
> A lot of overkill in my opinion, unless I miss something.
IMO using potentially mutli-thread unsafe functions in a library is not
optimal, we should strive to convert the other instances of strerror()
rather than move the other way.
> >>> causes a compiler error when building the perf tool in the linux-next tree.
> >>> I compile it using a FEDORA 28 installation, my gcc compiler version:
> >>> gcc (GCC) 8.0.1 20180324 (Red Hat 8.0.1-0.20)
> >>>
> >>> The file that causes the error is tools/lib/bpf/libbpf.c
> >>>
> >>> Here is the error message:
> > [...]
> >>> @@ -2334,7 +2331,7 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
> >>> __u64 data_tail = header->data_tail;
> >>> __u64 data_head = header->data_head;
> >>> void *base, *begin, *end;
> >>> - int ret;
> >>> + int ret = 0;
> >>>
> >>> asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */
> >>> if (data_head == data_tail)
> >>
> >> This looks like a separate issue. The ret variable should really be
> >> enum bpf_perf_event_ret, so could you please initialize it to one of the
> >> values of this enum?
> >>
> >> The uninitilized condition can only happen if (data_head != data_tail)
> >> but at the same time (data_head % size == data_tail % size) which
> >> should never really happen... Perhaps initializing to
> >> LIBBPF_PERF_EVENT_ERROR would make sense?
> >>
> >> Or better still adding:
> >>
> >> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> >> index f732237610e5..fa5a25945f19 100644
> >> --- a/tools/lib/bpf/libbpf.c
> >> +++ b/tools/lib/bpf/libbpf.c
> >> @@ -2289,6 +2289,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
> >>
> >> begin = base + data_tail % size;
> >> end = base + data_head % size;
> >> + if (being == end)
> >> + return LIBBPF_PERF_EVENT_ERROR;
> >
> > Sounds good to me.
> >
>
> If you want I can send you a separate patch for this.
As far as I'm concerned - yes, please!
^ permalink raw reply
* Re: [RFC] Add BPF_SYNCHRONIZE bpf(2) command
From: Daniel Colascione @ 2018-07-27 19:17 UTC (permalink / raw)
To: Joel Fernandes
Cc: Alexei Starovoitov, Lorenzo Colitti, Chenbo Feng,
Mathieu Desnoyers, Joel Fernandes, Alexei Starovoitov, lkml,
Tim Murray, Daniel Borkmann, netdev
In-Reply-To: <20180714181815.GA199777@joelaf.mtv.corp.google.com>
[-- Attachment #1: Type: text/plain, Size: 659 bytes --]
On Sat, Jul 14, 2018 at 11:18 AM, Joel Fernandes <joel@joelfernandes.org>
wrote:
> By the way just curious I was briefly going through kernel/bpf/arraymap.c.
> How are you protecting against load-store tearing of values of array map
> updates/lookups?
>
> For example, if userspace reads an array map at a particular index, while
> another CPU is updating it, then userspace can read partial values /
> half-updated values right? Since rcu_read_lock is in use, I was hoping to
> find something like rcu_assign_pointer there to protect readers against
> concurrent updates. Thanks for any clarification.
I'm also curious about the answer to this question.
[-- Attachment #2: Type: text/html, Size: 1002 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] net: ethernet: ti: cpsw: replace unnecessarily macroses on functions
From: Grygorii Strashko @ 2018-07-27 19:15 UTC (permalink / raw)
To: Ivan Khoronzhuk, davem; +Cc: linux-omap, netdev, linux-kernel
In-Reply-To: <20180727191318.18698-1-ivan.khoronzhuk@linaro.org>
On 07/27/2018 02:13 PM, Ivan Khoronzhuk wrote:
> Replace ugly macroses on functions.
>
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
--
regards,
-grygorii
^ permalink raw reply
* [PATCH net-next] net: ethernet: ti: cpsw: replace unnecessarily macroses on functions
From: Ivan Khoronzhuk @ 2018-07-27 19:13 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
Replace ugly macroses on functions.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
Based on net-next/master
drivers/net/ethernet/ti/cpsw.c | 63 +++++++++++++++++-----------------
1 file changed, 32 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 1b54c26c2bec..62326a98945b 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -565,40 +565,40 @@ static const struct cpsw_stats cpsw_gstrings_ch_stats[] = {
(func)(slave++, ##arg); \
} while (0)
-#define cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb) \
- do { \
- if (!cpsw->data.dual_emac) \
- break; \
- if (CPDMA_RX_SOURCE_PORT(status) == 1) { \
- ndev = cpsw->slaves[0].ndev; \
- skb->dev = ndev; \
- } else if (CPDMA_RX_SOURCE_PORT(status) == 2) { \
- ndev = cpsw->slaves[1].ndev; \
- skb->dev = ndev; \
- } \
- } while (0)
-#define cpsw_add_mcast(cpsw, priv, addr) \
- do { \
- if (cpsw->data.dual_emac) { \
- struct cpsw_slave *slave = cpsw->slaves + \
- priv->emac_port; \
- int slave_port = cpsw_get_slave_port( \
- slave->slave_num); \
- cpsw_ale_add_mcast(cpsw->ale, addr, \
- 1 << slave_port | ALE_PORT_HOST, \
- ALE_VLAN, slave->port_vlan, 0); \
- } else { \
- cpsw_ale_add_mcast(cpsw->ale, addr, \
- ALE_ALL_PORTS, \
- 0, 0, 0); \
- } \
- } while (0)
-
static inline int cpsw_get_slave_port(u32 slave_num)
{
return slave_num + 1;
}
+static inline void cpsw_src_port_detect(struct cpsw_common *cpsw, int status,
+ struct sk_buff *skb)
+{
+ if (!cpsw->data.dual_emac)
+ return;
+
+ if (CPDMA_RX_SOURCE_PORT(status) == 1)
+ skb->dev = cpsw->slaves[0].ndev;
+ else if (CPDMA_RX_SOURCE_PORT(status) == 2)
+ skb->dev = cpsw->slaves[1].ndev;
+}
+
+static void cpsw_add_mcast(struct cpsw_priv *priv, u8 *addr)
+{
+ struct cpsw_common *cpsw = priv->cpsw;
+
+ if (cpsw->data.dual_emac) {
+ struct cpsw_slave *slave = cpsw->slaves + priv->emac_port;
+ int slave_port = cpsw_get_slave_port(slave->slave_num);
+
+ cpsw_ale_add_mcast(cpsw->ale, addr,
+ 1 << slave_port | ALE_PORT_HOST,
+ ALE_VLAN, slave->port_vlan, 0);
+ return;
+ }
+
+ cpsw_ale_add_mcast(cpsw->ale, addr, ALE_ALL_PORTS, 0, 0, 0);
+}
+
static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
{
struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
@@ -706,7 +706,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
/* program multicast address list into ALE register */
netdev_for_each_mc_addr(ha, ndev) {
- cpsw_add_mcast(cpsw, priv, (u8 *)ha->addr);
+ cpsw_add_mcast(priv, (u8 *)ha->addr);
}
}
}
@@ -801,7 +801,8 @@ static void cpsw_rx_handler(void *token, int len, int status)
int ret = 0;
struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
- cpsw_dual_emac_src_port_detect(cpsw, status, ndev, skb);
+ cpsw_src_port_detect(cpsw, status, skb);
+ ndev = skb->dev;
if (unlikely(status < 0) || unlikely(!netif_running(ndev))) {
/* In dual emac mode check for all interfaces */
--
2.17.1
^ permalink raw reply related
* Re: [PATCH net-next] net: ethernet: ti: cpsw: add missed RX_CTAG feature for second slave
From: Grygorii Strashko @ 2018-07-27 17:37 UTC (permalink / raw)
To: Ivan Khoronzhuk, davem; +Cc: linux-omap, netdev, linux-kernel
In-Reply-To: <20180727165439.16933-1-ivan.khoronzhuk@linaro.org>
On 07/27/2018 11:54 AM, Ivan Khoronzhuk wrote:
> Seems it was missed while adding for first net dev in dual-emac mode.
>
> Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
> ---
> Based on net-next/master
Reviewed-by: Grygorii Strashko <grygorii.strashko@ti.com>
--
regards,
-grygorii
^ permalink raw reply
* Re: [PATCH] xen-netfront: wait xenbus state change when load module manually
From: Boris Ostrovsky @ 2018-07-27 18:40 UTC (permalink / raw)
To: Xiao Liang, netdev, xen-devel, davem, jgross; +Cc: linux-kernel
In-Reply-To: <20180727095608.25210-1-xiliang@redhat.com>
On 07/27/2018 05:56 AM, Xiao Liang wrote:
> When loading module manually, after call xenbus_switch_state to initializes
> the state of the netfront device, the driver state did not change so fast
> that may lead no dev created in latest kernel. This patch adds wait to make
> sure xenbus knows the driver is not in closed/unknown state.
>
> Current state:
> [vm]# ethtool eth0
> Settings for eth0:
> Link detected: yes
> [vm]# modprobe -r xen_netfront
> [vm]# modprobe xen_netfront
> [vm]# ethtool eth0
> Settings for eth0:
> Cannot get device settings: No such device
> Cannot get wake-on-lan settings: No such device
> Cannot get message level: No such device
> Cannot get link status: No such device
> No data available
>
> With the patch installed.
> [vm]# ethtool eth0
> Settings for eth0:
> Link detected: yes
> [vm]# modprobe -r xen_netfront
> [vm]# modprobe xen_netfront
> [vm]# ethtool eth0
> Settings for eth0:
> Link detected: yes
>
> Signed-off-by: Xiao Liang <xiliang@redhat.com>
> ---
> drivers/net/xen-netfront.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
> index a57daecf1d57..2d8812dd1534 100644
> --- a/drivers/net/xen-netfront.c
> +++ b/drivers/net/xen-netfront.c
> @@ -87,6 +87,7 @@ struct netfront_cb {
> /* IRQ name is queue name with "-tx" or "-rx" appended */
> #define IRQ_NAME_SIZE (QUEUE_NAME_SIZE + 3)
>
> +static DECLARE_WAIT_QUEUE_HEAD(module_load_q);
> static DECLARE_WAIT_QUEUE_HEAD(module_unload_q);
>
> struct netfront_stats {
> @@ -1330,6 +1331,11 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev)
> netif_carrier_off(netdev);
>
> xenbus_switch_state(dev, XenbusStateInitialising);
> + wait_event(module_load_q,
> + xenbus_read_driver_state(dev->otherend) !=
> + XenbusStateClosed &&
> + xenbus_read_driver_state(dev->otherend) !=
> + XenbusStateUnknown);
> return netdev;
>
> exit:
Should we have a wake_up somewhere? And what about other states --- is,
for example, XenbusStateClosing a valid reason to continue?
-boris
^ permalink raw reply
* Re: [PATCH 00/18] xfrm: Add compat layer
From: Andy Lutomirski @ 2018-07-27 17:09 UTC (permalink / raw)
To: Nathan Harold
Cc: Dmitry Safonov, Florian Westphal, Steffen Klassert, linux-kernel,
David S. Miller, Herbert Xu, Dmitry Safonov, netdev,
Andy Lutomirski, Ard Biesheuvel, H. Peter Anvin, Ingo Molnar,
John Stultz, Kirill A. Shutemov, Oleg Nesterov, Stephen Boyd,
Steven Rostedt, Thomas Gleixner, x86, linux-efi, Andrew Morton, G
In-Reply-To: <CADhJOfam+cY8uD4XTGvZSEFQdAgTu49G6cg6c64NJoP3bNuBmw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2064 bytes --]
> On Jul 27, 2018, at 9:48 AM, Nathan Harold <nharold@google.com> wrote:
>
> We (Android) are very interested in removing the restriction for 32-bit userspace processes accessing xfrm netlink on 64-bit kernels. IPsec support is required to pass Android conformance tests, and any manufacturer wishing to ship 32-bit userspace with a recent kernel needs out-of-tree changes (removing the compat_task check) to do so.
>
> That said, it’s not difficult to work around alignment issues directly in userspace, so maybe we could just remove the check and make this the caller's responsibility? Here’s an example of the workaround currently in the Android tree:
> https://android.googlesource.com/platform/system/netd/+/refs/heads/master/server/XfrmController.h#257
>
> We could also employ a (relatively simple) solution such as the one above in the uapi XFRM header itself, though it would require a caller to declare the target kernel ABI at compile time. Maybe that’s not unthinkable for an uncommon case?
>
Could there just be an XFRM2 that is entirely identical to XFRM for 64-bit userspace but makes the 32-bit structures match? If there are a grand total of two or so userspace implementations, that should cover most use cases. L
> -Nathan
>
>
>> On Fri, Jul 27, 2018 at 7:51 AM, Dmitry Safonov <dima@arista.com> wrote:
>> On Fri, 2018-07-27 at 16:19 +0200, Florian Westphal wrote:
>> > Dmitry Safonov <dima@arista.com> wrote:
>> > > 1. It will double copy netlink messages, making it O(n) instead of
>> > > O(1), where n - is number of bind()s.. Probably we don't care much.
>> >
>> > About those bind() patches, I don't understand why they are needed.
>> >
>> > Why can't you just add the compat skb to the native skb when doing
>> > the multicast call?
>> >
>> > skb_shinfo(skb)->frag_list = compat_skb;
>> > xfrm_nlmsg_multicast(net, skb, 0, ...
>>
>> Oh yeah, sorry, I think I misread the patch - will try to add compat
>> skb in the multicast call.
>>
>> --
>> Thanks,
>> Dmitry
>
[-- Attachment #2: Type: text/html, Size: 4724 bytes --]
^ permalink raw reply
* Re: [PATCH v2] perf build: Build error in libbpf with EXTRA_CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -O2"
From: Daniel Borkmann @ 2018-07-27 18:29 UTC (permalink / raw)
To: Jakub Kicinski, Thomas-Mich Richter
Cc: ast, netdev, linux-kernel, heiko.carstens, brueckner, schwidefsky,
wangnan0
In-Reply-To: <20180727105757.2d851920@cakuba.netronome.com>
On 07/27/2018 07:57 PM, Jakub Kicinski wrote:
> On Fri, 27 Jul 2018 09:22:03 +0200, Thomas-Mich Richter wrote:
>> On 07/27/2018 04:16 AM, Daniel Borkmann wrote:
>>> On 07/26/2018 03:48 AM, Jakub Kicinski wrote:
>>>> On Wed, 25 Jul 2018 09:21:26 +0200, Thomas Richter wrote:
>>>>> commit a5b8bd47dcc57 ("bpf tools: Collect eBPF programs from their own sections")
>>>>
>>>> Hmm.. are you sure it's not 531b014e7a2f ("tools: bpf: make use of
>>>> reallocarray") that caused the issue? That commit made us switch from
>>>> XSI-compliant to GNU-specific strerror_r() implementation..
>>>>
>>>> /me checks
>>>>
>>>> Yes it looks like 531b014e7a2f~ builds just fine.
>>>>
>>>> Daniel, did you try to apply v1 to the bpf tree? Perhaps there is a
>>>> confusion about the trees here, if this is caused by my recent change
>>>> it's a bpf-next material. strerror() works, but strerror_r() seems
>>>> nicer, so perhaps we could keep it if the patch worked in bpf-next?
>>>
>>> Yeah indeed, the issue is only in bpf-next. When I compile libbpf from
>>> bpf tree with the below flags then it's all good>
>>> Agree that we should rather use strerror_r() given this is a library.
>>
>> Are you sure to stick with strerror_r? I ask because it is the only
>> occurence of strerror_r in this file. All other error messages use strerror
>> as in:
>> pr_warning("failed to create map (name: '%s'): %s\n",
>> map->name,
>> strerror(errno));
>>
>> $ fgrep strerror tools/lib/bpf/libbpf.c
>> strerror(errno));
>> issue I try to solve---> strerror_r(-err, errmsg, sizeof(errmsg));
>> map->name, strerror(errno), errno);
>> strerror(errno));
>> pr_warning("load bpf program failed: %s\n", strerror(errno));
>> pr_warning("failed to statfs %s: %s\n", dir, strerror(errno));
>> pr_warning("failed to pin program: %s\n", strerror(errno));
>> pr_warning("failed to mkdir %s: %s\n", path, strerror(-err));
>> pr_warning("failed to pin map: %s\n", strerror(errno));
>> $
>>
>> The next issue with strerror_r is to assign the return value to a variable.
>> Then we end up with variable set but not used:
>> libbpf.c: In function ‘bpf_object__elf_collect’:
>> libbpf.c:809:35: error: variable ‘cp’ set but not used [-Werror=unused-but-set-variable]
>> char errmsg[STRERR_BUFSIZE], *cp;
>> ^
>> cc1: all warnings being treated as errors
>
> The GNU-specific strerror_r() returns a pointer to a string containing
> the error message. This may be either a pointer to a string that the
> function stores in buf, or a pointer to some (immutable) static string
> (in which case buf is unused). If the function stores a string in buf,
> then at most buflen bytes are stored (the string may be truncated if
> buflen is too small and errnum is unknown). The string always includes
> a terminating null byte ('\0').
>
> IOW you gotta use the return value.
>
>> Here is the source:
>> if (err) {
>> char errmsg[STRERR_BUFSIZE], *cp;
>>
>> cp = strerror_r(-err, errmsg, sizeof(errmsg));
>> pr_warning("failed to alloc program %s (%s): %s",
>> name, obj->path, errmsg);
>> }
>>
>> To fix this requires something like:
>> pr_warning("failed to alloc program %s (%s): %s",
>> name, obj->path, cp);
>
> This looks correct.
>
>> And after pr_warning() is done, the local array errmsg is deleted.
>>
>> A lot of overkill in my opinion, unless I miss something.
>
> IMO using potentially mutli-thread unsafe functions in a library is not
> optimal, we should strive to convert the other instances of strerror()
> rather than move the other way.
Yeah, fully agree. We should convert the other ones as well over to use
strerror_r().
Thanks,
Daniel
^ permalink raw reply
* [PATCH net-next] net: ethernet: ti: cpsw: add missed RX_CTAG feature for second slave
From: Ivan Khoronzhuk @ 2018-07-27 16:54 UTC (permalink / raw)
To: grygorii.strashko, davem
Cc: linux-omap, netdev, linux-kernel, Ivan Khoronzhuk
Seems it was missed while adding for first net dev in dual-emac mode.
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
---
Based on net-next/master
drivers/net/ethernet/ti/cpsw.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c
index 171abcfb6184..1b54c26c2bec 100644
--- a/drivers/net/ethernet/ti/cpsw.c
+++ b/drivers/net/ethernet/ti/cpsw.c
@@ -3287,7 +3287,7 @@ static int cpsw_probe_dual_emac(struct cpsw_priv *priv)
priv_sl2->emac_port = 1;
cpsw->slaves[1].ndev = ndev;
- ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
+ ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_RX;
ndev->netdev_ops = &cpsw_netdev_ops;
ndev->ethtool_ops = &cpsw_ethtool_ops;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v3 bpf-next 01/14] bpf: add ability to charge bpf maps memory dynamically
From: Daniel Borkmann @ 2018-07-27 18:01 UTC (permalink / raw)
To: Roman Gushchin, netdev; +Cc: linux-kernel, kernel-team, Alexei Starovoitov
In-Reply-To: <20180720174558.5829-2-guro@fb.com>
On 07/20/2018 07:45 PM, Roman Gushchin wrote:
> This commits extends existing bpf maps memory charging API
> to support dynamic charging/uncharging.
>
> This is required to account memory used by maps,
> if all entries are created dynamically after
> the map initialization.
>
> Signed-off-by: Roman Gushchin <guro@fb.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Acked-by: Martin KaFai Lau <kafai@fb.com>
> ---
> include/linux/bpf.h | 2 ++
> kernel/bpf/syscall.c | 53 +++++++++++++++++++++++++++++++++++++---------------
> 2 files changed, 40 insertions(+), 15 deletions(-)
>
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 5b5ad95cf339..5a4a256473c3 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -435,6 +435,8 @@ struct bpf_map * __must_check bpf_map_inc(struct bpf_map *map, bool uref);
> void bpf_map_put_with_uref(struct bpf_map *map);
> void bpf_map_put(struct bpf_map *map);
> int bpf_map_precharge_memlock(u32 pages);
> +int bpf_map_charge_memlock(struct bpf_map *map, u32 pages);
> +void bpf_map_uncharge_memlock(struct bpf_map *map, u32 pages);
> void *bpf_map_area_alloc(size_t size, int numa_node);
> void bpf_map_area_free(void *base);
> void bpf_map_init_from_attr(struct bpf_map *map, union bpf_attr *attr);
> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> index d10ecd78105f..cee452a19538 100644
> --- a/kernel/bpf/syscall.c
> +++ b/kernel/bpf/syscall.c
> @@ -181,32 +181,55 @@ int bpf_map_precharge_memlock(u32 pages)
> return 0;
> }
>
> -static int bpf_map_charge_memlock(struct bpf_map *map)
> +static int bpf_charge_memlock(struct user_struct *user, u32 pages)
> {
> - struct user_struct *user = get_current_user();
> - unsigned long memlock_limit;
> + unsigned long memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
>
> - memlock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
> + if (atomic_long_add_return(pages, &user->locked_vm) > memlock_limit) {
> + atomic_long_sub(pages, &user->locked_vm);
> + return -EPERM;
> + }
> + return 0;
> +}
>
> - atomic_long_add(map->pages, &user->locked_vm);
> +static int bpf_map_init_memlock(struct bpf_map *map)
> +{
> + struct user_struct *user = get_current_user();
> + int ret;
>
> - if (atomic_long_read(&user->locked_vm) > memlock_limit) {
> - atomic_long_sub(map->pages, &user->locked_vm);
> + ret = bpf_charge_memlock(user, map->pages);
> + if (ret) {
> free_uid(user);
> - return -EPERM;
> + return ret;
> }
> map->user = user;
> - return 0;
> + return ret;
> }
>
> -static void bpf_map_uncharge_memlock(struct bpf_map *map)
> +static void bpf_map_release_memlock(struct bpf_map *map)
> {
> struct user_struct *user = map->user;
> -
> - atomic_long_sub(map->pages, &user->locked_vm);
> + atomic_long_sub(map->pages, &map->user->locked_vm);
Just a small nit since you're respinning anyway, could you also make a
proper destructor for the bpf_charge_memlock(), so we have a bpf_uncharge_memlock()
which this one here would be calling as well as ...
> free_uid(user);
> }
>
> +int bpf_map_charge_memlock(struct bpf_map *map, u32 pages)
> +{
> + int ret;
> +
> + ret = bpf_charge_memlock(map->user, pages);
> + if (ret)
> + return ret;
> + map->pages += pages;
> + return ret;
> +}
> +
> +void bpf_map_uncharge_memlock(struct bpf_map *map, u32 pages)
> +{
> + atomic_long_sub(pages, &map->user->locked_vm);
... this one, so we hide the details there.
> + map->pages -= pages;
> +}
> +
> static int bpf_map_alloc_id(struct bpf_map *map)
> {
> int id;
> @@ -256,7 +279,7 @@ static void bpf_map_free_deferred(struct work_struct *work)
> {
> struct bpf_map *map = container_of(work, struct bpf_map, work);
>
> - bpf_map_uncharge_memlock(map);
> + bpf_map_release_memlock(map);
> security_bpf_map_free(map);
> /* implementation dependent freeing */
> map->ops->map_free(map);
> @@ -492,7 +515,7 @@ static int map_create(union bpf_attr *attr)
> if (err)
> goto free_map_nouncharge;
>
> - err = bpf_map_charge_memlock(map);
> + err = bpf_map_init_memlock(map);
> if (err)
> goto free_map_sec;
>
> @@ -515,7 +538,7 @@ static int map_create(union bpf_attr *attr)
> return err;
>
> free_map:
> - bpf_map_uncharge_memlock(map);
> + bpf_map_release_memlock(map);
> free_map_sec:
> security_bpf_map_free(map);
> free_map_nouncharge:
>
^ permalink raw reply
* Re: pull request (net-next): ipsec-next 2018-07-27
From: David Miller @ 2018-07-27 16:37 UTC (permalink / raw)
To: steffen.klassert; +Cc: herbert, netdev
In-Reply-To: <20180727072449.11896-1-steffen.klassert@secunet.com>
From: Steffen Klassert <steffen.klassert@secunet.com>
Date: Fri, 27 Jul 2018 09:24:35 +0200
> 4) Add virtual xfrm interfaces. The purpose of these interfaces
> is to overcome the design limitations that the existing
> VTI devices have.
Thanks for taking the time to explain this in detail. Looks
great.
Pulled, thanks Steffen.
^ permalink raw reply
* Re: [PATCH] perf build: Build error in libbpf missing initialization
From: Jakub Kicinski @ 2018-07-27 17:59 UTC (permalink / raw)
To: Thomas Richter
Cc: daniel, ast, netdev, linux-kernel, heiko.carstens, brueckner,
schwidefsky
In-Reply-To: <20180727082126.87530-1-tmricht@linux.ibm.com>
On Fri, 27 Jul 2018 10:21:26 +0200, Thomas Richter wrote:
> In linux-next tree compiling the perf tool with additional make flags
> "EXTRA_CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -O2"
> causes a compiler error. It is the warning
> 'variable may be used uninitialized'
> which is treated as error:
>
> I compile it using a FEDORA 28 installation, my gcc compiler version:
> gcc (GCC) 8.0.1 20180324 (Red Hat 8.0.1-0.20)
>
> The file that causes the error is tools/lib/bpf/libbpf.c
>
> Here is the error message:
>
> [root@p23lp27] # make V=1 EXTRA_CFLAGS="-Wp,-D_FORTIFY_SOURCE=2 -O2"
> [...]
> Makefile.config:849: No openjdk development package found, please
> install JDK package, e.g. openjdk-8-jdk, java-1.8.0-openjdk-devel
> Warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h'
> differs from latest version at 'include/uapi/linux/if_link.h'
> CC libbpf.o
> libbpf.c: In function ‘bpf_perf_event_read_simple’:
> libbpf.c:2342:6: error: ‘ret’ may be used uninitialized in this
> function [-Werror=maybe-uninitialized]
> int ret;
> ^
> cc1: all warnings being treated as errors
> mv: cannot stat './.libbpf.o.tmp': No such file or directory
> /home6/tmricht/linux-next/tools/build/Makefile.build:96: recipe for target 'libbpf.o' failed
>
> Fix this warning and add an addition check at the beginning
> of the while loop.
>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
>
> Suggested-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Ah, you already sent this, LGTM, thanks Thomas!
> tools/lib/bpf/libbpf.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 73465caa33ba..66965ca96113 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -2349,6 +2349,8 @@ bpf_perf_event_read_simple(void *mem, unsigned long size,
>
> begin = base + data_tail % size;
> end = base + data_head % size;
> + if (begin == end)
> + return LIBBPF_PERF_EVENT_ERROR;
>
> while (begin != end) {
> struct perf_event_header *ehdr;
^ permalink raw reply
* Re: pull request (net): ipsec 2018-07-27
From: David Miller @ 2018-07-27 16:20 UTC (permalink / raw)
To: steffen.klassert; +Cc: herbert, netdev
In-Reply-To: <20180727065154.28557-1-steffen.klassert@secunet.com>
From: Steffen Klassert <steffen.klassert@secunet.com>
Date: Fri, 27 Jul 2018 08:51:49 +0200
> 1) Fix PMTU handling of vti6. We update the PMTU on
> the xfrm dst_entry which is not cached anymore
> after the flowchache removal. So update the
> PMTU of the original dst_entry instead.
> From Eyal Birger.
>
> 2) Fix a leak of kernel memory to userspace.
> From Eric Dumazet.
>
> 3) Fix a possible dst_entry memleak in xfrm_lookup_route.
> From Tommi Rantala.
>
> 4) Fix a skb leak in case we can't call nlmsg_multicast
> from xfrm_nlmsg_multicast. From Florian Westphal.
>
> 5) Fix a leak of a temporary buffer in the error path of
> esp6_input. From Zhen Lei.
>
> Please pull or let me know if there are problems.
Pulled, thanks Steffen!
^ permalink raw reply
* [PATCH net] ipv4: remove BUG_ON() from fib_compute_spec_dst
From: Lorenzo Bianconi @ 2018-07-27 16:15 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1532705461.git.lorenzo.bianconi@redhat.com>
Remove BUG_ON() from fib_compute_spec_dst routine and check
in_dev pointer during flowi4 data structure initialization.
fib_compute_spec_dst routine can be run concurrently with device removal
where ip_ptr net_device pointer is set to NULL. This can happen
if userspace enables pkt info on UDP rx socket and the device
is removed while traffic is flowing
Fixes: 35ebf65e851c ("ipv4: Create and use fib_compute_spec_dst() helper")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
net/ipv4/fib_frontend.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index e46cdd310e5f..2998b0e47d4b 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -292,19 +292,19 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
return ip_hdr(skb)->daddr;
in_dev = __in_dev_get_rcu(dev);
- BUG_ON(!in_dev);
net = dev_net(dev);
scope = RT_SCOPE_UNIVERSE;
if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) {
+ bool vmark = in_dev && IN_DEV_SRC_VMARK(in_dev);
struct flowi4 fl4 = {
.flowi4_iif = LOOPBACK_IFINDEX,
.flowi4_oif = l3mdev_master_ifindex_rcu(dev),
.daddr = ip_hdr(skb)->saddr,
.flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
.flowi4_scope = scope,
- .flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0,
+ .flowi4_mark = vmark ? skb->mark : 0,
};
if (!fib_lookup(net, &fl4, &res, 0))
return FIB_RES_PREFSRC(net, res);
--
2.17.1
^ permalink raw reply related
* Re: [PATCH net] net/mlx5e: Move mlx5e_priv_flags into en_ethtool.c
From: Kamal Heib @ 2018-07-27 15:59 UTC (permalink / raw)
To: Saeed Mahameed; +Cc: David S . Miller, Saeed Mahameed, Linux Netdev List
In-Reply-To: <CALzJLG9mmtcyEapLSSU4Y2JEBCiOqLi3ns4EAhVpJsTxT1iNLw@mail.gmail.com>
On Thu, Jul 26, 2018 at 11:51:49AM -0700, Saeed Mahameed wrote:
> On Sun, Jul 15, 2018 at 12:06 PM, Kamal Heib <kamalheib1@gmail.com> wrote:
> > Move the definition of mlx5e_priv_flags into en_ethtool.c because it's
> > only used there.
> >
> > Fixes: 4e59e2888139 ("net/mlx5e: Introduce net device priv flags infrastructure")
> > Signed-off-by: Kamal Heib <kamalheib1@gmail.com>
> > ---
> > drivers/net/ethernet/mellanox/mlx5/core/en.h | 7 -------
> > drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 7 +++++++
> > 2 files changed, 7 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
> > index eb9eb7aa953a..84e6a5b42286 100644
> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
> > @@ -208,13 +208,6 @@ struct mlx5e_umr_wqe {
> >
> > extern const char mlx5e_self_tests[][ETH_GSTRING_LEN];
> >
> > -static const char mlx5e_priv_flags[][ETH_GSTRING_LEN] = {
> > - "rx_cqe_moder",
> > - "tx_cqe_moder",
> > - "rx_cqe_compress",
> > - "rx_striding_rq",
> > -};
> > -
>
> Hi Kamal, on a second thought, i would like to drop this change and
> keep mlx5e_priv_flags close/local to the below mlx5e_priv_flag.
>
> Please let me know.
>
Hi,
Basically this change came to avoid the following warning when compiling
the mlx5 driver with "W=1" flag and this error will appear for each
file that include the "en.h".
So, I suggest not drop this change.
In file included from drivers/net/ethernet/mellanox/mlx5/core//en_main.c:40:0:
drivers/net/ethernet/mellanox/mlx5/core//en.h:206:19: warning: ‘mlx5e_priv_flags’ defined but not used [-Wunused-const-variable=]
static const char mlx5e_priv_flags[][ETH_GSTRING_LEN] = {
Thanks,
Kamal
> > enum mlx5e_priv_flag {
> > MLX5E_PFLAG_RX_CQE_BASED_MODER = (1 << 0),
> > MLX5E_PFLAG_TX_CQE_BASED_MODER = (1 << 1),
> > diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
> > index fffe514ba855..2a1c35d82c2e 100644
> > --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
> > +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
> > @@ -33,6 +33,13 @@
> > #include "en.h"
> > #include "en/port.h"
> >
> > +static const char mlx5e_priv_flags[][ETH_GSTRING_LEN] = {
> > + "rx_cqe_moder",
> > + "tx_cqe_moder",
> > + "rx_cqe_compress",
> > + "rx_striding_rq",
> > +};
> > +
> > void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
> > struct ethtool_drvinfo *drvinfo)
> > {
> > --
> > 2.14.4
> >
^ permalink raw reply
* Re: Deadlock with restart_syscall()
From: Stephen Hemminger @ 2018-07-27 15:53 UTC (permalink / raw)
To: André Pribil; +Cc: netdev@vger.kernel.org
In-Reply-To: <681500CE65202E47A192754B01DAB4673BE3D87D8D@SDE12.beckipc.net>
On Mon, 16 Jul 2018 09:31:06 +0200
André Pribil <a.pribil@beck-ipc.com> wrote:
> Hello,
>
> I'm using kernel 4.14.52-rt34 on a single core ARM system and I'm seeing a
> deadlock inside the kernel when two RT processes make calls in the right
> temporal distance. The first process is trying to bring the Ethernet interface
> up, with the SIOCGIFFLAGS ioctl(). The second process is checking the Ethernet
> carrier, speed and duplex status, by reading e.g. "/sys/class/net/eth1/speed".
>
> The first process finally gets to phy_poll_reset() in
> drivers/net/phy/phy_device.c, where it calls msleep(50).
> It never returns from the sleep.
>
> The second process gets to speed_show() in net/core/net-sysfs.c. It tries to get
> the RTNL lock with rtnl_trylock(), but fails and calls restart_syscall().
> This happens over and over again.
>
> It seems like the first process in no longer scheduled and cannot release the
> RTNL lock, while the second process is busy restarting the syscall. The first
> process has a higher RT priority than the second process.
>
> Just for testing I've added the TIF_NEED_RESCHED flag to the restart_syscall()
> function and I did not see the deadlock again with this change.
>
> static inline int restart_syscall(void)
> {
> set_tsk_thread_flag(current, TIF_SIGPENDING | TIF_NEED_RESCHED);
> return -ERESTARTNOINTR;
> }
>
> As a second test I released the RTNL lock while calling msleep() in
> phy_poll_reset(). This also made the problem disappear.
>
> I've found this thread, where a similar issue with restart_syscall() has been
> reported:
> https://www.spinics.net/lists/netdev/msg415144.html
>
> Any ideas how to fix this issue?
>
> Andre
Don't do control operations from RT processes!
There can be cases of priority inversion where RT process is waiting for
something that requires a kthread to complete the operation.
^ permalink raw reply
* Re: [PATCH v3 bpf-next 02/14] bpf: introduce cgroup storage maps
From: Roman Gushchin @ 2018-07-27 17:12 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: netdev, linux-kernel, kernel-team, Alexei Starovoitov
In-Reply-To: <a7bbd507-3de9-e574-7187-f7915add7474@iogearbox.net>
On Fri, Jul 27, 2018 at 06:11:31AM +0200, Daniel Borkmann wrote:
> On 07/20/2018 07:45 PM, Roman Gushchin wrote:
> > This commit introduces BPF_MAP_TYPE_CGROUP_STORAGE maps:
> > a special type of maps which are implementing the cgroup storage.
> >
> > From the userspace point of view it's almost a generic
> > hash map with the (cgroup inode id, attachment type) pair
> > used as a key.
> >
> > The only difference is that some operations are restricted:
> > 1) a user can't create new entries,
> > 2) a user can't remove existing entries.
> >
> > The lookup from userspace is o(log(n)).
> >
> > Signed-off-by: Roman Gushchin <guro@fb.com>
> > Cc: Alexei Starovoitov <ast@kernel.org>
> > Cc: Daniel Borkmann <daniel@iogearbox.net>
> > Acked-by: Martin KaFai Lau <kafai@fb.com>
>
> (First of all sorry for the late review, only limited availability this week
> on my side.)
Np, thank you for the review!
>
> > ---
> > include/linux/bpf-cgroup.h | 38 +++++
> > include/linux/bpf.h | 1 +
> > include/linux/bpf_types.h | 3 +
> > include/uapi/linux/bpf.h | 6 +
> > kernel/bpf/Makefile | 1 +
> > kernel/bpf/local_storage.c | 367 +++++++++++++++++++++++++++++++++++++++++++++
> > kernel/bpf/verifier.c | 12 ++
> > 7 files changed, 428 insertions(+)
> > create mode 100644 kernel/bpf/local_storage.c
> >
> > diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
> > index 79795c5fa7c3..6b0e7bd4b154 100644
> > --- a/include/linux/bpf-cgroup.h
> > +++ b/include/linux/bpf-cgroup.h
> > @@ -3,19 +3,39 @@
> > #define _BPF_CGROUP_H
> >
> > #include <linux/jump_label.h>
> > +#include <linux/rbtree.h>
> > #include <uapi/linux/bpf.h>
> >
> [...]
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index 15d69b278277..0b089ba4595d 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -5140,6 +5140,14 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env)
> > return -E2BIG;
> > }
> >
> > + if (map->map_type == BPF_MAP_TYPE_CGROUP_STORAGE &&
> > + bpf_cgroup_storage_assign(env->prog, map)) {
> > + verbose(env,
> > + "only one cgroup storage is allowed\n");
> > + fdput(f);
> > + return -EBUSY;
> > + }
> > +
> > /* hold the map. If the program is rejected by verifier,
> > * the map will be released by release_maps() or it
> > * will be used by the valid program until it's unloaded
> > @@ -5148,6 +5156,10 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env)
> > map = bpf_map_inc(map, false);
> > if (IS_ERR(map)) {
> > fdput(f);
> > + if (map->map_type ==
> > + BPF_MAP_TYPE_CGROUP_STORAGE)
> > + bpf_cgroup_storage_release(env->prog,
> > + map);
>
> I think this behavior is a bit strange, meaning that we would reset the map via
> bpf_cgroup_storage_release() in this case, but if we error out and exit in any
> later instruction the prior bpf_cgroup_storage_assign() is not undone, meaning
> at this point we have no other choice but to destroy the map since any later
> BPF prog load with bpf_cgroup_storage_assign() attempt would fail with -EBUSY
> even though it's not assigned anywhere, is that correct? Same also on any other
> errors along the prog load path. E.g. say, as one example, your verifier buffer
> is too small, so any retry with the very same program from loader side would fail
> above due to different prog pointers?
Yeah, I see...
We should call bpf_cgroup_storage_release() from the generic verifier error path.
I'll fix this and the leak in the other patch and resend soon.
Thanks!
^ permalink raw reply
* Re: [net-next v5 3/3] net/tls: Remove redundant array allocation.
From: Dave Watson @ 2018-07-27 15:38 UTC (permalink / raw)
To: Vakul Garg
Cc: David Miller, netdev@vger.kernel.org, borisp@mellanox.com,
aviadye@mellanox.com, Doron Roberts-Kedes
In-Reply-To: <DB7PR04MB42527AC58D2D7F718520F3358B2A0@DB7PR04MB4252.eurprd04.prod.outlook.com>
On 07/27/18 09:34 AM, Vakul Garg wrote:
>
>
> > -----Original Message-----
> > From: Dave Watson [mailto:davejwatson@fb.com]
> > Sent: Thursday, July 26, 2018 2:31 AM
> > To: Vakul Garg <vakul.garg@nxp.com>
> > Cc: David Miller <davem@davemloft.net>; netdev@vger.kernel.org;
> > borisp@mellanox.com; aviadye@mellanox.com; Doron Roberts-Kedes
> > <doronrk@fb.com>
> > Subject: Re: [net-next v5 3/3] net/tls: Remove redundant array allocation.
> >
> > On 07/24/18 08:22 AM, Vakul Garg wrote:
> > > Will it be a bad idea to get rid of array 'sgin' on stack and simply
> > > kmalloc 'sgin' for whatever the number the number of pages returned by
> > iov_iter_npages()?
> > > We can allocate for sgout too with the same kmalloc().
> > >
> > > (Using a local array based 'sgin' is coming in the way to achieve
> > > sending multiple async record decryption requests to the accelerator
> > > without waiting for previous one to complete.)
> >
> > Yes we could do this, and yes we would need to heap allocate if you want to
> > support multiple outstanding decryption requests. I think async crypto
> > prevents any sort of zerocopy-fastpath, however.
>
> We already do a aead_request_alloc (which internally does kmalloc).
> To mitigate the cost of kmalloc/kfree for sg lists and aad, I am allocating a
> combined memory chunk for all of these and then segmenting it into
> aead_req, aad, sgin, sgout. This way there should be no extra cost for
> memory allocations in non-async.
Makes sense, sounds good to me.
^ permalink raw reply
* Re: [PATCH 00/18] xfrm: Add compat layer
From: Nathan Harold @ 2018-07-27 16:48 UTC (permalink / raw)
To: Dmitry Safonov
Cc: Florian Westphal, Steffen Klassert, linux-kernel, David S. Miller,
Herbert Xu, Dmitry Safonov, netdev, Andy Lutomirski,
Ard Biesheuvel, H. Peter Anvin, Ingo Molnar, John Stultz,
Kirill A. Shutemov, Oleg Nesterov, Stephen Boyd, Steven Rostedt,
Thomas Gleixner, x86, linux-efi, Andrew Morton,
Greg Kroah-Hartman
In-Reply-To: <1532703111.2679.20.camel@arista.com>
[-- Attachment #1: Type: text/plain, Size: 1805 bytes --]
*We (Android) are very interested in removing the restriction for 32-bit
userspace processes accessing xfrm netlink on 64-bit kernels. IPsec support
is required to pass Android conformance tests, and any manufacturer wishing
to ship 32-bit userspace with a recent kernel needs out-of-tree changes
(removing the compat_task check) to do so.That said, it’s not difficult to
work around alignment issues directly in userspace, so maybe we could just
remove the check and make this the caller's responsibility? Here’s an
example of the workaround currently in the Android
tree:https://android.googlesource.com/platform/system/netd/+/refs/heads/master/server/XfrmController.h#257
<https://android.googlesource.com/platform/system/netd/+/refs/heads/master/server/XfrmController.h#257>We
could also employ a (relatively simple) solution such as the one above in
the uapi XFRM header itself, though it would require a caller to declare
the target kernel ABI at compile time. Maybe that’s not unthinkable for an
uncommon case?-Nathan*
On Fri, Jul 27, 2018 at 7:51 AM, Dmitry Safonov <dima@arista.com> wrote:
> On Fri, 2018-07-27 at 16:19 +0200, Florian Westphal wrote:
> > Dmitry Safonov <dima@arista.com> wrote:
> > > 1. It will double copy netlink messages, making it O(n) instead of
> > > O(1), where n - is number of bind()s.. Probably we don't care much.
> >
> > About those bind() patches, I don't understand why they are needed.
> >
> > Why can't you just add the compat skb to the native skb when doing
> > the multicast call?
> >
> > skb_shinfo(skb)->frag_list = compat_skb;
> > xfrm_nlmsg_multicast(net, skb, 0, ...
>
> Oh yeah, sorry, I think I misread the patch - will try to add compat
> skb in the multicast call.
>
> --
> Thanks,
> Dmitry
>
[-- Attachment #2: Type: text/html, Size: 3972 bytes --]
^ permalink raw reply
* Re: [PATCH linux-firmware] Mellanox: Add new mlxsw_spectrum firmware 13.1702.6
From: Josh Boyer @ 2018-07-27 15:16 UTC (permalink / raw)
To: nird; +Cc: Linux Firmware, netdev, David Ahern, mlxsw
In-Reply-To: <20180722113608.24021-1-nird@mellanox.com>
Applied and pushed out.
josh
On Sun, Jul 22, 2018 at 7:43 AM Nir Dotan <nird@mellanox.com> wrote:
>
> This new firmware contains: - Support for new types of cables - Support for flashing future firmware without reboot - Support for Router ARP BC and UC traps Signed-off-by: Nir Dotan --- WHENCE | 3 ++- mellanox/mlxsw_spectrum-13.1702.6.mfa2 | Bin 0 -> 863220 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 mellanox/mlxsw_spectrum-13.1702.6.mfa2 diff --git a/WHENCE b/WHENCE index 6771831..cdc78ba 100644 --- a/WHENCE +++ b/WHENCE @@ -4050,9 +4050,10 @@ Driver: mlxsw_spectrum - Mellanox Spectrum switch File: mellanox/mlxsw_spectrum-13.1420.122.mfa2 File: mellanox/mlxsw_spectrum-13.1530.152.mfa2 File: mellanox/mlxsw_spectrum-13.1620.192.mfa2 +File: mellanox/mlxsw_spectrum-13.1702.6.mfa2 Licence: - Copyright (c) 2017 Mellanox Technologies, Ltd. All rights reserved. + Copyright (c) 2017-2018 Mellanox Technologies, Ltd. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/mellanox/mlxsw_spectrum-13.1702.6.mfa2 b/mellanox/mlxsw_spectrum-13.1702.6.mfa2 new file mode 100644 index 0000000000000000000000000000000000000000..0186d19c8285f161d2ffc6644e8451ff448e1684 GIT binary patch literal 863220 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
^ permalink raw reply
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