mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 23:54:04 +08:00
6922110d15
After migrating my laptop from 4.19-LTS to 5.4-LTS a while ago I noticed that my Ethernet port to which a bond and a VLAN interface are attached appeared to remain up after resuming from suspend with the cable unplugged (and that problem still persists with 5.10-LTS). It happens that the following happens: - the network driver (e1000e here) prepares to suspend, calls e1000e_down() which calls netif_carrier_off() to signal that the link is going down. - netif_carrier_off() adds a link_watch event to the list of events for this device - the device is completely stopped. - the machine suspends - the cable is unplugged and the machine brought to another location - the machine is resumed - the queued linkwatch events are processed for the device - the device doesn't yet have the __LINK_STATE_PRESENT bit and its events are silently dropped - the device is resumed with its link down - the upper VLAN and bond interfaces are never notified that the link had been turned down and remain up - the only way to provoke a change is to physically connect the machine to a port and possibly unplug it. The state after resume looks like this: $ ip -br li | egrep 'bond|eth' bond0 UP e8:6a:64:64:64:64 <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> eth0 DOWN e8:6a:64:64:64:64 <NO-CARRIER,BROADCAST,MULTICAST,SLAVE,UP> eth0.2@eth0 UP e8:6a:64:64:64:64 <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> Placing an explicit call to netdev_state_change() either in the suspend or the resume code in the NIC driver worked around this but the solution is not satisfying. The issue in fact really is in link_watch that loses events while it ought not to. It happens that the test for the device being present was added by commit |
||
---|---|---|
.. | ||
bpf_sk_storage.c | ||
datagram.c | ||
datagram.h | ||
dev_addr_lists.c | ||
dev_ioctl.c | ||
dev.c | ||
devlink.c | ||
drop_monitor.c | ||
dst_cache.c | ||
dst.c | ||
failover.c | ||
fib_notifier.c | ||
fib_rules.c | ||
filter.c | ||
flow_dissector.c | ||
flow_offload.c | ||
gen_estimator.c | ||
gen_stats.c | ||
gro_cells.c | ||
hwbm.c | ||
link_watch.c | ||
lwt_bpf.c | ||
lwtunnel.c | ||
Makefile | ||
neighbour.c | ||
net_namespace.c | ||
net-procfs.c | ||
net-sysfs.c | ||
net-sysfs.h | ||
net-traces.c | ||
netclassid_cgroup.c | ||
netevent.c | ||
netpoll.c | ||
netprio_cgroup.c | ||
page_pool.c | ||
pktgen.c | ||
ptp_classifier.c | ||
request_sock.c | ||
rtnetlink.c | ||
scm.c | ||
secure_seq.c | ||
selftests.c | ||
skbuff.c | ||
skmsg.c | ||
sock_diag.c | ||
sock_map.c | ||
sock_reuseport.c | ||
sock.c | ||
stream.c | ||
sysctl_net_core.c | ||
timestamping.c | ||
tso.c | ||
utils.c | ||
xdp.c |