Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DPAA2: properly set link state on startup #11

Closed
wants to merge 1 commit into from

Conversation

bzfbd
Copy link

@bzfbd bzfbd commented Jun 14, 2022

Factor out the link-state change tracking from media_change into
a new function dpaa2_ni_miibus_statchg(). There use mii information
for the link state as ifp->if_linkstate only gets updated after other
mii functions are called and thus lacks behind.

Add a new bus function to memac_mdio so we can set the dpni interface
and call MIIBUS_STATCHG on the dpni and pass that through to
dpaa2_ni_miibus_statchg().

It is a bit of a weird setup with two parallel device tress off ACPI
as ideally memac_mdio0 would be a child of dpaa2_ni0.
We will see how this will work with FDT at some point but at least the
current way of doing is flexible enough.
Currently we need to make sure MC0 can discover the memac_mdio via the
ACPI reference upon attach and have a way for DPNI to query that.
The new bus function now allows us to set a back-pointer in the other
direction from dpaa2_ni_setup().

nexus0
  acpi0
    dpaa2_mc0
      dpaa2_rc0
        dpaa2_ni0
    memac_mdio0
      memacphy0
        miibus1
          atphy0
    memac_mdio1

Most importantly and not to be missed at the end of dpaa2_ni_init()
make sure we initialize the link state as otherwise we will not see
any interrupts. That can be observed by a hanging NFS Root mount
for example, whereas with the previous code ifconfig would trigger
a SIOCGIFMEDIA call (from multi-user at some point) which then
indirectly and more by accident set the the MAC LINK STATE via
DPAA2_CMD_MAC_SET_LINK_STATE() and got the interface started.

This fixes #7

Factor out the link-state change tracking from media_change into
a new function dpaa2_ni_miibus_statchg().  There use mii information
for the link state as ifp->if_linkstate only gets updated after other
mii functions are called and thus lacks behind.

Add a new bus function to memac_mdio so we can set the dpni interface
and call MIIBUS_STATCHG on the dpni and pass that through to
dpaa2_ni_miibus_statchg().

It is a bit of a weird setup with two parallel device tress off ACPI
as ideally memac_mdio0 would be a child of dpaa2_ni0.
We will see how this will work with FDT at some point but at least the
current way of doing is flexible enough.
Currently we need to make sure MC0 can discover the memac_mdio via the
ACPI reference upon attach and have a way for DPNI to query that.
The new bus function now allows us to set a back-pointer in the other
direction from dpaa2_ni_setup().

nexus0
  acpi0
    dpaa2_mc0
      dpaa2_rc0
        dpaa2_ni0
    memac_mdio0
      memacphy0
        miibus1
          atphy0
    memac_mdio1

Most importantly and not to be missed  at the end of dpaa2_ni_init()
make sure we initialize the link state as otherwise we will not see
any interrupts.  That can be observed by a hanging NFS Root mount
for example, whereas with the previous code ifconfig would trigger
a SIOCGIFMEDIA call (from multi-user at some point) which then
indirectly and more by accident set the the MAC LINK STATE via
DPAA2_CMD_MAC_SET_LINK_STATE() and got the interface started.
@dsalychev dsalychev self-assigned this Jun 14, 2022
@dsalychev
Copy link

It rocks :) I'll spend sometime reading it today evening and will merge.

@dsalychev
Copy link

It panicked on Ten64:

Feeding entropy: .
ELF ldconfig path: /lib /usr/lib /usr/lib/compat /usr/local/lib /usr/local/lib/compat/pkg /usr/local/lib/compat/pkg
Setting hostname: guardian.
lo0: link state changed to UP
Fatal data abort:
  x0: ffff0000bd1f6000 (crypto_dev + bba96f40)
  x1: ffffa00019d18000
  x2: ffff00000090ef7c (digits + 20334)
  x3:              909
  x4: ffff0000007eb2cc (dpaa2_ni_media_tick + 0)
  x5: ffff0000bd1f6000 (crypto_dev + bba96f40)
  x6:                0
  x7:              100
  x8:                0
  x9:                0
 x10:                0
 x11: ffff000000ec8ca8 (w_locklistdata + 3b5e0)
 x12:                1
 x13:                0
 x14:            10000
 x15:                1
 x16:                8
 x17:     13940853b160
 x18: ffff000103c313c0
 x19: ffff0000bd1f6000 (crypto_dev + bba96f40)
 x20: ffffa00001d0e800
 x21: ffff0000bd1f61c0 (crypto_dev + bba97100)
 x22: ffff00000090ef7c (digits + 20334)
 x23:                0
 x24:                0
 x25:         80206910
 x26: ffffa00001d0e800
 x27:                0
 x28:         80206910
 x29: ffff000103c313e0
  sp: ffff000103c313c0
  lr: ffff0000007e7f34 (dpaa2_ni_miibus_statchg + 28)
 elr: ffff0000007e7f3c (dpaa2_ni_miibus_statchg + 30)
spsr:         20000045
 far:               3c
 esr:         96000004
panic: vm_fault failed: ffff0000007e7f3c error 1
cpuid = 6
time = 6
KDB: stack backtrace:
db_trace_self() at db_trace_self
db_trace_self_wrapper() at db_trace_self_wrapper+0x30
vpanic() at vpanic+0x138
panic() at panic+0x44
data_abort() at data_abort+0x2f0
handle_el1h_sync() at handle_el1h_sync+0x10
--- exception, esr 0x96000004
dpaa2_ni_miibus_statchg() at dpaa2_ni_miibus_statchg+0x30
dpaa2_ni_ioctl() at dpaa2_ni_ioctl+0x224
ifhwioctl() at ifhwioctl+0xba0
ifioctl() at ifioctl+0x70c
kern_ioctl() at kern_ioctl+0x2e4
sys_ioctl() at sys_ioctl+0x144
do_el0_sync() at do_el0_sync+0x508
handle_el0_sync() at handle_el0_sync+0x40
--- exception, esr 0x56000000
KDB: enter: panic
[ thread pid 82747 tid 100350 ]
Stopped at      kdb_enter+0x40: undefined       f907c27f
db> 

