Merge pull request #5177 from Alexays/fix/recent-issue-bugs
fix: backlight I/O flooding (#5020) + network IP recovery after link flap (#5122)
This commit is contained in:
@@ -183,6 +183,12 @@ void waybar::modules::Network::createEventSocket() {
|
|||||||
if (nl_socket_set_nonblocking(ev_sock_)) {
|
if (nl_socket_set_nonblocking(ev_sock_)) {
|
||||||
throw std::runtime_error("Can't set non-blocking on network socket");
|
throw std::runtime_error("Can't set non-blocking on network socket");
|
||||||
}
|
}
|
||||||
|
// Enlarge the socket receive buffer so that a burst of link/address/route
|
||||||
|
// change notifications (e.g. a router reboot or a PPPoE redial) is less likely
|
||||||
|
// to overflow it and make the kernel drop messages (ENOBUFS). Overruns are
|
||||||
|
// still handled in worker() by resynchronising the state, but a larger buffer
|
||||||
|
// avoids most of them. The kernel caps the request at net.core.rmem_max.
|
||||||
|
nl_socket_set_buffer_size(ev_sock_, 1024 * 1024, 0);
|
||||||
nl_socket_add_memberships(ev_sock_, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, 0);
|
nl_socket_add_memberships(ev_sock_, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, 0);
|
||||||
if (!config_["interface"].isString()) {
|
if (!config_["interface"].isString()) {
|
||||||
nl_socket_add_memberships(ev_sock_, RTNLGRP_IPV4_ROUTE, RTNLGRP_IPV6_ROUTE, 0);
|
nl_socket_add_memberships(ev_sock_, RTNLGRP_IPV4_ROUTE, RTNLGRP_IPV6_ROUTE, 0);
|
||||||
@@ -277,6 +283,27 @@ void waybar::modules::Network::worker() {
|
|||||||
rc = 0;
|
rc = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (rc == -NLE_NOMEM || errno == ENOBUFS) {
|
||||||
|
// The kernel dropped multicast notifications because our receive
|
||||||
|
// buffer overflowed. This happens during a burst of
|
||||||
|
// link/address/route changes such as a router reboot or a PPPoE
|
||||||
|
// redial. We have lost track of the current state -- in
|
||||||
|
// particular the RTM_NEWADDR carrying the interface's new IP
|
||||||
|
// address may have been dropped -- so request a fresh dump to
|
||||||
|
// resynchronise. Without this the address (cleared by the
|
||||||
|
// preceding RTM_DELADDR) would stay blank until Waybar is
|
||||||
|
// restarted, because nothing else re-queries it (#5122).
|
||||||
|
spdlog::warn("network: netlink receive buffer overrun, resyncing state");
|
||||||
|
want_link_dump_ = true;
|
||||||
|
want_addr_dump_ = true;
|
||||||
|
if (!config_["interface"].isString()) {
|
||||||
|
want_route_dump_ = true;
|
||||||
|
}
|
||||||
|
askForStateDump();
|
||||||
|
// Keep draining; the next recv proceeds normally now that the
|
||||||
|
// overrun has been reported.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
spdlog::error("nl_recvmsgs_default error: {}", nl_geterror(-rc));
|
spdlog::error("nl_recvmsgs_default error: {}", nl_geterror(-rc));
|
||||||
|
|||||||
@@ -230,9 +230,21 @@ BacklightBackend::BacklightBackend(std::chrono::milliseconds interval,
|
|||||||
upsert_device(devices, dev.get());
|
upsert_device(devices, dev.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refresh state if timed out
|
// Refresh state if timed out. Only re-read the sysfs attributes of the
|
||||||
|
// devices we already track instead of re-enumerating the whole udev tree
|
||||||
|
// (udev_enumerate_scan_devices), which walks all of /sys/class/backlight
|
||||||
|
// and /sys/class/leds and floods the filesystem with open/close syscalls
|
||||||
|
// on every polling tick (#5020). Device add/remove is already delivered
|
||||||
|
// by the udev monitor above, so a periodic full re-scan is redundant.
|
||||||
if (event_count == 0) {
|
if (event_count == 0) {
|
||||||
enumerate_devices(devices, udev.get());
|
for (const auto& device : devices) {
|
||||||
|
std::unique_ptr<udev_device, UdevDeviceDeleter> dev{
|
||||||
|
udev_device_new_from_subsystem_sysname(udev.get(), device.subsystem().c_str(),
|
||||||
|
device.name().c_str())};
|
||||||
|
if (dev) {
|
||||||
|
upsert_device(devices, dev.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::scoped_lock<std::mutex> lock(udev_thread_mutex_);
|
std::scoped_lock<std::mutex> lock(udev_thread_mutex_);
|
||||||
|
|||||||
Reference in New Issue
Block a user