* Re: WARNING in perf_trace_buf_alloc (2)
From: Alexei Starovoitov @ 2018-04-28 5:23 UTC (permalink / raw)
To: Eric Biggers
Cc: Alexei Starovoitov, Daniel Borkmann, linux-kernel, mingo, rostedt,
syzkaller-bugs, netdev, syzbot
In-Reply-To: <20180421193701.GE1098@sol.localdomain>
On Sat, Apr 21, 2018 at 12:37:01PM -0700, Eric Biggers wrote:
> [+bpf maintainers and netdev]
>
> On Mon, Nov 06, 2017 at 03:56:01AM -0800, syzbot wrote:
> > Hello,
> >
> > syzkaller hit the following crash on
> > 5cb0512c02ecd7e6214e912e4c150f4219ac78e0
> > git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/master
> > compiler: gcc (GCC) 7.1.1 20170620
> > .config is attached
> > Raw console output is attached.
> > C reproducer is attached
> > syzkaller reproducer is attached. See https://goo.gl/kgGztJ
> > for information about syzkaller reproducers
> >
> >
> > ------------[ cut here ]------------
> > WARNING: CPU: 0 PID: 3008 at kernel/trace/trace_event_perf.c:274
> > perf_trace_buf_alloc+0x12d/0x160 kernel/trace/trace_event_perf.c:273
> > Kernel panic - not syncing: panic_on_warn set ...
> >
> > CPU: 0 PID: 3008 Comm: syzkaller609027 Not tainted 4.14.0-rc7+ #159
> > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> > Google 01/01/2011
> > Call Trace:
> > __dump_stack lib/dump_stack.c:17 [inline]
> > dump_stack+0x194/0x257 lib/dump_stack.c:53
> > panic+0x1e4/0x417 kernel/panic.c:181
> > __warn+0x1c4/0x1d9 kernel/panic.c:542
> > report_bug+0x211/0x2d0 lib/bug.c:184
> > fixup_bug+0x40/0x90 arch/x86/kernel/traps.c:178
> > do_trap_no_signal arch/x86/kernel/traps.c:212 [inline]
> > do_trap+0x260/0x390 arch/x86/kernel/traps.c:261
> > do_error_trap+0x120/0x390 arch/x86/kernel/traps.c:298
> > do_invalid_op+0x1b/0x20 arch/x86/kernel/traps.c:311
> > invalid_op+0x18/0x20 arch/x86/entry/entry_64.S:906
> > RIP: 0010:perf_trace_buf_alloc+0x12d/0x160
> > kernel/trace/trace_event_perf.c:273
> > RSP: 0018:ffff8801c0fdf760 EFLAGS: 00010286
> > RAX: 000000000000001c RBX: 1ffff100381fbefe RCX: 0000000000000000
> > RDX: 000000000000001c RSI: 1ffff100381fbeac RDI: ffffed00381fbee0
> > RBP: ffff8801c0fdf780 R08: 0000000000000001 R09: 0000000000000000
> > R10: ffff8801c0fdf7a0 R11: 0000000000000000 R12: 000000000000082c
> > R13: ffff8801c0fdf810 R14: ffff8801c0fdf890 R15: ffff8801d8b34b40
> > perf_trace_bpf_map_keyval+0x260/0xbd0 include/trace/events/bpf.h:228
> > trace_bpf_map_update_elem include/trace/events/bpf.h:274 [inline]
> > map_update_elem kernel/bpf/syscall.c:597 [inline]
> > SYSC_bpf kernel/bpf/syscall.c:1478 [inline]
> > SyS_bpf+0x33eb/0x46a0 kernel/bpf/syscall.c:1453
> > entry_SYSCALL_64_fastpath+0x1f/0xbe
> > RIP: 0033:0x445c29
> > RSP: 002b:00000000007eff68 EFLAGS: 00000246 ORIG_RAX: 0000000000000141
> > RAX: ffffffffffffffda RBX: 00007ffe66adb340 RCX: 0000000000445c29
> > RDX: 0000000000000020 RSI: 000000002053dfe0 RDI: 0000000000000002
> > RBP: 0000000000000082 R08: 0000000000000000 R09: 0000000000000000
> > R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000403280
> > R13: 0000000000403310 R14: 0000000000000000 R15: 0000000000000000
> > Dumping ftrace buffer:
> > (ftrace buffer empty)
> > Kernel Offset: disabled
> > Rebooting in 86400 seconds..
> >
> >
> > ---
> > This bug is generated by a dumb bot. It may contain errors.
> > See https://goo.gl/tpsmEJ for details.
> > Direct all questions to syzkaller@googlegroups.com.
> > Please credit me with: Reported-by: syzbot <syzkaller@googlegroups.com>
> >
> > syzbot will keep track of this bug report.
> > Once a fix for this bug is committed, please reply to this email with:
> > #syz fix: exact-commit-title
> > To mark this as a duplicate of another syzbot report, please reply with:
> > #syz dup: exact-subject-of-another-report
> > If it's a one-off invalid bug report, please reply with:
> > #syz invalid
> > Note: if the crash happens again, it will cause creation of a new bug
> > report.
> > Note: all commands must start from beginning of the line.
>
> This still happens on Linus' tree. It seems one of the BPF tracepoints is
> trying to pass a buffer that is too long. Here's a simplified reproducer that
right. this is easily reproducible.
looks like tracepoints in bpf core rot quite a bit.
will send a patch to address that soon.
> works on Linus' tree (commit 5e7c7806111ade5). Note: it's not 100% reliable for
> some reason; you may have to run it a couple times. Daniel or Alexei, can one
> of you please look into this more? Thanks!
>
> #include <linux/bpf.h>
> #include <linux/perf_event.h>
> #include <stdio.h>
> #include <sys/syscall.h>
> #include <unistd.h>
>
> int main()
> {
> int tracepoint_id;
> FILE *f;
>
> f = fopen("/sys/kernel/debug/tracing/events/bpf/bpf_map_update_elem/id",
> "r");
> fscanf(f, "%d", &tracepoint_id);
>
> struct perf_event_attr perf_attr = {
> .type = PERF_TYPE_TRACEPOINT,
> .size = sizeof(perf_attr),
> .config = tracepoint_id,
> };
> syscall(__NR_perf_event_open, &perf_attr, 0, 0, -1, 0);
>
> for (;;) {
> union bpf_attr create_attr = {
> .map_type = BPF_MAP_TYPE_HASH,
> .key_size = 4,
> .value_size = 2048,
> .max_entries = 1,
> };
> int fd = syscall(__NR_bpf, BPF_MAP_CREATE,
> &create_attr, sizeof(create_attr));
>
> char key[4] = { 0 };
> char value[2048] = { 0 };
> union bpf_attr update_attr = {
> .map_fd = fd,
> .key = (unsigned long)key,
> .value = (unsigned long)value,
> };
> syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM,
> &update_attr, sizeof(update_attr));
> close(fd);
> }
> }
^ permalink raw reply
* Re: [PATCH bpf-next v7 05/10] bpf/verifier: improve register value range tracking with ARSH
From: Yonghong Song @ 2018-04-28 5:23 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: ast, daniel, netdev, kernel-team
In-Reply-To: <20180427234817.g6zprnsoj3cfvzhb@ast-mbp>
On 4/27/18 4:48 PM, Alexei Starovoitov wrote:
> On Wed, Apr 25, 2018 at 12:29:05PM -0700, Yonghong Song wrote:
>> When helpers like bpf_get_stack returns an int value
>> and later on used for arithmetic computation, the LSH and ARSH
>> operations are often required to get proper sign extension into
>> 64-bit. For example, without this patch:
>> 54: R0=inv(id=0,umax_value=800)
>> 54: (bf) r8 = r0
>> 55: R0=inv(id=0,umax_value=800) R8_w=inv(id=0,umax_value=800)
>> 55: (67) r8 <<= 32
>> 56: R8_w=inv(id=0,umax_value=3435973836800,var_off=(0x0; 0x3ff00000000))
>> 56: (c7) r8 s>>= 32
>> 57: R8=inv(id=0)
>> With this patch:
>> 54: R0=inv(id=0,umax_value=800)
>> 54: (bf) r8 = r0
>> 55: R0=inv(id=0,umax_value=800) R8_w=inv(id=0,umax_value=800)
>> 55: (67) r8 <<= 32
>> 56: R8_w=inv(id=0,umax_value=3435973836800,var_off=(0x0; 0x3ff00000000))
>> 56: (c7) r8 s>>= 32
>> 57: R8=inv(id=0, umax_value=800,var_off=(0x0; 0x3ff))
>> With better range of "R8", later on when "R8" is added to other register,
>> e.g., a map pointer or scalar-value register, the better register
>> range can be derived and verifier failure may be avoided.
>>
>> In our later example,
>> ......
>> usize = bpf_get_stack(ctx, raw_data, max_len, BPF_F_USER_STACK);
>> if (usize < 0)
>> return 0;
>> ksize = bpf_get_stack(ctx, raw_data + usize, max_len - usize, 0);
>> ......
>> Without improving ARSH value range tracking, the register representing
>> "max_len - usize" will have smin_value equal to S64_MIN and will be
>> rejected by verifier.
>>
>> Signed-off-by: Yonghong Song <yhs@fb.com>
>> ---
>> include/linux/tnum.h | 4 +++-
>> kernel/bpf/tnum.c | 10 ++++++++++
>> kernel/bpf/verifier.c | 41 +++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 54 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/linux/tnum.h b/include/linux/tnum.h
>> index 0d2d3da..c7dc2b5 100644
>> --- a/include/linux/tnum.h
>> +++ b/include/linux/tnum.h
>> @@ -23,8 +23,10 @@ struct tnum tnum_range(u64 min, u64 max);
>> /* Arithmetic and logical ops */
>> /* Shift a tnum left (by a fixed shift) */
>> struct tnum tnum_lshift(struct tnum a, u8 shift);
>> -/* Shift a tnum right (by a fixed shift) */
>> +/* Shift (rsh) a tnum right (by a fixed shift) */
>> struct tnum tnum_rshift(struct tnum a, u8 shift);
>> +/* Shift (arsh) a tnum right (by a fixed min_shift) */
>> +struct tnum tnum_arshift(struct tnum a, u8 min_shift);
>> /* Add two tnums, return @a + @b */
>> struct tnum tnum_add(struct tnum a, struct tnum b);
>> /* Subtract two tnums, return @a - @b */
>> diff --git a/kernel/bpf/tnum.c b/kernel/bpf/tnum.c
>> index 1f4bf68..938d412 100644
>> --- a/kernel/bpf/tnum.c
>> +++ b/kernel/bpf/tnum.c
>> @@ -43,6 +43,16 @@ struct tnum tnum_rshift(struct tnum a, u8 shift)
>> return TNUM(a.value >> shift, a.mask >> shift);
>> }
>>
>> +struct tnum tnum_arshift(struct tnum a, u8 min_shift)
>> +{
>> + /* if a.value is negative, arithmetic shifting by minimum shift
>> + * will have larger negative offset compared to more shifting.
>> + * If a.value is nonnegative, arithmetic shifting by minimum shift
>> + * will have larger positive offset compare to more shifting.
>> + */
>> + return TNUM((s64)a.value >> min_shift, (s64)a.mask >> min_shift);
>> +}
>> +
>> struct tnum tnum_add(struct tnum a, struct tnum b)
>> {
>> u64 sm, sv, sigma, chi, mu;
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 6e3f859..573807f 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -2974,6 +2974,47 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env,
>> /* We may learn something more from the var_off */
>> __update_reg_bounds(dst_reg);
>> break;
>> + case BPF_ARSH:
>> + if (umax_val >= insn_bitness) {
>> + /* Shifts greater than 31 or 63 are undefined.
>> + * This includes shifts by a negative number.
>> + */
>> + mark_reg_unknown(env, regs, insn->dst_reg);
>> + break;
>> + }
>> +
>> + /* BPF_ARSH is an arithmetic shift. The new range of
>> + * smin_value and smax_value should take the sign
>> + * into consideration.
>> + *
>> + * For example, if smin_value = -16, umin_val = 0
>> + * and umax_val = 2, the new smin_value should be
>> + * -16 >> 0 = -16 since -16 >> 2 = -4.
>> + * If smin_value = 16, umin_val = 0 and umax_val = 2,
>> + * the new smin_value should be 16 >> 2 = 4.
>> + *
>> + * Now suppose smax_value = -4, umin_val = 0 and
>> + * umax_val = 2, the new smax_value should be
>> + * -4 >> 2 = -1. If smax_value = 32 with the same
>> + * umin_val/umax_val, the new smax_value should remain 32.
>> + */
>> + if (dst_reg->smin_value < 0)
>> + dst_reg->smin_value >>= umin_val;
>> + else
>> + dst_reg->smin_value >>= umax_val;
>> + if (dst_reg->smax_value < 0)
>> + dst_reg->smax_value >>= umax_val;
>> + else
>> + dst_reg->smax_value >>= umin_val;
>
> above sounds correct, but unnecessary, since we have this:
> if ((src_known && (smin_val != smax_val || umin_val != umax_val)) mark_unknown
> at the top.
Yes, so the following should be much simpler:
dst_reg->smin_value >>= umin_val;
dst_reg->smax_value >>= umin_val;
>
> Also would it work if we blow smin/smax just like umin/umax
> and rely on tnum_arshift only?
I tried. This does not work. For example, with blowing up smin/smax
method, the below R8 will have umax/smax the same as both derived
from var_off.
60: R0=inv(id=0,umax_value=800,var_off=(0x0; 0x3ff)) R1=inv0
R2_w=map_value(id=0,off=0,ks=4,vs=1600,umax_value=1023,var_off=(0
x0; 0x3ff)) R6=ctx(id=0,off=0,imm=0)
R7=map_value(id=0,off=0,ks=4,vs=1600,imm=0)
R8=inv(id=0,umax_value=1023,var_off=(0x0; 0x3
ff)) R9=inv800 R10=fp0,call_-1
60: (1f) r9 -= r8
61: R0=inv(id=0,umax_value=800,var_off=(0x0; 0x3ff)) R1=inv0
R2_w=map_value(id=0,off=0,ks=4,vs=1600,umax_value=1023,var_off=(0
x0; 0x3ff)) R6=ctx(id=0,off=0,imm=0)
R7=map_value(id=0,off=0,ks=4,vs=1600,imm=0)
R8=inv(id=0,umax_value=1023,var_off=(0x0; 0x3
ff)) R9_w=inv(id=0,smin_value=-223,smax_value=800) R10=fp0,call_-1
After r9 -= r8, the smin_value for R9 becomes -223.
>
> When you rebase please document new helper in new man-page style.
Will do.
Thanks.
>
> Thanks
>
>> + dst_reg->var_off = tnum_arshift(dst_reg->var_off, umin_val);
>> +
>> + /* blow away the dst_reg umin_value/umax_value and rely on
>> + * dst_reg var_off to refine the result.
>> + */
>> + dst_reg->umin_value = 0;
>> + dst_reg->umax_value = U64_MAX;
>> + __update_reg_bounds(dst_reg);
>> + break;
>> default:
>> mark_reg_unknown(env, regs, insn->dst_reg);
>> break;
>> --
>> 2.9.5
>>
^ permalink raw reply
* Re: Request for stable 4.14.x inclusion: net: don't call update_pmtu unconditionally
From: Greg KH @ 2018-04-28 4:41 UTC (permalink / raw)
To: Eddie Chapman; +Cc: Thomas Deutschmann, stable, davem, nicolas.dichtel, netdev
In-Reply-To: <7485fe73-0c33-e5b4-6c9b-c8c7a359be4a@ehuk.net>
On Fri, Apr 27, 2018 at 07:43:52PM +0100, Eddie Chapman wrote:
> On 27/04/18 19:07, Thomas Deutschmann wrote:
> > Hi Greg,
> >
> > first, we need to cherry-pick another patch first:
> > > From 52a589d51f1008f62569bf89e95b26221ee76690 Mon Sep 17 00:00:00 2001
> > > From: Xin Long <lucien.xin@gmail.com>
> > > Date: Mon, 25 Dec 2017 14:43:58 +0800
> > > Subject: [PATCH] geneve: update skb dst pmtu on tx path
> > >
> > > Commit a93bf0ff4490 ("vxlan: update skb dst pmtu on tx path") has fixed
> > > a performance issue caused by the change of lower dev's mtu for vxlan.
> > >
> > > The same thing needs to be done for geneve as well.
> > >
> > > Note that geneve cannot adjust it's mtu according to lower dev's mtu
> > > when creating it. The performance is very low later when netperfing
> > > over it without fixing the mtu manually. This patch could also avoid
> > > this issue.
> > >
> > > Signed-off-by: Xin Long <lucien.xin@gmail.com>
> > > Signed-off-by: David S. Miller <davem@davemloft.net>
>
> Oops, I completely missed that the coreos patch doesn't have the geneve hunk
> that is in the original 4.15 patch. I don't load the geneve module on my box
> hence why no problems surfaced on my machine.
>
> Thanks Thomas for the correct instructions. Ignore my message Greg, I'll
> drop back into the shadows where I belong, sorry for the noise!
Talking about patches and pointing me at them is not noise at all, don't
be sorry! :)
I'll work on this after these next kernels are released, thanks all for
the details on what needs to be done.
greg k-h
^ permalink raw reply
* [PATCH net-next] libcxgb,cxgb4: use __skb_put_zero to simplfy code
From: YueHaibing @ 2018-04-28 4:35 UTC (permalink / raw)
To: ganeshgr, johannes.berg, davem; +Cc: netdev, linux-kernel, YueHaibing
use helper __skb_put_zero to replace the pattern of __skb_put() && memset()
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c | 3 +--
drivers/net/ethernet/chelsio/cxgb4/srq.c | 3 +--
drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.h | 15 +++++----------
3 files changed, 7 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
index db92f18..aae9802 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c
@@ -64,8 +64,7 @@ static int set_tcb_field(struct adapter *adap, struct filter_entry *f,
if (!skb)
return -ENOMEM;
- req = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*req));
- memset(req, 0, sizeof(*req));
+ req = (struct cpl_set_tcb_field *)__skb_put_zero(skb, sizeof(*req));
INIT_TP_WR_CPL(req, CPL_SET_TCB_FIELD, ftid);
req->reply_ctrl = htons(REPLY_CHAN_V(0) |
QUEUENO_V(adap->sge.fw_evtq.abs_id) |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/srq.c b/drivers/net/ethernet/chelsio/cxgb4/srq.c
index 6228a57..82b70a5 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/srq.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/srq.c
@@ -84,8 +84,7 @@ int cxgb4_get_srq_entry(struct net_device *dev,
if (!skb)
return -ENOMEM;
req = (struct cpl_srq_table_req *)
- __skb_put(skb, sizeof(*req));
- memset(req, 0, sizeof(*req));
+ __skb_put_zero(skb, sizeof(*req));
INIT_TP_WR(req, 0);
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SRQ_TABLE_REQ,
TID_TID_V(srq_idx) |
diff --git a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.h b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.h
index 4b5aacc..240ba9d 100644
--- a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.h
+++ b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.h
@@ -90,8 +90,7 @@ cxgb_mk_tid_release(struct sk_buff *skb, u32 len, u32 tid, u16 chan)
{
struct cpl_tid_release *req;
- req = __skb_put(skb, len);
- memset(req, 0, len);
+ req = __skb_put_zero(skb, len);
INIT_TP_WR(req, tid);
OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_TID_RELEASE, tid));
@@ -104,8 +103,7 @@ cxgb_mk_close_con_req(struct sk_buff *skb, u32 len, u32 tid, u16 chan,
{
struct cpl_close_con_req *req;
- req = __skb_put(skb, len);
- memset(req, 0, len);
+ req = __skb_put_zero(skb, len);
INIT_TP_WR(req, tid);
OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_CLOSE_CON_REQ, tid));
@@ -119,8 +117,7 @@ cxgb_mk_abort_req(struct sk_buff *skb, u32 len, u32 tid, u16 chan,
{
struct cpl_abort_req *req;
- req = __skb_put(skb, len);
- memset(req, 0, len);
+ req = __skb_put_zero(skb, len);
INIT_TP_WR(req, tid);
OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_REQ, tid));
@@ -134,8 +131,7 @@ cxgb_mk_abort_rpl(struct sk_buff *skb, u32 len, u32 tid, u16 chan)
{
struct cpl_abort_rpl *rpl;
- rpl = __skb_put(skb, len);
- memset(rpl, 0, len);
+ rpl = __skb_put_zero(skb, len);
INIT_TP_WR(rpl, tid);
OPCODE_TID(rpl) = cpu_to_be32(MK_OPCODE_TID(CPL_ABORT_RPL, tid));
@@ -149,8 +145,7 @@ cxgb_mk_rx_data_ack(struct sk_buff *skb, u32 len, u32 tid, u16 chan,
{
struct cpl_rx_data_ack *req;
- req = __skb_put(skb, len);
- memset(req, 0, len);
+ req = __skb_put_zero(skb, len);
INIT_TP_WR(req, tid);
OPCODE_TID(req) = cpu_to_be32(MK_OPCODE_TID(CPL_RX_DATA_ACK, tid));
--
2.7.0
^ permalink raw reply related
* [PATCH 1/1] tg3: fix meaningless hw_stats reading after tg3_halt memset 0 hw_stats
From: Zumeng Chen @ 2018-04-28 3:15 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: siva.kallam, mchan, prashant, davem, Zumeng Chen
Reading hw_stats will get the actual data after a sucessfull tg3_reset_hw,
which actually after tg3_timer_start, so tg->hw_stats_flag is introduced to
tell tg3_get_stats64 when hw_stats is ready to read, and it will be false
after having done memset(tp->hw_stats, 0) in tg3_halt. Plus tg3_get_stats64
and tg3_halt are protected by tp->lock in all scope.
Meanwhile, this patch is also to fix a kernel BUG_ON(in_interrupt) crash when
tg3_free_consistent is stuck in tp->lock, which might get a lot of in_softirq
counts(512 or so), and BUG_ON when vunmap to unmap hw->stats.
------------[ cut here ]------------
kernel BUG at /kernel-source//mm/vmalloc.c:1621!
Internal error: Oops - BUG: 0 [#1] PREEMPT SMP
task: ffffffc874310000 task.stack: ffffffc8742bc000
PC is at vunmap+0x48/0x50
LR is at __dma_free+0x98/0xa0
pc : [<ffffff80081eb420>] lr : [<ffffff8008097fb8>] pstate: 00000145
sp : ffffffc8742bfad0
x29: ffffffc8742bfad0 x28: ffffffc874310000
x27: ffffffc878931200 x26: ffffffc874530000
x25: 0000000000000003 x24: ffffff800b3aa000
x23: 00000000700bb000 x22: 0000000000000000
x21: 0000000000000000 x20: ffffffc87aafd0a0
x19: ffffff800b3aa000 x18: 0000000000000020
x17: 0000007f9e191e10 x16: ffffff8008eb0d28
x15: 000000000000000a x14: 0000000000070cc8
x13: ffffff8008c65000 x12: 00000000ffffffff
x11: 000000000000000a x10: ffffffbf21d0e220
x9 : 0000000000000004 x8 : ffffff8008c65000
x7 : 0000000000003ff0 x6 : 0000000000000000
x5 : ffffff8008097f20 x4 : 0000000000000000
x3 : ffffff8008fd4fff x2 : ffffffc87b361788
x1 : ffffff800b3aafff x0 : 0000000000000201
Process connmand (pid: 785, stack limit = 0xffffffc8742bc000)
Stack: (0xffffffc8742bfad0 to 0xffffffc8742c0000)
fac0: ffffffc8742bfaf0 ffffff8008097fb8
fae0: 0000000000001000 ffffff80ffffffff ffffffc8742bfb30 ffffff8000b717d4
fb00: ffffffc87aafd0a0 ffffff8008a38000 ffffff800b3aa000 ffffffc874530904
fb20: ffffffc874530900 00000000700bb000 ffffffc8742bfb80 ffffff8000b80324
fb40: 0000000000000001 ffffffc874530900 0000000000000100 0000000000000200
fb60: 0000000000009003 ffffffc874530000 0000000000000003 ffffffc874530000
fb80: ffffffc8742bfbd0 ffffff8000b8aa5c ffffffc874530900 ffffffc874530000
fba0: 00000000ffff0001 0000000000000000 0000000000009003 ffffffc878931210
fbc0: 0000000000009002 ffffffc874530000 ffffffc8742bfc00 ffffff80088bf44c
fbe0: ffffffc874530000 ffffffc8742bfc50 00000000ffff0001 ffffffc874310000
fc00: ffffffc8742bfc30 ffffff80088bf5e4 ffffffc874530000 00000000ffff9002
fc20: ffffffc8742bfc40 ffffffc874530000 ffffffc8742bfc60 ffffff80088c9d58
fc40: ffffffc874530000 ffffff80088c9d34 ffffffc874530080 ffffffc874530080
fc60: ffffffc8742bfca0 ffffff80088c9e4c ffffffc874530000 0000000000009003
fc80: 0000000000008914 0000000000000000 0000007ffd94ba10 ffffffc8742bfd38
fca0: ffffffc8742bfcd0 ffffff80089509f8 0000000000000000 00000000ffffff9d
fcc0: 0000000000008914 0000000000000000 ffffffc8742bfd60 ffffff8008953088
fce0: 0000000000008914 ffffffc874b49b80 0000007ffd94ba10 ffffff8008e9b400
fd00: 0000000000000004 0000007ffd94ba10 0000000000000124 000000000000001d
fd20: ffffff8008a32000 ffffff8008e9b400 0000000000000004 0000000034687465
fd40: 0000000000000000 0000000000009002 0000000000000000 0000000000000000
fd60: ffffffc8742bfd90 ffffff80088a1720 ffffffc874b49b80 0000000000008914
fd80: 0000007ffd94ba10 0000000000000000 ffffffc8742bfdc0 ffffff80088a2648
fda0: 0000000000008914 0000007ffd94ba10 ffffff8008e9b400 ffffffc878a73c00
fdc0: ffffffc8742bfe00 ffffff800822e9e0 0000000000008914 0000007ffd94ba10
fde0: ffffffc874b49bb0 ffffffc8747e5800 ffffffc8742bfe50 ffffff800823cd58
fe00: ffffffc8742bfe80 ffffff800822f0ec 0000000000000000 ffffffc878a73c00
fe20: ffffffc878a73c00 0000000000000004 0000000000008914 0000000000080000
fe40: ffffffc8742bfe80 ffffff800822f0b0 0000000000000000 ffffffc878a73c00
fe60: ffffffc878a73c00 0000000000000004 0000000000008914 ffffff8008083730
fe80: 0000000000000000 ffffff8008083730 0000000000000000 00000048771fb000
fea0: ffffffffffffffff 0000007f9e191e1c 0000000000000000 0000000000000015
fec0: 0000000000000004 0000000000008914 0000007ffd94ba10 0000000000000000
fee0: 000000000000002f 0000000000000004 0000000000000010 0000000000000000
ff00: 000000000000001d 0000000fffffffff 0101010101010101 0000000000000000
ff20: 6532336338646634 00656c6261635f38 0000007f9e46a220 0000007f9e45f318
ff40: 00000000004c1a58 0000007f9e191e10 00000000000006df 0000000000000000
ff60: 0000000000000004 00000000004c6470 00000000004c3c40 0000000000512d20
ff80: 0000000000000001 0000000000000000 0000000000000000 0000000000000000
ffa0: 0000000000000000 0000007ffd94b9f0 0000000000463dec 0000007ffd94b9f0
ffc0: 0000007f9e191e1c 0000000000000000 0000000000000004 000000000000001d
ffe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
Call trace:
Exception stack(0xffffffc8742bf900 to 0xffffffc8742bfa30)
f900: ffffff800b3aa000 0000008000000000 ffffffc8742bfad0 ffffff80081eb420
f920: ffffff8000000000 ffffff80081a58ec ffffffc8742bf940 ffffff80081c3ea8
f940: ffffffc8742bf990 ffffff80081a591c ffffffc8742bf970 ffffff8008a1d89c
f960: ffffff8008eb1780 ffffff8008eb1780 ffffffc8742bf990 ffffff80081a59dc
f980: ffffffbf21c4ae00 ffffffbf00000000 ffffffc8742bfa20 ffffff80081a5db4
f9a0: 0000000000000201 ffffff800b3aafff ffffffc87b361788 ffffff8008fd4fff
f9c0: 0000000000000000 ffffff8008097f20 0000000000000000 0000000000003ff0
f9e0: ffffff8008c65000 0000000000000004 ffffffbf21d0e220 000000000000000a
fa00: 00000000ffffffff ffffff8008c65000 0000000000070cc8 000000000000000a
fa20: ffffff8008eb0d28 0000007f9e191e10
[<ffffff80081eb420>] vunmap+0x48/0x50
[<ffffff8008097fb8>] __dma_free+0x98/0xa0
[<ffffff8000b717d4>] tg3_free_consistent+0x14c/0x190 [tg3]
[<ffffff8000b80324>] tg3_stop+0x204/0x238 [tg3]
[<ffffff8000b8aa5c>] tg3_close+0x34/0x98 [tg3]
[<ffffff80088bf44c>] __dev_close_many+0x94/0xe8
[<ffffff80088bf5e4>] __dev_close+0x34/0x50
[<ffffff80088c9d58>] __dev_change_flags+0xa0/0x160
[<ffffff80088c9e4c>] dev_change_flags+0x34/0x70
[<ffffff80089509f8>] devinet_ioctl+0x740/0x808
[<ffffff8008953088>] inet_ioctl+0x140/0x158
[<ffffff80088a1720>] sock_do_ioctl+0x40/0x88
[<ffffff80088a2648>] sock_ioctl+0x238/0x368
[<ffffff800822e9e0>] do_vfs_ioctl+0xb0/0x730
[<ffffff800822f0ec>] SyS_ioctl+0x8c/0xa8
[<ffffff8008083730>] el0_svc_naked+0x24/0x28
Code: f9400bf3 a8c27bfd d65f03c0 d503201f (d4210000)
---[ end trace e214990b7cc445ce ]---
Kernel panic - not syncing: Fatal exception in interrupt
Signed-off-by: Zumeng Chen <zumeng.chen@gmail.com>
---
drivers/net/ethernet/broadcom/tg3.c | 13 ++++++++-----
drivers/net/ethernet/broadcom/tg3.h | 1 +
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 537d571..2621821 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -8723,14 +8723,11 @@ static void tg3_free_consistent(struct tg3 *tp)
tg3_mem_rx_release(tp);
tg3_mem_tx_release(tp);
- /* Protect tg3_get_stats64() from reading freed tp->hw_stats. */
- tg3_full_lock(tp, 0);
if (tp->hw_stats) {
dma_free_coherent(&tp->pdev->dev, sizeof(struct tg3_hw_stats),
tp->hw_stats, tp->stats_mapping);
tp->hw_stats = NULL;
}
- tg3_full_unlock(tp);
}
/*
@@ -9334,6 +9331,7 @@ static int tg3_halt(struct tg3 *tp, int kind, bool silent)
/* And make sure the next sample is new data */
memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
+ tp->hw_stats_flag = false;
}
return err;
@@ -10732,6 +10730,7 @@ static int tg3_reset_hw(struct tg3 *tp, bool reset_phy)
*/
static int tg3_init_hw(struct tg3 *tp, bool reset_phy)
{
+ int retval;
/* Chip may have been just powered on. If so, the boot code may still
* be running initialization. Wait for it to finish to avoid races in
* accessing the hardware.
@@ -10743,7 +10742,11 @@ static int tg3_init_hw(struct tg3 *tp, bool reset_phy)
tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
- return tg3_reset_hw(tp, reset_phy);
+ retval = tg3_reset_hw(tp, reset_phy);
+ if (retval == 0)
+ tp->hw_stats_flag = true;
+
+ return retval;
}
#ifdef CONFIG_TIGON3_HWMON
@@ -14155,7 +14158,7 @@ static void tg3_get_stats64(struct net_device *dev,
struct tg3 *tp = netdev_priv(dev);
spin_lock_bh(&tp->lock);
- if (!tp->hw_stats) {
+ if (!tp->hw_stats || (tp->hw_stats_flag == false)) {
*stats = tp->net_stats_prev;
spin_unlock_bh(&tp->lock);
return;
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 3b5e98e..6727d93 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -3352,6 +3352,7 @@ struct tg3 {
struct pci_dev *pdev_peer;
struct tg3_hw_stats *hw_stats;
+ bool hw_stats_flag;
dma_addr_t stats_mapping;
struct work_struct reset_task;
--
2.9.3
^ permalink raw reply related
* Re: Performance regressions in TCP_STREAM tests in Linux 4.15 (and later)
From: Steven Rostedt @ 2018-04-28 3:11 UTC (permalink / raw)
To: Michael Wenig
Cc: netdev@vger.kernel.org, eric.dumazet@gmail.com, Shilpi Agarwal,
Boon Ang, Darren Hart, Steven Rostedt, Abdul Anshad Azeez
In-Reply-To: <BN3PR0501MB1425A7479873B556E84F0AA1B08D0@BN3PR0501MB1425.namprd05.prod.outlook.com>
We'd like this email archived in netdev list, but since netdev is
notorious for blocking outlook email as spam, it didn't go through. So
I'm replying here to help get it into the archives.
Thanks!
-- Steve
On Fri, 27 Apr 2018 23:05:46 +0000
Michael Wenig <mwenig@vmware.com> wrote:
> As part of VMware's performance testing with the Linux 4.15 kernel,
> we identified CPU cost and throughput regressions when comparing to
> the Linux 4.14 kernel. The impacted test cases are mostly TCP_STREAM
> send tests when using small message sizes. The regressions are
> significant (up 3x) and were tracked down to be a side effect of Eric
> Dumazat's RB tree changes that went into the Linux 4.15 kernel.
> Further investigation showed our use of the TCP_NODELAY flag in
> conjunction with Eric's change caused the regressions to show and
> simply disabling TCP_NODELAY brought performance back to normal.
> Eric's change also resulted into significant improvements in our
> TCP_RR test cases.
>
>
>
> Based on these results, our theory is that Eric's change made the
> system overall faster (reduced latency) but as a side effect less
> aggregation is happening (with TCP_NODELAY) and that results in lower
> throughput. Previously even though TCP_NODELAY was set, system was
> slower and we still got some benefit of aggregation. Aggregation
> helps in better efficiency and higher throughput although it can
> increase the latency. If you are seeing a regression in your
> application throughput after this change, using TCP_NODELAY might
> help bring performance back however that might increase latency.
>
>
>
> As such, we are not asking for a fix but simply want to document for
> others what we have found.
>
>
>
> Michael Wenig
>
> Performance Engineering
>
> VMware, Inc.
>
^ permalink raw reply
* Re: [RFC v3 0/5] virtio: support packed ring
From: Jason Wang @ 2018-04-28 2:45 UTC (permalink / raw)
To: Tiwei Bie; +Cc: Michael S. Tsirkin, netdev, linux-kernel, virtualization, wexu
In-Reply-To: <20180427091234.n6vr3wcnbnqxd3so@debian>
On 2018年04月27日 17:12, Tiwei Bie wrote:
> On Fri, Apr 27, 2018 at 02:17:51PM +0800, Jason Wang wrote:
>> On 2018年04月27日 12:18, Michael S. Tsirkin wrote:
>>> On Fri, Apr 27, 2018 at 11:56:05AM +0800, Jason Wang wrote:
>>>> On 2018年04月25日 13:15, Tiwei Bie wrote:
>>>>> Hello everyone,
>>>>>
>>>>> This RFC implements packed ring support in virtio driver.
>>>>>
>>>>> Some simple functional tests have been done with Jason's
>>>>> packed ring implementation in vhost:
>>>>>
>>>>> https://lkml.org/lkml/2018/4/23/12
>>>>>
>>>>> Both of ping and netperf worked as expected (with EVENT_IDX
>>>>> disabled). But there are below known issues:
>>>>>
>>>>> 1. Reloading the guest driver will break the Tx/Rx;
>>>> Will have a look at this issue.
>>>>
>>>>> 2. Zeroing the flags when detaching a used desc will
>>>>> break the guest -> host path.
>>>> I still think zeroing flags is unnecessary or even a bug. At host, I track
>>>> last observed avail wrap counter and detect avail like (what is suggested in
>>>> the example code in the spec):
>>>>
>>>> static bool desc_is_avail(struct vhost_virtqueue *vq, __virtio16 flags)
>>>> {
>>>> bool avail = flags & cpu_to_vhost16(vq, DESC_AVAIL);
>>>>
>>>> return avail == vq->avail_wrap_counter;
>>>> }
>>>>
>>>> So zeroing wrap can not work with this obviously.
>>>>
>>>> Thanks
>>> I agree. I think what one should do is flip the available bit.
>>>
>> But is this flipping a must?
>>
>> Thanks
> Yeah, that's my question too. It seems to be a requirement
> for driver that, the only change to the desc status that a
> driver can do during running is to mark the desc as avail,
> and any other changes to the desc status are not allowed.
> Similarly, the device can only mark the desc as used, and
> any other changes to the desc status are also not allowed.
> So the question is, are there such requirements?
Looks not, but I think we need clarify this in the spec.
Thanks
>
> Based on below contents in the spec:
>
> """
> Thus VIRTQ_DESC_F_AVAIL and VIRTQ_DESC_F_USED bits are different
> for an available descriptor and equal for a used descriptor.
>
> Note that this observation is mostly useful for sanity-checking
> as these are necessary but not sufficient conditions
> """
>
> It seems that, it's necessary for devices to check whether
> the AVAIL bit and USED bit are different.
>
> Best regards,
> Tiwei Bie
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
^ permalink raw reply
* Re: [PATCH net-next] udp: remove stray export symbol
From: David Miller @ 2018-04-28 2:23 UTC (permalink / raw)
To: willemdebruijn.kernel; +Cc: netdev, willemb
In-Reply-To: <20180427151210.13397-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Fri, 27 Apr 2018 11:12:10 -0400
> From: Willem de Bruijn <willemb@google.com>
>
> UDP GSO needs to export __udp_gso_segment to call it from ipv6.
>
> I accidentally exported static ipv4 function __udp4_gso_segment.
> Remove that EXPORT_SYMBOL_GPL.
>
> Fixes: ee80d1ebe5ba ("udp: add udp gso")
> Signed-off-by: Willem de Bruijn <willemb@google.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net] vhost: Use kzalloc() to allocate vhost_msg_node
From: Jason Wang @ 2018-04-28 2:23 UTC (permalink / raw)
To: Kevin Easton, Michael S. Tsirkin
Cc: kvm, virtualization, netdev, linux-kernel, syzkaller-bugs
In-Reply-To: <20180428015106.GA27738@la.guarana.org>
On 2018年04月28日 09:51, Kevin Easton wrote:
> On Fri, Apr 27, 2018 at 09:07:56PM -0400, Kevin Easton wrote:
>> On Fri, Apr 27, 2018 at 07:05:45PM +0300, Michael S. Tsirkin wrote:
>>> On Fri, Apr 27, 2018 at 11:45:02AM -0400, Kevin Easton wrote:
>>>> The struct vhost_msg within struct vhost_msg_node is copied to userspace,
>>>> so it should be allocated with kzalloc() to ensure all structure padding
>>>> is zeroed.
>>>>
>>>> Signed-off-by: Kevin Easton <kevin@guarana.org>
>>>> Reported-by: syzbot+87cfa083e727a224754b@syzkaller.appspotmail.com
>>> Does it help if a patch naming the padding is applied,
>>> and then we init just the relevant field?
>>> Just curious.
>> No, I don't believe that is sufficient to fix the problem.
> Scratch that, somehow I missed the "..and then we init just the
> relevant field" part, sorry.
>
> There's still the padding after the vhost_iotlb_msg to consider. It's
> named in the union but I don't think that's guaranteed to be initialised
> when the iotlb member of the union is used to initialise things.
>
>> I didn't name the padding in my original patch because I wasn't sure
>> if the padding actually exists on 32 bit architectures?
> This might still be a conce
Yes.
print &((struct vhost_msg *)0)->iotlb
$3 = (struct vhost_iotlb_msg *) 0x4
>
> At the end of the day, zeroing 96 bytes (the full size of vhost_msg_node)
> is pretty quick.
>
> - Kevin
Right, and even if it may be used heavily in the data-path, zeroing is
not the main delay in that path.
Thanks
^ permalink raw reply
* Re: [PATCH net] vhost: Use kzalloc() to allocate vhost_msg_node
From: Kevin Easton @ 2018-04-28 1:51 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Jason Wang, kvm, virtualization, netdev, linux-kernel,
syzkaller-bugs
In-Reply-To: <20180428010756.GA27341@la.guarana.org>
On Fri, Apr 27, 2018 at 09:07:56PM -0400, Kevin Easton wrote:
> On Fri, Apr 27, 2018 at 07:05:45PM +0300, Michael S. Tsirkin wrote:
> > On Fri, Apr 27, 2018 at 11:45:02AM -0400, Kevin Easton wrote:
> > > The struct vhost_msg within struct vhost_msg_node is copied to userspace,
> > > so it should be allocated with kzalloc() to ensure all structure padding
> > > is zeroed.
> > >
> > > Signed-off-by: Kevin Easton <kevin@guarana.org>
> > > Reported-by: syzbot+87cfa083e727a224754b@syzkaller.appspotmail.com
> >
> > Does it help if a patch naming the padding is applied,
> > and then we init just the relevant field?
> > Just curious.
>
> No, I don't believe that is sufficient to fix the problem.
Scratch that, somehow I missed the "..and then we init just the
relevant field" part, sorry.
There's still the padding after the vhost_iotlb_msg to consider. It's
named in the union but I don't think that's guaranteed to be initialised
when the iotlb member of the union is used to initialise things.
> I didn't name the padding in my original patch because I wasn't sure
> if the padding actually exists on 32 bit architectures?
This might still be a concern, too?
At the end of the day, zeroing 96 bytes (the full size of vhost_msg_node)
is pretty quick.
- Kevin
^ permalink raw reply
* Re: [PATCH 2/2] bpf: btf: remove a couple conditions
From: Martin KaFai Lau @ 2018-04-28 1:27 UTC (permalink / raw)
To: Dan Carpenter
Cc: Alexei Starovoitov, Daniel Borkmann, netdev, linux-kernel,
kernel-janitors
In-Reply-To: <20180427212648.zskc5bk2hunkwvsg@kafai-mbp.dhcp.thefacebook.com>
On Fri, Apr 27, 2018 at 02:26:50PM -0700, Martin KaFai Lau wrote:
> On Fri, Apr 27, 2018 at 11:31:36PM +0300, Dan Carpenter wrote:
> > On Fri, Apr 27, 2018 at 10:21:17PM +0200, Daniel Borkmann wrote:
> > > On 04/27/2018 09:39 PM, Dan Carpenter wrote:
> > > > On Fri, Apr 27, 2018 at 10:55:46AM -0700, Martin KaFai Lau wrote:
> > > >> On Fri, Apr 27, 2018 at 10:20:25AM -0700, Martin KaFai Lau wrote:
> > > >>> On Fri, Apr 27, 2018 at 05:04:59PM +0300, Dan Carpenter wrote:
> > > >>>> We know "err" is zero so we can remove these and pull the code in one
> > > >>>> indent level.
> > > >>>>
> > > >>>> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> > > >>> Thanks for the simplification!
> > > >>>
> > > >>> Acked-by: Martin KaFai Lau <kafai@fb.com>
> > > >> btw, it should be for bpf-next. Please tag the subject with bpf-next when
> > > >> you respin. Thanks!
> > >
> > > Dan, thanks a lot for your fixes! Please respin with addressing Martin's
> > > feedback when you get a chance.
> > >
> >
> > My understanding is that he'd prefer we just ignore the static checker
> > warning since it's a false positive.
> Right, I think patch 1 is not needed. I would prefer to use a comment
> in those cases.
>
> > Should I instead initialize the
> > size to zero or something just to silence it?
After another thought, I think init size to zero is
fine which is less intrusive.
Thanks!
Martin
> >
> > regards,
> > dan carpenter
> >
^ permalink raw reply
* Re: [PATCH net] vhost: Use kzalloc() to allocate vhost_msg_node
From: Kevin Easton @ 2018-04-28 1:07 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Jason Wang, kvm, virtualization, netdev, linux-kernel,
syzkaller-bugs
In-Reply-To: <20180427185501-mutt-send-email-mst@kernel.org>
On Fri, Apr 27, 2018 at 07:05:45PM +0300, Michael S. Tsirkin wrote:
> On Fri, Apr 27, 2018 at 11:45:02AM -0400, Kevin Easton wrote:
> > The struct vhost_msg within struct vhost_msg_node is copied to userspace,
> > so it should be allocated with kzalloc() to ensure all structure padding
> > is zeroed.
> >
> > Signed-off-by: Kevin Easton <kevin@guarana.org>
> > Reported-by: syzbot+87cfa083e727a224754b@syzkaller.appspotmail.com
>
> Does it help if a patch naming the padding is applied,
> and then we init just the relevant field?
> Just curious.
No, I don't believe that is sufficient to fix the problem.
The structure is allocated by kmalloc(), then individual fields are
initialised. The named adding would be forced to be initialised if
it were initialised with a struct initialiser, but that's not the case.
The compiler is free to leave padding0 with whatever junk kmalloc()
left there.
Having said that, naming the padding *does* help - technically, the
compiler is allowed to put whatever it likes in the padding every time
you modify the struct. It really needs both.
I didn't name the padding in my original patch because I wasn't sure
if the padding actually exists on 32 bit architectures?
- Kevin
^ permalink raw reply
* Re: Suggestions on iterating eBPF maps
From: Alexei Starovoitov @ 2018-04-28 1:04 UTC (permalink / raw)
To: Chenbo Feng; +Cc: netdev, Daniel Borkmann, Lorenzo Colitti, Joel Fernandes
In-Reply-To: <CAMOXUJmAH56sDd7XRG1E1yJFgHCyQL79uVf-nVPT=yp4uZsBhQ@mail.gmail.com>
On Fri, Apr 27, 2018 at 06:33:56PM +0000, Chenbo Feng wrote:
> resend with plain text
>
> On Fri, Apr 27, 2018 at 11:22 AM Chenbo Feng <fengc@google.com> wrote:
>
> > Hi net-next,
>
> > When doing the eBPF tools user-space development I noticed that the map
> iterating process in user-space have some little flaws. If we want to dump
> the whole map. The only way now I know is to use a null key to start the
> iteration and keep calling bpf_get_next_key and bpf_look_up_elem for each
> new key value pair until we reach the end of the map. I noticed the
> bpftools recently added used the similar approach.
>
> > The overhead of repeating syscalls is acceptable, but the race problem
> come with this iteration process is a little annoying. If the current key
> we are using get deleted before we do the syscall to get the next key . The
> next key returned will start from the beginning of the map again and some
> entry will be dumped again depending on the position of the key deleted. If
> the racing problem is within the same userspace process, it can be easily
> fixed by adding some read/write locks. However, if multiple processes is
> reading the map through pinned fd while there is one process is editing the
> map entry or the kernel program is deleting entries, it become harder to
> get a consistent and correct map dump.
>
> > We are wondering if there is already implementation we didn't notice in
> mainline kernel that help improved this iteration process and addressed the
> racing problem mentioned above? If not, what can be down to address the
> issue above. One thing we came up with is to use a single entry bpf map as
> a across process lock to prevent multiple userspace process to read/write
> other maps at the same time. But I don't know how safe this solution is
> since there will still be a race to read the lock map value and setup the
> lock.
to avoid seeing duplicate keys due to parallel removal one can walk all
keys with get_next first. Remove duplicate keys and then lookup their values.
By that time some elements could be removed and lookups will be failing.
Another approach could be to use map-in-map and have almost atomic
replace of the whole map with new potentially empty map. The prog
can continue using the new map, while user space walks no longer
accessed old map.
yet another approach would be to introduce a knob to the prog
that user space controls and make program obey that knob.
When it's on the prog won't be deleting/updating maps.
^ permalink raw reply
* Re: [Cake] [PATCH iproute2-next v7] Add support for cake qdisc
From: Stephen Hemminger @ 2018-04-28 1:03 UTC (permalink / raw)
To: Toke Høiland-Jørgensen; +Cc: netdev, cake
In-Reply-To: <20180427195720.9380-1-toke@toke.dk>
On Fri, 27 Apr 2018 21:57:20 +0200
Toke Høiland-Jørgensen <toke@toke.dk> wrote:
> sch_cake is intended to squeeze the most bandwidth and latency out of even
> the slowest ISP links and routers, while presenting an API simple enough
> that even an ISP can configure it.
>
> Example of use on a cable ISP uplink:
>
> tc qdisc add dev eth0 cake bandwidth 20Mbit nat docsis ack-filter
>
> To shape a cable download link (ifb and tc-mirred setup elided)
>
> tc qdisc add dev ifb0 cake bandwidth 200mbit nat docsis ingress wash besteffort
>
> Cake is filled with:
>
> * A hybrid Codel/Blue AQM algorithm, "Cobalt", tied to an FQ_Codel
> derived Flow Queuing system, which autoconfigures based on the bandwidth.
> * A novel "triple-isolate" mode (the default) which balances per-host
> and per-flow FQ even through NAT.
> * An deficit based shaper, that can also be used in an unlimited mode.
> * 8 way set associative hashing to reduce flow collisions to a minimum.
> * A reasonable interpretation of various diffserv latency/loss tradeoffs.
> * Support for zeroing diffserv markings for entering and exiting traffic.
> * Support for interacting well with Docsis 3.0 shaper framing.
> * Support for DSL framing types and shapers.
> * Support for ack filtering.
> * Extensive statistics for measuring, loss, ecn markings, latency variation.
>
> Various versions baking have been available as an out of tree build for
> kernel versions going back to 3.10, as the embedded router world has been
> running a few years behind mainline Linux. A stable version has been
> generally available on lede-17.01 and later.
>
> sch_cake replaces a combination of iptables, tc filter, htb and fq_codel
> in the sqm-scripts, with sane defaults and vastly simpler configuration.
>
> Cake's principal author is Jonathan Morton, with contributions from
> Kevin Darbyshire-Bryant, Toke Høiland-Jørgensen, Sebastian Moeller,
> Ryan Mounce, Guido Sarducci, Dean Scarff, Nils Andreas Svee, Dave Täht,
> and Loganaden Velvindron.
>
> Testing from Pete Heist, Georgios Amanakis, and the many other members of
> the cake@lists.bufferbloat.net mailing list.
>
> Signed-off-by: Dave Taht <dave.taht@gmail.com>
> Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
> ---
> Changelog:
> v7:
> - Move the target/interval presets to a table and check that only
> one is passed.
>
> v6:
> - Identical to v5 because apparently I don't git so well... :/
>
> v5:
> - Print the SPLIT_GSO flag
> - Switch to print_u64() for JSON output
> - Fix a format string for mpu option output
>
> v4:
> - Switch stats parsing to use nested netlink attributes
> - Tweaks to JSON stats output keys
>
> v3:
> - Remove accidentally included test flag
>
> v2:
> - Updated netlink config ABI
> - Remove diffserv-llt mode
> - Various tweaks and clean-ups of stats output
> man/man8/tc-cake.8 | 632 ++++++++++++++++++++++++++++++++++++++
> man/man8/tc.8 | 1 +
> tc/Makefile | 1 +
> tc/q_cake.c | 748 +++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 1382 insertions(+)
> create mode 100644 man/man8/tc-cake.8
> create mode 100644 tc/q_cake.c
Looks good to me, when cake makes it into net-next.
^ permalink raw reply
* Re: [PATCH v4] bpf, x86_32: add eBPF JIT compiler for ia32
From: Daniel Borkmann @ 2018-04-28 0:47 UTC (permalink / raw)
To: Wang YanQing, ast, illusionist.neo, tglx, mingo, hpa, davem, x86,
netdev, linux-kernel
In-Reply-To: <20180426101257.GA29387@udknight>
On 04/26/2018 12:12 PM, Wang YanQing wrote:
[...]
> +/* encode 'dst_reg' and 'src_reg' registers into x86_32 opcode 'byte' */
> +static u8 add_2reg(u8 byte, u32 dst_reg, u32 src_reg)
> +{
> + return byte + dst_reg + (src_reg << 3);
> +}
> +
> +static void jit_fill_hole(void *area, unsigned int size)
> +{
> + /* fill whole space with int3 instructions */
> + memset(area, 0xcc, size);
> +}
> +
> +/* Checks whether BPF register is on scratch stack space or not. */
> +static inline bool is_on_stack(u8 bpf_reg)
> +{
> + static u8 stack_regs[] = {BPF_REG_AX};
Nit: you call this stack_regs here ...
> + int i, reg_len = sizeof(stack_regs);
> +
> + for (i = 0 ; i < reg_len ; i++) {
> + if (bpf_reg == stack_regs[i])
> + return false;
... but [BPF_REG_AX] = {IA32_ESI, IA32_EDI} is the only one
that is not on stack?
> + }
> + return true;
> +}
> +
> +static inline void emit_ia32_mov_i(const u8 dst, const u32 val, bool dstk,
> + u8 **pprog)
> +{
> + u8 *prog = *pprog;
> + int cnt = 0;
> +
> + if (dstk) {
> + if (val == 0) {
> + /* xor eax,eax */
> + EMIT2(0x33, add_2reg(0xC0, IA32_EAX, IA32_EAX));
> + /* mov dword ptr [ebp+off],eax */
> + EMIT3(0x89, add_2reg(0x40, IA32_EBP, IA32_EAX),
> + STACK_VAR(dst));
> + } else {
> + EMIT3_off32(0xC7, add_1reg(0x40, IA32_EBP),
> + STACK_VAR(dst), val);
> + }
> + } else {
> + if (val == 0)
> + EMIT2(0x33, add_2reg(0xC0, dst, dst));
> + else
> + EMIT2_off32(0xC7, add_1reg(0xC0, dst),
> + val);
> + }
> + *pprog = prog;
> +}
> +
[...]
> + if (is_imm8(jmp_offset)) {
> + EMIT2(jmp_cond, jmp_offset);
> + } else if (is_simm32(jmp_offset)) {
> + EMIT2_off32(0x0F, jmp_cond + 0x10, jmp_offset);
> + } else {
> + pr_err("cond_jmp gen bug %llx\n", jmp_offset);
> + return -EFAULT;
> + }
> +
> + break;
> + }
> + case BPF_JMP | BPF_JA:
> + jmp_offset = addrs[i + insn->off] - addrs[i];
> + if (!jmp_offset)
> + /* optimize out nop jumps */
> + break;
Needs same fix as in x86-64 JIT in 1612a981b766 ("bpf, x64: fix JIT emission
for dead code").
> +emit_jmp:
> + if (is_imm8(jmp_offset)) {
> + EMIT2(0xEB, jmp_offset);
> + } else if (is_simm32(jmp_offset)) {
> + EMIT1_off32(0xE9, jmp_offset);
> + } else {
> + pr_err("jmp gen bug %llx\n", jmp_offset);
> + return -EFAULT;
> + }
> + break;
^ permalink raw reply
* Re: [PATCH v7 net-next 4/4] netvsc: refactor notifier/event handling code to use the failover framework
From: Siwei Liu @ 2018-04-28 0:43 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Stephen Hemminger, Jiri Pirko, Sridhar Samudrala, David Miller,
Netdev, virtualization, virtio-dev, Brandeburg, Jesse,
Alexander Duyck, Jakub Kicinski, Jason Wang
In-Reply-To: <20180427012530-mutt-send-email-mst@kernel.org>
On Thu, Apr 26, 2018 at 4:42 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Thu, Apr 26, 2018 at 03:14:46PM -0700, Siwei Liu wrote:
>> On Wed, Apr 25, 2018 at 7:28 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> > On Wed, Apr 25, 2018 at 03:57:57PM -0700, Siwei Liu wrote:
>> >> On Wed, Apr 25, 2018 at 3:22 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> >> > On Wed, Apr 25, 2018 at 02:38:57PM -0700, Siwei Liu wrote:
>> >> >> On Mon, Apr 23, 2018 at 1:06 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> >> >> > On Mon, Apr 23, 2018 at 12:44:39PM -0700, Siwei Liu wrote:
>> >> >> >> On Mon, Apr 23, 2018 at 10:56 AM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> >> >> >> > On Mon, Apr 23, 2018 at 10:44:40AM -0700, Stephen Hemminger wrote:
>> >> >> >> >> On Mon, 23 Apr 2018 20:24:56 +0300
>> >> >> >> >> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>> >> >> >> >>
>> >> >> >> >> > On Mon, Apr 23, 2018 at 10:04:06AM -0700, Stephen Hemminger wrote:
>> >> >> >> >> > > > >
>> >> >> >> >> > > > >I will NAK patches to change to common code for netvsc especially the
>> >> >> >> >> > > > >three device model. MS worked hard with distro vendors to support transparent
>> >> >> >> >> > > > >mode, ans we really can't have a new model; or do backport.
>> >> >> >> >> > > > >
>> >> >> >> >> > > > >Plus, DPDK is now dependent on existing model.
>> >> >> >> >> > > >
>> >> >> >> >> > > > Sorry, but nobody here cares about dpdk or other similar oddities.
>> >> >> >> >> > >
>> >> >> >> >> > > The network device model is a userspace API, and DPDK is a userspace application.
>> >> >> >> >> >
>> >> >> >> >> > It is userspace but are you sure dpdk is actually poking at netdevs?
>> >> >> >> >> > AFAIK it's normally banging device registers directly.
>> >> >> >> >> >
>> >> >> >> >> > > You can't go breaking userspace even if you don't like the application.
>> >> >> >> >> >
>> >> >> >> >> > Could you please explain how is the proposed patchset breaking
>> >> >> >> >> > userspace? Ignoring DPDK for now, I don't think it changes the userspace
>> >> >> >> >> > API at all.
>> >> >> >> >> >
>> >> >> >> >>
>> >> >> >> >> The DPDK has a device driver vdev_netvsc which scans the Linux network devices
>> >> >> >> >> to look for Linux netvsc device and the paired VF device and setup the
>> >> >> >> >> DPDK environment. This setup creates a DPDK failsafe (bondingish) instance
>> >> >> >> >> and sets up TAP support over the Linux netvsc device as well as the Mellanox
>> >> >> >> >> VF device.
>> >> >> >> >>
>> >> >> >> >> So it depends on existing 2 device model. You can't go to a 3 device model
>> >> >> >> >> or start hiding devices from userspace.
>> >> >> >> >
>> >> >> >> > Okay so how does the existing patch break that? IIUC does not go to
>> >> >> >> > a 3 device model since netvsc calls failover_register directly.
>> >> >> >> >
>> >> >> >> >> Also, I am working on associating netvsc and VF device based on serial number
>> >> >> >> >> rather than MAC address. The serial number is how Windows works now, and it makes
>> >> >> >> >> sense for Linux and Windows to use the same mechanism if possible.
>> >> >> >> >
>> >> >> >> > Maybe we should support same for virtio ...
>> >> >> >> > Which serial do you mean? From vpd?
>> >> >> >> >
>> >> >> >> > I guess you will want to keep supporting MAC for old hypervisors?
>> >> >> >> >
>> >> >> >> > It all seems like a reasonable thing to support in the generic core.
>> >> >> >>
>> >> >> >> That's the reason why I chose explicit identifier rather than rely on
>> >> >> >> MAC address to bind/pair a device. MAC address can change. Even if it
>> >> >> >> can't, malicious guest user can fake MAC address to skip binding.
>> >> >> >>
>> >> >> >> -Siwei
>> >> >> >
>> >> >> > Address should be sampled at device creation to prevent this
>> >> >> > kind of hack. Not that it buys the malicious user much:
>> >> >> > if you can poke at MAC addresses you probably already can
>> >> >> > break networking.
>> >> >>
>> >> >> I don't understand why poking at MAC address may potentially break
>> >> >> networking.
>> >> >
>> >> > Set a MAC address to match another device on the same LAN,
>> >> > packets will stop reaching that MAC.
>> >>
>> >> What I meant was guest users may create a virtual link, say veth that
>> >> has exactly the same MAC address as that for the VF, which can easily
>> >> get around of the binding procedure.
>> >
>> > This patchset limits binding to PCI devices so it won't be affected
>> > by any hacks around virtual devices.
>>
>> Wait, I vaguely recall you seemed to like to generalize this feature
>> to non-PCI device.
>
> It's purely a layering thing. It is cleaner not to have PCI specific
> data in the device-specific transport-independent section of the virtio
> spec.
>
OK. So looks like you think it's okay to include PCI specific concept
but not the data? Like a feature indicating the virtio device is
behind a (external) PCI bridge, and perhaps also includes the data
present in the PCI bridge/function's capability?
Sorry for asking tough questions. I still need to understand and
digest the boundary of this layering thing.
>
>> But now you're saying it should stick to PCI. It's
>> not that I'm reluctant with sticking to PCI. The fact is that I don't
>> think we can go with implementation until the semantics of the
>> so-called _F_STANDBY feature can be clearly defined into the spec.
>> Previously the boundary of using MAC address as the identifier for
>> bonding was quite confusing to me. And now PCI adds to the matrix.
>
> PCI is simply one way to exclude software NICs. It's not the most
> elegant one, but it will cover many setups. We can add more types, but
> we do want to exclude software devices since these have
> not been supplied by the hypervisor.
I'm afraid it's a loose end. The real thing is there's no way to
indicate VF or passthrough device on Linux, even true on some other
OS. There's no such flag exists yet. Even the emulated e1000 and
rltk8139 device looks the same as PCI device. And as part of the
requirements of being a spec, the behaviour and expectation need to be
precisely described for implementations to follow. There's no point to
assume just one OS will implement this feature so it needs to depend
on specifics of that OS.
>
>> However it still does not gurantee uniqueness I think. It's almost
>> incorrect of choosing MAC address as the ID in the beginning since
>> that has the implication of breaking existing configs.
>
> IMO there's no chance it will break any existing config since
> no existing config sets _F_STANDBY.
True, but it breaks people's expectation that it has to rely on MAC
address being unique when turning it on for live migration, and once
it happens some configs with same MAC address would break (for e.g.
bonding setup can have it for cross subnet failover and site
replication). Unless this limitation is clearly documented in the spec
I don't think people will notice that until it breaks.
>
>> I don't think
>> libvirt or QEMU today retricts the MAC address to be unique per VM
>> instance. Neither the virtio spec mentions that.
>
> You really don't have to.
>
>> In addition, it's difficult to fake PCI device on Linux does not mean
>> the same applies to other OSes that is going to implement this VirtIO
>> feature. It's a fragile assumption IMHO.
>
> What an OS does internally is its own business.
>
> What we are telling the guest here is simply that the virtio NIC is
> actually the same device as some other NIC. At this point we do not
> specify this other NIC in any way. So how do you find it? Well it has
> to have the same MAC clearly.
Well this condition is absolutely neccessary but not sufficient. There
should be some other unique key to help find the NIC as the MAC cannot
be unique as what people generally thought it be.
>
> You point out that there could be multiple NICs with the same
> MAC in theory. It's a broken config generally but since it
> kind of works in some setups maybe it's worth supporting.
> If so we can look for ways to make the matching more specific by e.g.
> adding more flags but I see that as a separate issue,
> and pretty narrow in scope.
Well there are precedents that people thought something broken but
soon find out users already depends on the "broken" behaviour.
Nowadays widely use of virtualization technology make MAC address
duplication really cheap. It's not that uncommon as one might think.
Unless the expectation can be explicitly documented in the spec, I
don't feel it's something users can easily infer from what the new
feature should target - live migration.
>
>> >
>> >> There's no explicit flag to
>> >> identify a VF or pass-through device AFAIK. And sometimes this happens
>> >> maybe due to user misconfiguring the link. This process should be
>> >> hardened to avoid from any potential configuration errors.
>> >
>> > They are still PCI devices though.
>> >
>> >> >
>> >> >> Unlike VF, passthrough PCI endpoint device has its freedom
>> >> >> to change the MAC address. Even on a VF setup it's not neccessarily
>> >> >> always safe to assume the VF's MAC address cannot or shouldn't be
>> >> >> changed. That depends on the specific need whether the host admin
>> >> >> wants to restrict guest from changing the MAC address, although in
>> >> >> most cases it's true.
>> >> >>
>> >> >> I understand we can use the perm_addr to distinguish. But as said,
>> >> >> this will pose limitation of flexible configuration where one can
>> >> >> assign VFs with identical MAC address at all while each VF belongs to
>> >> >> different PF and/or different subnet for e.g. load balancing.
>> >> >> And
>> >> >> furthermore, the QEMU device model never uses MAC address to be
>> >> >> interpreted as an identifier, which requires to be unique per VM
>> >> >> instance. Why we're introducing this inconsistency?
>> >> >>
>> >> >> -Siwei
>> >> >
>> >> > Because it addresses most of the issues and is simple. That's already
>> >> > much better than what we have now which is nothing unless guest
>> >> > configures things manually.
>> >>
>> >> Did you see my QEMU patch for using BDF as the grouping identifier?
>> >
>> > Yes. And I don't think it can work because bus numbers are
>> > guest specified.
>>
>> I know it's not ideal but perhaps its the best one can do in the KVM
>> world without adding complex config e.g. PCI bridge.
>
> KVM is just a VMX/SVM driver. I think you mean QEMU. And well -
> "best one can do" is a high bar to clear.
>
>
Glad you'd have to admit that there's no better way *without
introducing complex PCI bridge setup* in the KVM, oops, QEMU without
KVM? err, QEMU with KVM world.
>> Even if bus
>> number is guest specified, it's readily available in the guest and
>> recognizable by any OS, while on the QEMU configuration users specify
>> an id instead of the bus number. Unlike Hyper-V PCI bus, I don't think
>> there exists a para-virtual PCI bus in QEMU backend to expose VPD
>> capability to a passthrough device.
>
> We can always add more interfaces if we need them. But let's be clear
> that we are adding an interface and what are we trying to fix by doing
> it. Let's not mix it as part of the failover discussion.
I'm sorry, I don't understand why this should not be part of the
failover discussion.
There's a lot of ambiguity about the semantics and the expectation of
the _F_STANDBY feature, and that should be recorded in virtio-dev. If
you think we should run it with a different thread, I can definitely
fork a new thread to continue.
As you may wonder, the other aspects unclear to me now are:
- does this feature imply the device model already? The 3-netdev?
- should clear the feature bit upon unsuccessful creation of the
failover interface or failure to enslave the VF?
- does the feature bit indicate migratability status for the
corresponding VF/PT device?
- does the feature expect automatic bonding by default or always?
- does the guest user have the freedom to disable/re-enable the
automatic bonding? such that they can use raw VF for DPDK or RDMA
after the migration
- ...
I hope the answer won't just be to look at what the current
implementation is doing. The discussion will be helpful, at least not
harmful, for people to understand the intention and definition
clearly, since live migration itself is just too complicated.
>
>> >
>> >> And there can be others like what you suggested, but the point is that
>> >> it's requried to support explicit grouping mechanism from day one,
>> >> before the backup property cast into stones.
>> >
>> > Let's start with addressing simple configs with just two NICs.
>> >
>> > Down the road I can see possible extensions that can work: for example,
>> > require that devices are on the same pci bridge. Or we could even make
>> > the virtio device actually include a pci bridge (as part of same
>> > or a child function), the PT would have to be
>> > behind it.
>> >
>> > As long as we are not breaking anything, adding more flags to fix
>> > non-working configurations is always fair game.
>>
>> While it may work, the PCI bridge has NUMA and IOMMU implications that
>> would restrict the current flexibility to group devices.
>
> It's interesting you should mention that.
>
> If you want to be flexible in placing the primary device WRT NUMA and
> IOMMU, and given that both IOMMU and NUMA are keyed by the bus address,
> then doesn't this completely break the idea of passing
> the bus address to the guest?
I'm confused. Isn't the NUMA and IOMMU disposition host admin should
explicitly define? In that case it's assumed that s/he understand the
implication and the bus address doesn't restrict the host admin from
placing the device according to the NUMA or IOMMU
consideration/constrait.
>
>> I'm not sure
>> if vIOMMU would have to be introduced inadvertently for
>> isolation/protection of devices under the PCI bridge which may cause
>> negative performance impact on the VF.
>
> No idea how do you introduce an IOMMU inadvertently.
If the virtio has to be behind a different bridge thus IOMMU domain
than that for VF (which does not actually need a guest IOMMU) then
your former proposal of grouping them *under the same bridge* would
come across hurtles.
>
>> >
>> >> This is orthogonal to
>> >> device model being proposed, be it 1-netdev or not. Delaying it would
>> >> just mean support and compatibility burden, appearing more like a
>> >> design flaw rather than a feature to add later on.
>> >
>> > Well it's mostly myself who gets to support it, and I see the device
>> > model as much more fundamental as userspace will come to depend
>> > on it. So I'm not too worried, let's take this one step at a time.
>> >
>> >> >
>> >> > I think ideally the infrastructure should suppport flexible matching of
>> >> > NICs - netvsc is already reported to be moving to some kind of serial
>> >> > address.
>> >> >
>> >> As Stephen said, Hyper-V supports the serial UUID thing from day-one.
>> >> It's just the Linux netvsc guest driver itself does not leverage that
>> >> ID from the very beginging.
>> >>
>> >> Regards,
>> >> -Siwei
>> >
>> > We could add something like this, too. For example,
>> > we could add a virtual VPD capability with a UUID.
>>
>> I'm not an expert on that and wonder how you could do this (add a
>> virtual VPD capability with a UUID to passthrough device) with
>> existing QEMU emulation model and native PCI bus.
>
>
> I think I see an elegant way to do that.
>
> You could put it in the port where you want to stick you PT device.
>
> Here's how it could work then:
>
>
> - standby virtio device is tied to a pci bridge.
>
> Tied how? Well it could be
> - behind this bridge
An external PCI bridge? This gets back to the first question I ask.
It's interesting a virtio feature should reference an externel object
which seems more like a layering problem at least to me.
> - include a bridge internally
This internal one being a native PCI bridge or VirtIO PCI bridge? I'm
almost cerntain it should be the latter down the road. That determines
where the VPD or SN capability should reside.
> - have the bridge as a PCI function
> - include a bridge and the bridge as a PCI function
> - have a VPD or serial capability with same UUID as the bridge
>
> - primary passthrough device is placed behind a bridge
> *with the same ID*
>
> - either simply behind the same bridge
> - or behind another bridge with the same UUID.
>
Good. Decouple the concept of grouping to rely on same PCI bridge, and
another bridge with same UUID seems more flexible and promissing.
>
> The treatment could also be limited just to bridges which have a
> specific vendor/device id (maybe a good idea), or in any other arbitrary
> way.
I'd think anway VirtIO spec revision is unavoidable if you have to
involve PCI bridge. Not so complicated?
Regards,
-Siwei
>
>
>
>
>> >
>> > Do you know how exactly does hyperv pass the UUID for NICs?
>>
>> Stephen might know it more and can correct me. But my personal
>> interpretation is that the SN is a host generated 32 bit sequence
>> number which is unique per VM instance and gets propogated to guest
>> via the para-virtual Hyper-V PCI bus.
>>
>> Regards,
>> -Siwei
>
> Ah, so it's a Hyper-V thing.
>
>
>
>
>> >
>> >> >
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >>
>> >> >> >> >
>> >> >> >> > --
>> >> >> >> > MST
^ permalink raw reply
* [PATCH ethtool 2/2] ethtool: Add support for PHY test modes
From: Florian Fainelli @ 2018-04-28 0:32 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Russell King, open list, davem,
cphealy, nikita.yoush, vivien.didelot, Nisar.Sayed,
UNGLinuxDriver
In-Reply-To: <20180428003237.1536-1-f.fainelli@gmail.com>
Add two new commands:
--get-phy-tests which allows fetching supported test modes by a given
network device's PHY interface
--set-phy-test which allows entering one of the modes listed before and
pass an eventual set of test specific data
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
ethtool.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/ethtool.c b/ethtool.c
index 3289e0f6e8ec..f02cd3560197 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4854,6 +4854,118 @@ static int do_reset(struct cmd_context *ctx)
return 0;
}
+static int do_gphytest(struct cmd_context *ctx)
+{
+ struct ethtool_gstrings *strings;
+ struct ethtool_phy_test test;
+ unsigned int i;
+ int max_len = 0, cur_len, rc;
+
+ if (ctx->argc != 0)
+ exit_bad_args();
+
+ strings = get_stringset(ctx, ETH_SS_PHY_TESTS, 0, 1);
+ if (!strings) {
+ perror("Cannot get PHY tests strings");
+ return 1;
+ }
+ if (strings->len == 0) {
+ fprintf(stderr, "No PHY tests defined\n");
+ rc = 1;
+ goto err;
+ }
+
+ /* Find longest string and align all strings accordingly */
+ for (i = 0; i < strings->len; i++) {
+ cur_len = strlen((const char*)strings->data +
+ i * ETH_GSTRING_LEN);
+ if (cur_len > max_len)
+ max_len = cur_len;
+ }
+
+ printf("PHY tests %s:\n", ctx->devname);
+ for (i = 0; i < strings->len; i++) {
+ memset(&test, 0, sizeof(test));
+ test.cmd = ETHTOOL_GPHYTEST;
+ test.mode = i;
+
+ rc = send_ioctl(ctx, &test);
+ if (rc < 0)
+ continue;
+
+ fprintf(stdout, " %.*s (Test data: %s)\n",
+ max_len,
+ (const char *)strings->data + i * ETH_GSTRING_LEN,
+ test.len ? "Yes" : "No");
+ }
+
+ rc = 0;
+
+err:
+ free(strings);
+ return rc;
+}
+
+static int do_sphytest(struct cmd_context *ctx)
+{
+ struct ethtool_gstrings *strings;
+ struct ethtool_phy_test gtest;
+ struct ethtool_phy_test *stest;
+ unsigned int i;
+ int rc;
+
+ if (ctx->argc < 1)
+ exit_bad_args();
+
+ strings = get_stringset(ctx, ETH_SS_PHY_TESTS, 0, 1);
+ if (!strings) {
+ perror("Cannot get PHY test modes");
+ return 1;
+ }
+
+ if (strings->len == 0) {
+ fprintf(stderr, "No PHY tests defined\n");
+ rc = 1;
+ goto err;
+ }
+
+ for (i = 0; i < strings->len; i++) {
+ if (!strcmp(ctx->argp[0],
+ (const char *)strings->data + i * ETH_GSTRING_LEN))
+ break;
+ }
+
+ if (i == strings->len)
+ exit_bad_args();
+
+ memset(>est, 0, sizeof(gtest));
+ gtest.cmd = ETHTOOL_GPHYTEST;
+ gtest.mode = i;
+ rc = send_ioctl(ctx, >est);
+ if (rc < 0) {
+ rc = 1;
+ goto err;
+ }
+
+ stest = calloc(1, sizeof(*stest) + gtest.len);
+ if (!stest) {
+ perror("Unable to allocate memory");
+ rc = 1;
+ goto err;
+ }
+
+ stest->cmd = ETHTOOL_SPHYTEST;
+ stest->len = gtest.len;
+ stest->mode = i;
+
+ rc = send_ioctl(ctx, stest);
+ free(stest);
+err:
+ free(strings);
+ return rc;
+}
+
+
static int parse_named_bool(struct cmd_context *ctx, const char *name, u8 *on)
{
if (ctx->argc < 2)
@@ -5223,6 +5335,9 @@ static const struct option {
{ "--show-fec", 1, do_gfec, "Show FEC settings"},
{ "--set-fec", 1, do_sfec, "Set FEC settings",
" [ encoding auto|off|rs|baser ]\n"},
+ { "--get-phy-tests", 1, do_gphytest,"Get PHY test mode(s)" },
+ { "--set-phy-test", 1, do_sphytest, "Set PHY test mode",
+ " [ test options ]\n" },
{ "-h|--help", 0, show_usage, "Show this help" },
{ "--version", 0, do_version, "Show version number" },
{}
--
2.14.1
^ permalink raw reply related
* [PATCH ethtool 1/2] ethtool-copy.h: Sync with net-next
From: Florian Fainelli @ 2018-04-28 0:32 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Russell King, open list, davem,
cphealy, nikita.yoush, vivien.didelot, Nisar.Sayed,
UNGLinuxDriver
In-Reply-To: <20180428003237.1536-1-f.fainelli@gmail.com>
This brings support for PHY test modes (not accepted yet)
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
ethtool-copy.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/ethtool-copy.h b/ethtool-copy.h
index 8cc61e9ab40b..42fb94129da5 100644
--- a/ethtool-copy.h
+++ b/ethtool-copy.h
@@ -572,6 +572,7 @@ enum ethtool_stringset {
ETH_SS_TUNABLES,
ETH_SS_PHY_STATS,
ETH_SS_PHY_TUNABLES,
+ ETH_SS_PHY_TESTS,
};
/**
@@ -1296,6 +1297,25 @@ enum ethtool_fec_config_bits {
#define ETHTOOL_FEC_RS (1 << ETHTOOL_FEC_RS_BIT)
#define ETHTOOL_FEC_BASER (1 << ETHTOOL_FEC_BASER_BIT)
+/**
+ * struct ethtool_phy_test - Ethernet PHY test mode
+ * @cmd: Command number = %ETHTOOL_GPHYTEST or %ETHTOOL_SPHYTEST
+ * @flags: A bitmask of flags from &enum ethtool_test_flags. Some
+ * flags may be set by the user on entry; others may be set by
+ * the driver on return.
+ * @mode: PHY test mode to enter. The index should be a valid test mode
+ * obtained through ethtool_get_strings with %ETH_SS_PHY_TESTS
+ * @len: The length of the test specific array @data
+ * @data: Array of test specific results to be interpreted with @mode
+ */
+struct ethtool_phy_test {
+ __u32 cmd;
+ __u32 flags;
+ __u32 mode;
+ __u32 len;
+ __u8 data[0];
+};
+
/* CMDs currently supported */
#define ETHTOOL_GSET 0x00000001 /* DEPRECATED, Get settings.
* Please use ETHTOOL_GLINKSETTINGS
@@ -1391,6 +1411,9 @@ enum ethtool_fec_config_bits {
#define ETHTOOL_GFECPARAM 0x00000050 /* Get FEC settings */
#define ETHTOOL_SFECPARAM 0x00000051 /* Set FEC settings */
+#define ETHTOOL_GPHYTEST 0x00000052 /* Get PHY test mode(s) */
+#define ETHTOOL_SPHYTEST 0x00000053 /* Set PHY test mode */
+
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
#define SPARC_ETH_SSET ETHTOOL_SSET
--
2.14.1
^ permalink raw reply related
* [RFC net-next 5/5] net: phy: broadcom: Add support for PHY test modes
From: Florian Fainelli @ 2018-04-28 0:32 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Russell King, open list, davem,
cphealy, nikita.yoush, vivien.didelot, Nisar.Sayed,
UNGLinuxDriver
In-Reply-To: <20180428003237.1536-1-f.fainelli@gmail.com>
Re-use the generic PHY library test modes for 100BaseT2 and 1000BaseT
and advertise support for those through the newly added ethtool knobs.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/bcm-phy-lib.c | 15 +++++++++------
drivers/net/phy/bcm7xxx.c | 3 +++
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c
index e797e0863895..cb3081e523a5 100644
--- a/drivers/net/phy/bcm-phy-lib.c
+++ b/drivers/net/phy/bcm-phy-lib.c
@@ -334,6 +334,8 @@ int bcm_phy_get_sset_count(struct phy_device *phydev, int sset)
{
if (sset == ETH_SS_PHY_STATS)
return ARRAY_SIZE(bcm_phy_hw_stats);
+ else if (sset == ETH_SS_PHY_TESTS)
+ return genphy_get_test_count(phydev);
return -EOPNOTSUPP;
}
@@ -343,12 +345,13 @@ void bcm_phy_get_strings(struct phy_device *phydev, u32 stringset, u8 *data)
{
unsigned int i;
- if (stringset != ETH_SS_PHY_STATS)
- return;
-
- for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
- strlcpy(data + i * ETH_GSTRING_LEN,
- bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN);
+ if (stringset == ETH_SS_PHY_STATS) {
+ for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
+ strlcpy(data + i * ETH_GSTRING_LEN,
+ bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN);
+ } else if (stringset == ETH_SS_PHY_TESTS) {
+ genphy_get_test_strings(phydev, data);
+ }
}
EXPORT_SYMBOL_GPL(bcm_phy_get_strings);
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 1835af147eea..1efd287ed320 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -619,6 +619,9 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev)
.get_sset_count = bcm_phy_get_sset_count, \
.get_strings = bcm_phy_get_strings, \
.get_stats = bcm7xxx_28nm_get_phy_stats, \
+ .set_test = genphy_set_test, \
+ .get_test = genphy_get_test, \
+ .get_test_len = genphy_get_test_len, \
.probe = bcm7xxx_28nm_probe, \
}
--
2.14.1
^ permalink raw reply related
* [RFC net-next 4/5] net: phy: Add support for IEEE standard test modes
From: Florian Fainelli @ 2018-04-28 0:32 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Russell King, open list, davem,
cphealy, nikita.yoush, vivien.didelot, Nisar.Sayed,
UNGLinuxDriver
In-Reply-To: <20180428003237.1536-1-f.fainelli@gmail.com>
Add support for the 100BaseT2 and 1000BaseT standard test modes as
defined by the IEEE 802.3-2012-Section two and three. We provide a set
of helper functions for PHY drivers to either punt entirely onto
genphy_* functions or if they desire, build additional tests on top of
the standard ones available.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/phy/Kconfig | 6 ++
drivers/net/phy/Makefile | 4 +-
drivers/net/phy/phy-tests.c | 159 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/phy.h | 22 ++++++
4 files changed, 190 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/phy/phy-tests.c
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index edb8b9ab827f..ef3f2f1ae990 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -200,6 +200,12 @@ config LED_TRIGGER_PHY
<Speed in megabits>Mbps OR <Speed in gigabits>Gbps OR link
for any speed known to the PHY.
+config CONFIG_PHYLIB_TEST_MODES
+ bool "Support for test modes"
+ ---help---
+ Selecting this option will allow the PHY library to support
+ test modes: electrical, cable diagnostics, pattern generator etc.
+
comment "MII PHY device drivers"
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 701ca0b8717e..e9905432e164 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,7 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
# Makefile for Linux PHY drivers and MDIO bus drivers
-libphy-y := phy.o phy-c45.o phy-core.o phy_device.o
+libphy-y := phy.o phy-c45.o phy-core.o phy_device.o \
+ phy-tests.o
mdio-bus-y += mdio_bus.o mdio_device.o
ifdef CONFIG_MDIO_DEVICE
@@ -18,6 +19,7 @@ obj-$(CONFIG_MDIO_DEVICE) += mdio-bus.o
endif
libphy-$(CONFIG_SWPHY) += swphy.o
libphy-$(CONFIG_LED_TRIGGER_PHY) += phy_led_triggers.o
+libphy-$(CONFIG_PHYLIB_TEST_MODES) += phy-tests.o
obj-$(CONFIG_PHYLINK) += phylink.o
obj-$(CONFIG_PHYLIB) += libphy.o
diff --git a/drivers/net/phy/phy-tests.c b/drivers/net/phy/phy-tests.c
new file mode 100644
index 000000000000..5709d7821925
--- /dev/null
+++ b/drivers/net/phy/phy-tests.c
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0
+/* PHY library common test modes
+ */
+#include <linux/export.h>
+#include <linux/phy.h>
+
+/* genphy_get_test - Get PHY test specific data
+ * @phydev: the PHY device instance
+ * @test: the desired test mode
+ * @data: test specific data (none)
+ */
+int genphy_get_test(struct phy_device *phydev, struct ethtool_phy_test *test,
+ u8 *data)
+{
+ if (test->mode >= PHY_STD_TEST_MODE_MAX)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(genphy_get_test);
+
+/* genphy_set_test - Make a PHY enter one of the standard IEEE defined
+ * test modes
+ * @phydev: the PHY device instance
+ * @test: the desired test mode
+ * @data: test specific data (none)
+ *
+ * This function makes the designated @phydev enter the desired standard
+ * 100BaseT2 or 1000BaseT test mode as defined in IEEE 802.3-2012 section TWO
+ * and THREE under 32.6.1.2.1 and 40.6.1.1.2 respectively
+ */
+int genphy_set_test(struct phy_device *phydev,
+ struct ethtool_phy_test *test, const u8 *data)
+{
+ u16 shift, base, bmcr = 0;
+ int ret;
+
+ /* Exit test mode */
+ if (test->mode == PHY_STD_TEST_MODE_NORMAL) {
+ ret = phy_read(phydev, MII_CTRL1000);
+ if (ret < 0)
+ return ret;
+
+ ret &= ~GENMASK(15, 13);
+
+ return phy_write(phydev, MII_CTRL1000, ret);
+ }
+
+ switch (test->mode) {
+ case PHY_STD_TEST_MODE_100BASET2_1:
+ case PHY_STD_TEST_MODE_100BASET2_2:
+ case PHY_STD_TEST_MODE_100BASET2_3:
+ if (!(phydev->supported & PHY_100BT_FEATURES))
+ return -EOPNOTSUPP;
+
+ shift = 14;
+ base = test->mode - PHY_STD_TEST_MODE_NORMAL;
+ bmcr = BMCR_SPEED100;
+ break;
+
+ case PHY_STD_TEST_MODE_1000BASET_1:
+ case PHY_STD_TEST_MODE_1000BASET_2:
+ case PHY_STD_TEST_MODE_1000BASET_3:
+ case PHY_STD_TEST_MODE_1000BASET_4:
+ if (!(phydev->supported & PHY_1000BT_FEATURES))
+ return -EOPNOTSUPP;
+
+ shift = 13;
+ base = test->mode - PHY_STD_TEST_MODE_100BASET2_MAX;
+ bmcr = BMCR_SPEED1000;
+ break;
+
+ default:
+ /* Let an upper driver deal with additional modes it may
+ * support
+ */
+ return -EOPNOTSUPP;
+ }
+
+ /* Force speed and duplex */
+ ret = phy_write(phydev, MII_BMCR, bmcr | BMCR_FULLDPLX);
+ if (ret < 0)
+ return ret;
+
+ /* Set the desired test mode bit */
+ return phy_write(phydev, MII_CTRL1000, (test->mode + base) << shift);
+}
+EXPORT_SYMBOL_GPL(genphy_set_test);
+
+static const char *const phy_std_test_mode_str[] = {
+ "normal",
+ "100baseT2-tx-waveform",
+ "100baseT2-tx-jitter",
+ "100baseT2-tx-idle",
+ "1000baseT-tx-waveform",
+ "1000baseT-tx-jitter-master",
+ "1000baseT-tx-jitter-slave",
+ "1000BaseT-tx-distorsion"
+};
+
+/* genphy_get_test_count - Get PHY test count
+ * @phydev: the PHY device instance
+ *
+ * Returns the number of supported test modes for this PHY
+ */
+int genphy_get_test_count(struct phy_device *phydev)
+{
+ return ARRAY_SIZE(phy_std_test_mode_str);
+}
+EXPORT_SYMBOL_GPL(genphy_get_test_count);
+
+/* genphy_get_test_len - Return the amount of test specific data given
+ * a specific test mode
+ * @phydev: the PHY device instance
+ * @mode: the desired test mode
+ */
+int genphy_get_test_len(struct phy_device *phydev, u32 mode)
+{
+ switch (mode) {
+ case PHY_STD_TEST_MODE_NORMAL:
+ case PHY_STD_TEST_MODE_100BASET2_1:
+ case PHY_STD_TEST_MODE_100BASET2_2:
+ case PHY_STD_TEST_MODE_100BASET2_3:
+ case PHY_STD_TEST_MODE_1000BASET_1:
+ case PHY_STD_TEST_MODE_1000BASET_2:
+ case PHY_STD_TEST_MODE_1000BASET_3:
+ case PHY_STD_TEST_MODE_1000BASET_4:
+ /* no test specific data */
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+EXPORT_SYMBOL_GPL(genphy_get_test_len);
+
+/* genphy_get_test_strings - Obtain the PHY device supported test modes
+ * text representations
+ * @phydev: the PHY device instance
+ * @data: buffer to store strings
+ */
+void genphy_get_test_strings(struct phy_device *phydev, u8 *data)
+{
+ unsigned int i;
+
+ if (!(phydev->supported & PHY_100BT_FEATURES))
+ return;
+
+ for (i = 0; i < PHY_STD_TEST_MODE_100BASET2_MAX; i++)
+ strlcpy(data + i * ETH_GSTRING_LEN,
+ phy_std_test_mode_str[i], ETH_GSTRING_LEN);
+
+ if (!(phydev->supported & PHY_1000BT_FEATURES))
+ return;
+
+ for (; i < PHY_STD_TEST_MODE_MAX; i++)
+ strlcpy(data + i * ETH_GSTRING_LEN,
+ phy_std_test_mode_str[i], ETH_GSTRING_LEN);
+}
+EXPORT_SYMBOL_GPL(genphy_get_test_strings);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 449afde7ca7c..7155187cf268 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -165,6 +165,20 @@ static inline const char *phy_modes(phy_interface_t interface)
}
}
+enum phy_std_test_mode {
+ /* Normal operation - disables test mode */
+ PHY_STD_TEST_MODE_NORMAL = 0,
+ PHY_STD_TEST_MODE_100BASET2_1,
+ PHY_STD_TEST_MODE_100BASET2_2,
+ PHY_STD_TEST_MODE_100BASET2_3,
+ PHY_STD_TEST_MODE_100BASET2_MAX = PHY_STD_TEST_MODE_100BASET2_3,
+ PHY_STD_TEST_MODE_1000BASET_1,
+ PHY_STD_TEST_MODE_1000BASET_2,
+ PHY_STD_TEST_MODE_1000BASET_3,
+ PHY_STD_TEST_MODE_1000BASET_4,
+ PHY_STD_TEST_MODE_MAX,
+ /* PHY drivers can implement their own test modes after that value */
+};
#define PHY_INIT_TIMEOUT 100000
#define PHY_STATE_TIME 1
@@ -997,6 +1011,14 @@ int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad,
int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,
u16 regnum, u16 val);
+int genphy_get_test(struct phy_device *phydev, struct ethtool_phy_test *t,
+ u8 *data);
+int genphy_set_test(struct phy_device *phydev, struct ethtool_phy_test *t,
+ const u8 *data);
+int genphy_get_test_count(struct phy_device *phydev);
+void genphy_get_test_strings(struct phy_device *phydev, u8 *data);
+int genphy_get_test_len(struct phy_device *phydev, u32 mode);
+
/* Clause 45 PHY */
int genphy_c45_restart_aneg(struct phy_device *phydev);
int genphy_c45_aneg_done(struct phy_device *phydev);
--
2.14.1
^ permalink raw reply related
* [RFC net-next 3/5] net: ethtool: Add plumbing to get/set PHY test modes
From: Florian Fainelli @ 2018-04-28 0:32 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Russell King, open list, davem,
cphealy, nikita.yoush, vivien.didelot, Nisar.Sayed,
UNGLinuxDriver
In-Reply-To: <20180428003237.1536-1-f.fainelli@gmail.com>
Implement the core ethtool changes to get/set PHY test modes, no driver
implements that yet, but the internal API is defined and now allows it.
We also provide the required helpers in PHYLIB in order to call the
appropriate functions within the drivers.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/linux/phy.h | 63 ++++++++++++++++++++++++++++++++++++++++--
net/core/ethtool.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 135 insertions(+), 7 deletions(-)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index deba0c11647f..449afde7ca7c 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -659,6 +659,14 @@ struct phy_driver {
struct ethtool_tunable *tuna,
const void *data);
int (*set_loopback)(struct phy_device *dev, bool enable);
+
+ /* Get and Set PHY test modes */
+ int (*get_test_len)(struct phy_device *dev, u32 mode);
+ int (*get_test)(struct phy_device *dev,
+ struct ethtool_phy_test *test, u8 *data);
+ int (*set_test)(struct phy_device *dev,
+ struct ethtool_phy_test *test,
+ const u8 *data);
};
#define to_phy_driver(d) container_of(to_mdio_common_driver(d), \
struct phy_driver, mdiodrv)
@@ -1090,9 +1098,11 @@ static inline int phy_ethtool_get_sset_count(struct phy_device *phydev,
if (!phydev->drv)
return -EIO;
- if (phydev->drv->get_sset_count &&
- phydev->drv->get_strings &&
- phydev->drv->get_stats) {
+ if (!phydev->drv->get_sset_count || !phydev->drv->get_strings)
+ return -EOPNOTSUPP;
+
+ if (phydev->drv->get_stats || phydev->drv->get_test_len ||
+ phydev->drv->get_test || phydev->drv->set_test) {
mutex_lock(&phydev->lock);
ret = phydev->drv->get_sset_count(phydev, sset);
mutex_unlock(&phydev->lock);
@@ -1116,6 +1126,53 @@ static inline int phy_ethtool_get_stats(struct phy_device *phydev,
return 0;
}
+static inline int phy_ethtool_get_test_len(struct phy_device *phydev,
+ u32 mode)
+{
+ int ret;
+
+ if (!phydev->drv)
+ return -EIO;
+
+ mutex_lock(&phydev->lock);
+ ret = phydev->drv->get_test_len(phydev, mode);
+ mutex_unlock(&phydev->lock);
+
+ return ret;
+}
+
+static inline int phy_ethtool_get_test(struct phy_device *phydev,
+ struct ethtool_phy_test *test,
+ u8 *data)
+{
+ int ret;
+
+ if (!phydev->drv)
+ return -EIO;
+
+ mutex_lock(&phydev->lock);
+ ret = phydev->drv->get_test(phydev, test, data);
+ mutex_unlock(&phydev->lock);
+
+ return ret;
+}
+
+static inline int phy_ethtool_set_test(struct phy_device *phydev,
+ struct ethtool_phy_test *test,
+ const u8 *data)
+{
+ int ret;
+
+ if (!phydev->drv)
+ return -EIO;
+
+ mutex_lock(&phydev->lock);
+ ret = phydev->drv->set_test(phydev, test, data);
+ mutex_unlock(&phydev->lock);
+
+ return ret;
+}
+
extern struct bus_type mdio_bus_type;
struct mdio_board_info {
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 0b9e2a44e1d1..52d2c9bc49b4 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -227,8 +227,9 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset)
if (sset == ETH_SS_PHY_TUNABLES)
return ARRAY_SIZE(phy_tunable_strings);
- if (sset == ETH_SS_PHY_STATS && dev->phydev &&
- !ops->get_ethtool_phy_stats)
+ if ((sset == ETH_SS_PHY_STATS && dev->phydev &&
+ !ops->get_ethtool_phy_stats) ||
+ (sset == ETH_SS_PHY_TESTS && dev->phydev))
return phy_ethtool_get_sset_count(dev->phydev, sset);
if (ops->get_sset_count && ops->get_strings)
@@ -252,8 +253,9 @@ static void __ethtool_get_strings(struct net_device *dev,
memcpy(data, tunable_strings, sizeof(tunable_strings));
else if (stringset == ETH_SS_PHY_TUNABLES)
memcpy(data, phy_tunable_strings, sizeof(phy_tunable_strings));
- else if (stringset == ETH_SS_PHY_STATS && dev->phydev &&
- !ops->get_ethtool_phy_stats)
+ else if ((stringset == ETH_SS_PHY_STATS && dev->phydev &&
+ !ops->get_ethtool_phy_stats) ||
+ (stringset == ETH_SS_PHY_TESTS && dev->phydev))
phy_ethtool_get_strings(dev->phydev, stringset, data);
else
/* ops->get_strings is valid because checked earlier */
@@ -2016,6 +2018,68 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
return ret;
}
+static int ethtool_get_phy_test(struct net_device *dev, void __user *useraddr)
+{
+ struct phy_device *phydev = dev->phydev;
+ struct ethtool_phy_test test;
+ int ret, test_len;
+ void *data;
+
+ if (!phydev)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&test, useraddr, sizeof(test)))
+ return -EFAULT;
+
+ test_len = phy_ethtool_get_test_len(phydev, test.mode);
+ if (test_len < 0)
+ return test_len;
+
+ test.len = test_len;
+ data = kmalloc(test_len, GFP_USER);
+ if (test_len && !data)
+ return -ENOMEM;
+
+ ret = phy_ethtool_get_test(phydev, &test, data);
+ if (ret < 0)
+ goto out;
+
+ ret = -EFAULT;
+ if (copy_to_user(useraddr, &test, sizeof(test)))
+ goto out;
+ useraddr += sizeof(test);
+ if (test_len && copy_to_user(useraddr, data, test_len))
+ goto out;
+ ret = 0;
+out:
+ kfree(data);
+ return ret;
+}
+
+static int ethtool_set_phy_test(struct net_device *dev, void __user *useraddr)
+{
+ struct phy_device *phydev = dev->phydev;
+ struct ethtool_phy_test test;
+ void *data;
+ int ret;
+
+ if (!phydev)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&test, useraddr, sizeof(test)))
+ return -EFAULT;
+
+ useraddr += sizeof(test);
+ data = memdup_user(useraddr, test.len);
+ if (IS_ERR(data))
+ return PTR_ERR(data);
+
+ ret = phy_ethtool_set_test(phydev, &test, data);
+
+ kfree(data);
+ return ret;
+}
+
static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
{
struct ethtool_perm_addr epaddr;
@@ -2637,6 +2701,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_PHY_GTUNABLE:
case ETHTOOL_GLINKSETTINGS:
case ETHTOOL_GFECPARAM:
+ case ETHTOOL_GPHYTEST:
break;
default:
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
@@ -2852,6 +2917,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_SFECPARAM:
rc = ethtool_set_fecparam(dev, useraddr);
break;
+ case ETHTOOL_GPHYTEST:
+ rc = ethtool_get_phy_test(dev, useraddr);
+ break;
+ case ETHTOOL_SPHYTEST:
+ rc = ethtool_set_phy_test(dev, useraddr);
+ break;
default:
rc = -EOPNOTSUPP;
}
--
2.14.1
^ permalink raw reply related
* [RFC net-next 2/5] net: ethtool: Add UAPI for PHY test modes
From: Florian Fainelli @ 2018-04-28 0:32 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Russell King, open list, davem,
cphealy, nikita.yoush, vivien.didelot, Nisar.Sayed,
UNGLinuxDriver
In-Reply-To: <20180428003237.1536-1-f.fainelli@gmail.com>
Add the necessary UAPI changes to support querying the PHY tests modes
implemented and optionally associated test specific data. This will be
used as the foundation for supporting:
- IEEE standard electrical test modes
- cable diagnostics
- packet tester
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
include/uapi/linux/ethtool.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 4ca65b56084f..a8befecfe853 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -567,6 +567,7 @@ struct ethtool_pauseparam {
* @ETH_SS_RSS_HASH_FUNCS: RSS hush function names
* @ETH_SS_PHY_STATS: Statistic names, for use with %ETHTOOL_GPHYSTATS
* @ETH_SS_PHY_TUNABLES: PHY tunable names
+ * @ETH_SS_PHY_TESTS: PHY tests, for use with %ETHTOOL_GPHYTEST
*/
enum ethtool_stringset {
ETH_SS_TEST = 0,
@@ -578,6 +579,7 @@ enum ethtool_stringset {
ETH_SS_TUNABLES,
ETH_SS_PHY_STATS,
ETH_SS_PHY_TUNABLES,
+ ETH_SS_PHY_TESTS,
};
/**
@@ -1296,6 +1298,25 @@ enum ethtool_fec_config_bits {
ETHTOOL_FEC_BASER_BIT,
};
+/**
+ * struct ethtool_phy_test - Ethernet PHY test mode
+ * @cmd: Command number = %ETHTOOL_GPHYTEST or %ETHTOOL_SPHYTEST
+ * @flags: A bitmask of flags from &enum ethtool_test_flags. Some
+ * flags may be set by the user on entry; others may be set by
+ * the driver on return.
+ * @mode: PHY test mode to enter. The index should be a valid test mode
+ * obtained through ethtool_get_strings with %ETH_SS_PHY_TESTS
+ * @len: The length of the test specific array @data
+ * @data: Array of test specific results to be interpreted with @mode
+ */
+struct ethtool_phy_test {
+ __u32 cmd;
+ __u32 flags;
+ __u32 mode;
+ __u32 len;
+ __u8 data[0];
+};
+
#define ETHTOOL_FEC_NONE (1 << ETHTOOL_FEC_NONE_BIT)
#define ETHTOOL_FEC_AUTO (1 << ETHTOOL_FEC_AUTO_BIT)
#define ETHTOOL_FEC_OFF (1 << ETHTOOL_FEC_OFF_BIT)
@@ -1396,6 +1417,8 @@ enum ethtool_fec_config_bits {
#define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */
#define ETHTOOL_GFECPARAM 0x00000050 /* Get FEC settings */
#define ETHTOOL_SFECPARAM 0x00000051 /* Set FEC settings */
+#define ETHTOOL_GPHYTEST 0x00000052 /* Get PHY test mode(s) */
+#define ETHTOOL_SPHYTEST 0x00000053 /* Set PHY test mode */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
--
2.14.1
^ permalink raw reply related
* [RFC net-next 1/5] net: phy: Pass stringset argument to ethtool operations
From: Florian Fainelli @ 2018-04-28 0:32 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Russell King, open list, davem,
cphealy, nikita.yoush, vivien.didelot, Nisar.Sayed,
UNGLinuxDriver
In-Reply-To: <20180428003237.1536-1-f.fainelli@gmail.com>
In preparation for returning a different type of strings other than
ETH_SS_STATS update the PHY drivers, helpers and consumers of these
functions.
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/dsa/b53/b53_common.c | 4 ++--
drivers/net/phy/bcm-phy-lib.c | 12 +++++++++---
drivers/net/phy/bcm-phy-lib.h | 4 ++--
drivers/net/phy/bcm7xxx.c | 6 ++++--
drivers/net/phy/broadcom.c | 6 ++++--
drivers/net/phy/marvell.c | 11 +++++++++--
drivers/net/phy/micrel.c | 11 +++++++++--
drivers/net/phy/smsc.c | 10 ++++++++--
include/linux/phy.h | 14 ++++++++------
include/net/dsa.h | 4 ++--
net/core/ethtool.c | 7 ++++---
net/dsa/master.c | 9 +++++----
net/dsa/port.c | 8 ++++----
13 files changed, 70 insertions(+), 36 deletions(-)
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 9f561fe505cb..8201e8f5c028 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -837,7 +837,7 @@ void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset,
if (!phydev)
return;
- phy_ethtool_get_strings(phydev, data);
+ phy_ethtool_get_strings(phydev, stringset, data);
}
}
EXPORT_SYMBOL(b53_get_strings);
@@ -899,7 +899,7 @@ int b53_get_sset_count(struct dsa_switch *ds, int port, int sset)
if (!phydev)
return 0;
- return phy_ethtool_get_sset_count(phydev);
+ return phy_ethtool_get_sset_count(phydev, sset);
}
return 0;
diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c
index 0876aec7328c..e797e0863895 100644
--- a/drivers/net/phy/bcm-phy-lib.c
+++ b/drivers/net/phy/bcm-phy-lib.c
@@ -330,16 +330,22 @@ static const struct bcm_phy_hw_stat bcm_phy_hw_stats[] = {
{ "phy_remote_rcv_nok", MII_BRCM_CORE_BASE14, 0, 8 },
};
-int bcm_phy_get_sset_count(struct phy_device *phydev)
+int bcm_phy_get_sset_count(struct phy_device *phydev, int sset)
{
- return ARRAY_SIZE(bcm_phy_hw_stats);
+ if (sset == ETH_SS_PHY_STATS)
+ return ARRAY_SIZE(bcm_phy_hw_stats);
+
+ return -EOPNOTSUPP;
}
EXPORT_SYMBOL_GPL(bcm_phy_get_sset_count);
-void bcm_phy_get_strings(struct phy_device *phydev, u8 *data)
+void bcm_phy_get_strings(struct phy_device *phydev, u32 stringset, u8 *data)
{
unsigned int i;
+ if (stringset != ETH_SS_PHY_STATS)
+ return;
+
for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
strlcpy(data + i * ETH_GSTRING_LEN,
bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN);
diff --git a/drivers/net/phy/bcm-phy-lib.h b/drivers/net/phy/bcm-phy-lib.h
index 7c73808cbbde..bebcfe106283 100644
--- a/drivers/net/phy/bcm-phy-lib.h
+++ b/drivers/net/phy/bcm-phy-lib.h
@@ -42,8 +42,8 @@ int bcm_phy_downshift_get(struct phy_device *phydev, u8 *count);
int bcm_phy_downshift_set(struct phy_device *phydev, u8 count);
-int bcm_phy_get_sset_count(struct phy_device *phydev);
-void bcm_phy_get_strings(struct phy_device *phydev, u8 *data);
+int bcm_phy_get_sset_count(struct phy_device *phydev, int sset);
+void bcm_phy_get_strings(struct phy_device *phydev, u32 stringset, u8 *data);
void bcm_phy_get_stats(struct phy_device *phydev, u64 *shadow,
struct ethtool_stats *stats, u64 *data);
diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c
index 29b1c88b55cc..1835af147eea 100644
--- a/drivers/net/phy/bcm7xxx.c
+++ b/drivers/net/phy/bcm7xxx.c
@@ -587,6 +587,9 @@ static void bcm7xxx_28nm_get_phy_stats(struct phy_device *phydev,
static int bcm7xxx_28nm_probe(struct phy_device *phydev)
{
struct bcm7xxx_phy_priv *priv;
+ int count;
+
+ count = bcm_phy_get_sset_count(phydev, ETH_SS_PHY_STATS);
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -594,8 +597,7 @@ static int bcm7xxx_28nm_probe(struct phy_device *phydev)
phydev->priv = priv;
- priv->stats = devm_kcalloc(&phydev->mdio.dev,
- bcm_phy_get_sset_count(phydev), sizeof(u64),
+ priv->stats = devm_kcalloc(&phydev->mdio.dev, count, sizeof(u64),
GFP_KERNEL);
if (!priv->stats)
return -ENOMEM;
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index 3bb6b66dc7bf..dd909799baf0 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -547,6 +547,9 @@ struct bcm53xx_phy_priv {
static int bcm53xx_phy_probe(struct phy_device *phydev)
{
struct bcm53xx_phy_priv *priv;
+ int count;
+
+ count = bcm_phy_get_sset_count(phydev, ETH_SS_PHY_STATS);
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -554,8 +557,7 @@ static int bcm53xx_phy_probe(struct phy_device *phydev)
phydev->priv = priv;
- priv->stats = devm_kcalloc(&phydev->mdio.dev,
- bcm_phy_get_sset_count(phydev), sizeof(u64),
+ priv->stats = devm_kcalloc(&phydev->mdio.dev, count, sizeof(u64),
GFP_KERNEL);
if (!priv->stats)
return -ENOMEM;
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index b8f57e9b9379..cf962182297b 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -1464,18 +1464,25 @@ static int m88e1318_set_wol(struct phy_device *phydev,
return phy_restore_page(phydev, oldpage, err);
}
-static int marvell_get_sset_count(struct phy_device *phydev)
+static int marvell_get_sset_count(struct phy_device *phydev, int sset)
{
+ if (sset != ETH_SS_PHY_STATS)
+ return -EOPNOTSUPP;
+
if (phydev->supported & SUPPORTED_FIBRE)
return ARRAY_SIZE(marvell_hw_stats);
else
return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS;
}
-static void marvell_get_strings(struct phy_device *phydev, u8 *data)
+static void marvell_get_strings(struct phy_device *phydev, u32 stringset,
+ u8 *data)
{
int i;
+ if (stringset != ETH_SS_PHY_STATS)
+ return;
+
for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) {
strlcpy(data + i * ETH_GSTRING_LEN,
marvell_hw_stats[i].string, ETH_GSTRING_LEN);
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index de31c5170a5b..54f3e400a454 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -635,15 +635,22 @@ static int ksz8873mll_config_aneg(struct phy_device *phydev)
return 0;
}
-static int kszphy_get_sset_count(struct phy_device *phydev)
+static int kszphy_get_sset_count(struct phy_device *phydev, int sset)
{
+ if (sset != ETH_SS_PHY_STATS)
+ return -EOPNOTSUPP;
+
return ARRAY_SIZE(kszphy_hw_stats);
}
-static void kszphy_get_strings(struct phy_device *phydev, u8 *data)
+static void kszphy_get_strings(struct phy_device *phydev, u32 stringset,
+ u8 *data)
{
int i;
+ if (stringset != ETH_SS_PHY_STATS)
+ return;
+
for (i = 0; i < ARRAY_SIZE(kszphy_hw_stats); i++) {
strlcpy(data + i * ETH_GSTRING_LEN,
kszphy_hw_stats[i].string, ETH_GSTRING_LEN);
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index c328208388da..c1a4d4d0879d 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -153,15 +153,21 @@ static int lan87xx_read_status(struct phy_device *phydev)
return err;
}
-static int smsc_get_sset_count(struct phy_device *phydev)
+static int smsc_get_sset_count(struct phy_device *phydev, int sset)
{
+ if (sset != ETH_SS_PHY_STATS)
+ return -EOPNOTSUPP;
+
return ARRAY_SIZE(smsc_hw_stats);
}
-static void smsc_get_strings(struct phy_device *phydev, u8 *data)
+static void smsc_get_strings(struct phy_device *phydev, u32 stringset, u8 *data)
{
int i;
+ if (stringset != ETH_SS_PHY_STATS)
+ return;
+
for (i = 0; i < ARRAY_SIZE(smsc_hw_stats); i++) {
strncpy(data + i * ETH_GSTRING_LEN,
smsc_hw_stats[i].string, ETH_GSTRING_LEN);
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 073235e70442..deba0c11647f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -647,8 +647,8 @@ struct phy_driver {
struct ethtool_eeprom *ee, u8 *data);
/* Get statistics from the phy using ethtool */
- int (*get_sset_count)(struct phy_device *dev);
- void (*get_strings)(struct phy_device *dev, u8 *data);
+ int (*get_sset_count)(struct phy_device *dev, int sset);
+ void (*get_strings)(struct phy_device *dev, u32 stringset, u8 *data);
void (*get_stats)(struct phy_device *dev,
struct ethtool_stats *stats, u64 *data);
@@ -1069,19 +1069,21 @@ void mdio_bus_exit(void);
#endif
/* Inline function for use within net/core/ethtool.c (built-in) */
-static inline int phy_ethtool_get_strings(struct phy_device *phydev, u8 *data)
+static inline int phy_ethtool_get_strings(struct phy_device *phydev,
+ u32 stringset, u8 *data)
{
if (!phydev->drv)
return -EIO;
mutex_lock(&phydev->lock);
- phydev->drv->get_strings(phydev, data);
+ phydev->drv->get_strings(phydev, stringset, data);
mutex_unlock(&phydev->lock);
return 0;
}
-static inline int phy_ethtool_get_sset_count(struct phy_device *phydev)
+static inline int phy_ethtool_get_sset_count(struct phy_device *phydev,
+ int sset)
{
int ret;
@@ -1092,7 +1094,7 @@ static inline int phy_ethtool_get_sset_count(struct phy_device *phydev)
phydev->drv->get_strings &&
phydev->drv->get_stats) {
mutex_lock(&phydev->lock);
- ret = phydev->drv->get_sset_count(phydev);
+ ret = phydev->drv->get_sset_count(phydev, sset);
mutex_unlock(&phydev->lock);
return ret;
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 462e9741b210..528388cda0a0 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -592,8 +592,8 @@ static inline int call_dsa_notifiers(unsigned long val, struct net_device *dev,
#define BRCM_TAG_GET_QUEUE(v) ((v) & 0xff)
-int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data);
+int dsa_port_get_phy_strings(struct dsa_port *dp, u32 stringset, uint8_t *data);
int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data);
-int dsa_port_get_phy_sset_count(struct dsa_port *dp);
+int dsa_port_get_phy_sset_count(struct dsa_port *dp, int sset);
#endif
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index b849fdae7e87..0b9e2a44e1d1 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -229,7 +229,7 @@ static int __ethtool_get_sset_count(struct net_device *dev, int sset)
if (sset == ETH_SS_PHY_STATS && dev->phydev &&
!ops->get_ethtool_phy_stats)
- return phy_ethtool_get_sset_count(dev->phydev);
+ return phy_ethtool_get_sset_count(dev->phydev, sset);
if (ops->get_sset_count && ops->get_strings)
return ops->get_sset_count(dev, sset);
@@ -254,7 +254,7 @@ static void __ethtool_get_strings(struct net_device *dev,
memcpy(data, phy_tunable_strings, sizeof(phy_tunable_strings));
else if (stringset == ETH_SS_PHY_STATS && dev->phydev &&
!ops->get_ethtool_phy_stats)
- phy_ethtool_get_strings(dev->phydev, data);
+ phy_ethtool_get_strings(dev->phydev, stringset, data);
else
/* ops->get_strings is valid because checked earlier */
ops->get_strings(dev, stringset, data);
@@ -1977,7 +1977,8 @@ static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
return -EOPNOTSUPP;
if (dev->phydev && !ops->get_ethtool_phy_stats)
- n_stats = phy_ethtool_get_sset_count(dev->phydev);
+ n_stats = phy_ethtool_get_sset_count(dev->phydev,
+ ETH_SS_PHY_STATS);
else
n_stats = ops->get_sset_count(dev, ETH_SS_PHY_STATS);
if (n_stats < 0)
diff --git a/net/dsa/master.c b/net/dsa/master.c
index c90ee3227dea..4dbbaad2c8aa 100644
--- a/net/dsa/master.c
+++ b/net/dsa/master.c
@@ -42,7 +42,8 @@ static void dsa_master_get_ethtool_phy_stats(struct net_device *dev,
int count = 0;
if (dev->phydev && !ops->get_ethtool_phy_stats) {
- count = phy_ethtool_get_sset_count(dev->phydev);
+ count = phy_ethtool_get_sset_count(dev->phydev,
+ ETH_SS_PHY_STATS);
if (count >= 0)
phy_ethtool_get_stats(dev->phydev, stats, data);
} else if (ops->get_sset_count && ops->get_ethtool_phy_stats) {
@@ -66,7 +67,7 @@ static int dsa_master_get_sset_count(struct net_device *dev, int sset)
if (sset == ETH_SS_PHY_STATS && dev->phydev &&
!ops->get_ethtool_phy_stats)
- count = phy_ethtool_get_sset_count(dev->phydev);
+ count = phy_ethtool_get_sset_count(dev->phydev, sset);
else if (ops->get_sset_count)
count = ops->get_sset_count(dev, sset);
@@ -98,11 +99,11 @@ static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset,
if (stringset == ETH_SS_PHY_STATS && dev->phydev &&
!ops->get_ethtool_phy_stats) {
- mcount = phy_ethtool_get_sset_count(dev->phydev);
+ mcount = phy_ethtool_get_sset_count(dev->phydev, stringset);
if (mcount < 0)
mcount = 0;
else
- phy_ethtool_get_strings(dev->phydev, data);
+ phy_ethtool_get_strings(dev->phydev, stringset, data);
} else if (ops->get_sset_count && ops->get_strings) {
mcount = ops->get_sset_count(dev, stringset);
if (mcount < 0)
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 2413beb995be..4e836da4cdd3 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -384,7 +384,7 @@ void dsa_port_link_unregister_of(struct dsa_port *dp)
dsa_port_setup_phy_of(dp, false);
}
-int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data)
+int dsa_port_get_phy_strings(struct dsa_port *dp, u32 stringset, uint8_t *data)
{
struct phy_device *phydev;
int ret = -EOPNOTSUPP;
@@ -396,7 +396,7 @@ int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data)
if (IS_ERR_OR_NULL(phydev))
return ret;
- ret = phy_ethtool_get_strings(phydev, data);
+ ret = phy_ethtool_get_strings(phydev, stringset, data);
put_device(&phydev->mdio.dev);
return ret;
@@ -422,7 +422,7 @@ int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data)
}
EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats);
-int dsa_port_get_phy_sset_count(struct dsa_port *dp)
+int dsa_port_get_phy_sset_count(struct dsa_port *dp, int sset)
{
struct phy_device *phydev;
int ret = -EOPNOTSUPP;
@@ -434,7 +434,7 @@ int dsa_port_get_phy_sset_count(struct dsa_port *dp)
if (IS_ERR_OR_NULL(phydev))
return ret;
- ret = phy_ethtool_get_sset_count(phydev);
+ ret = phy_ethtool_get_sset_count(phydev, sset);
put_device(&phydev->mdio.dev);
return ret;
--
2.14.1
^ permalink raw reply related
* [RFC net-next 0/5] Support for PHY test modes
From: Florian Fainelli @ 2018-04-28 0:32 UTC (permalink / raw)
To: netdev
Cc: Florian Fainelli, Andrew Lunn, Russell King, open list, davem,
cphealy, nikita.yoush, vivien.didelot, Nisar.Sayed,
UNGLinuxDriver
Hi all,
This patch series adds support for specifying PHY test modes through ethtool
and paves the ground for adding support for more complex test modes that might
require data to be exchanged between user and kernel space.
As an example, patches are included to add support for the IEEE electrical test
modes for 100BaseT2 and 1000BaseT. Those do not require data to be passed back
and forth.
I believe the infrastructure to be usable enough to add support for other things
like:
- cable diagnostics
- pattern generator/waveform generator with specific pattern being indicated
for instance
Questions for Andrew, and others:
- there could be room for adding additional ETH_TEST_FL_* values in order to
help determine how the test should be running
- some of these tests can be disruptive to connectivity, the minimum we could
do is stop the PHY state machine and restart it when "normal" is used to exit
those test modes
Comments welcome!
Example:
# ethtool --get-phy-tests gphy
PHY tests gphy:
normal (Test data: No)
100baseT2-tx-waveform (Test data: No)
100baseT2-tx-jitter (Test data: No)
100baseT2-tx-idle (Test data: No)
1000baseT-tx-waveform (Test data: No)
1000baseT-tx-jitter-master (Test data: No)
1000baseT-tx-jitter-slave (Test data: No)
1000BaseT-tx-distorsion (Test data: No)
# ethtool --set-phy-test gphy 100baseT2-tx-waveform
# [ 65.262513] brcm-sf2 f0b00000.ethernet_switch gphy: Link is Down
Florian Fainelli (5):
net: phy: Pass stringset argument to ethtool operations
net: ethtool: Add UAPI for PHY test modes
net: ethtool: Add plumbing to get/set PHY test modes
net: phy: Add support for IEEE standard test modes
net: phy: broadcom: Add support for PHY test modes
drivers/net/dsa/b53/b53_common.c | 4 +-
drivers/net/phy/Kconfig | 6 ++
drivers/net/phy/Makefile | 4 +-
drivers/net/phy/bcm-phy-lib.c | 21 ++++--
drivers/net/phy/bcm-phy-lib.h | 4 +-
drivers/net/phy/bcm7xxx.c | 9 ++-
drivers/net/phy/broadcom.c | 6 +-
drivers/net/phy/marvell.c | 11 ++-
drivers/net/phy/micrel.c | 11 ++-
drivers/net/phy/phy-tests.c | 159 +++++++++++++++++++++++++++++++++++++++
drivers/net/phy/smsc.c | 10 ++-
include/linux/phy.h | 99 +++++++++++++++++++++---
include/net/dsa.h | 4 +-
include/uapi/linux/ethtool.h | 23 ++++++
net/core/ethtool.c | 86 +++++++++++++++++++--
net/dsa/master.c | 9 ++-
net/dsa/port.c | 8 +-
17 files changed, 427 insertions(+), 47 deletions(-)
create mode 100644 drivers/net/phy/phy-tests.c
--
2.14.1
^ permalink raw reply
* Re: [PATCH net-next v2 0/6] mlxsw: SPAN: Support routes pointing at bridges
From: David Miller @ 2018-04-28 0:28 UTC (permalink / raw)
To: idosch; +Cc: netdev, bridge, jiri, petrm, nikolay, stephen, mlxsw
In-Reply-To: <20180427151111.22099-1-idosch@mellanox.com>
From: Ido Schimmel <idosch@mellanox.com>
Date: Fri, 27 Apr 2018 18:11:05 +0300
> Changes from v1 to v2:
>
> - Change the suite of bridge accessor functions to br_vlan_pvid_rtnl(),
> br_vlan_info_rtnl(), br_fdb_find_port_rtnl().
Please address Stephen Hemminger's feedback, otherwise this series
looks good to go.
Thanks.
^ 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