@dsalychev
Copy link

I'll look into it later.

@bzfbd
Copy link
Author

bzfbd commented Jun 15, 2022

Oh, no mii there (yet).

if (sc->fixed_link)
return;

@dsalychev
Copy link

Yeah, you're right. It helped.

@dsalychev
Copy link

Applied in 4529394. Thanks for that!

@dsalychev dsalychev closed this Jun 15, 2022
dsalychev pushed a commit that referenced this pull request Apr 3, 2023
Under certain loads, the following panic is hit:

    panic: page fault
    KDB: stack backtrace:
    #0 0xffffffff805db025 at kdb_backtrace+0x65
    #1 0xffffffff8058e86f at vpanic+0x17f
    #2 0xffffffff8058e6e3 at panic+0x43
    #3 0xffffffff808adc15 at trap_fatal+0x385
    #4 0xffffffff808adc6f at trap_pfault+0x4f
    #5 0xffffffff80886da8 at calltrap+0x8
    #6 0xffffffff80669186 at vgonel+0x186
    #7 0xffffffff80669841 at vgone+0x31
    #8 0xffffffff8065806d at vfs_hash_insert+0x26d
    #9 0xffffffff81a39069 at sfs_vgetx+0x149
    #10 0xffffffff81a39c54 at zfsctl_snapdir_lookup+0x1e4
    #11 0xffffffff8065a28c at lookup+0x45c
    #12 0xffffffff806594b9 at namei+0x259
    #13 0xffffffff80676a33 at kern_statat+0xf3
    #14 0xffffffff8067712f at sys_fstatat+0x2f
    #15 0xffffffff808ae50c at amd64_syscall+0x10c
    #16 0xffffffff808876bb at fast_syscall_common+0xf8

The page fault occurs because vgonel() will call VOP_CLOSE() for active
vnodes. For this reason, define vop_close for zfsctl_ops_snapshot. While
here, define vop_open for consistency.

After adding the necessary vop, the bug progresses to the following
panic:

    panic: VERIFY3(vrecycle(vp) == 1) failed (0 == 1)
    cpuid = 17
    KDB: stack backtrace:
    #0 0xffffffff805e29c5 at kdb_backtrace+0x65
    #1 0xffffffff8059620f at vpanic+0x17f
    #2 0xffffffff81a27f4a at spl_panic+0x3a
    #3 0xffffffff81a3a4d0 at zfsctl_snapshot_inactive+0x40
    #4 0xffffffff8066fdee at vinactivef+0xde
    #5 0xffffffff80670b8a at vgonel+0x1ea
    #6 0xffffffff806711e1 at vgone+0x31
    #7 0xffffffff8065fa0d at vfs_hash_insert+0x26d
    #8 0xffffffff81a39069 at sfs_vgetx+0x149
    #9 0xffffffff81a39c54 at zfsctl_snapdir_lookup+0x1e4
    #10 0xffffffff80661c2c at lookup+0x45c
    #11 0xffffffff80660e59 at namei+0x259
    #12 0xffffffff8067e3d3 at kern_statat+0xf3
    #13 0xffffffff8067eacf at sys_fstatat+0x2f
    #14 0xffffffff808b5ecc at amd64_syscall+0x10c
    #15 0xffffffff8088f07b at fast_syscall_common+0xf8

This is caused by a race condition that can occur when allocating a new
vnode and adding that vnode to the vfs hash. If the newly created vnode
loses the race when being inserted into the vfs hash, it will not be
recycled as its usecount is greater than zero, hitting the above
assertion.

Fix this by dropping the assertion.

FreeBSD-issue: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=252700
Reviewed-by: Andriy Gapon <avg@FreeBSD.org>
Reviewed-by: Mateusz Guzik <mjguzik@gmail.com>
Reviewed-by: Alek Pinchuk <apinchuk@axcient.com>
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Signed-off-by: Rob Wing <rob.wing@klarasystems.com>
Co-authored-by: Rob Wing <rob.wing@klarasystems.com>
Submitted-by: Klara, Inc.
Sponsored-by: rsync.net
Closes #14501
dsalychev pushed a commit that referenced this pull request Sep 9, 2023
netlink(4) calls back into the driver during detach and it attempts to
start an internal synchronized op recursively, causing an interruptible
hang.  Fix it by failing the ioctl if the VI has been marked as DOOMED
by cxgbe_detach.

Here's the stack for the hang for reference.
 #6  begin_synchronized_op
 #7  cxgbe_media_status
 #8  ifmedia_ioctl
 #9  cxgbe_ioctl
 #10 if_ioctl
 #11 get_operstate_ether
 #12 get_operstate
 #13 dump_iface
 #14 rtnl_handle_ifevent
 #15 rtnl_handle_ifnet_event
 #16 rt_ifmsg
 #17 if_unroute
 #18 if_down
 #19 if_detach_internal
 #20 if_detach
 #21 ether_ifdetach
 #22 cxgbe_vi_detach
 #23 cxgbe_detach
 #24 DEVICE_DETACH

MFC after:	3 days
Sponsored by:	Chelsio Communications
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NFS Root does not work
2 participants