diff --git a/sys/netlink/netlink_debug.h b/sys/netlink/netlink_debug.h --- a/sys/netlink/netlink_debug.h +++ b/sys/netlink/netlink_debug.h @@ -40,7 +40,10 @@ * Generic debug * [nl_domain] func_name: debug text */ -#define NL_LOG RT_LOG +#define NL_LOG(_l, ...) do { \ + if (THREAD_CAN_SLEEP()) \ + RT_LOG_##_l((_l), __VA_ARGS__); \ +} while (0) /* * Logging for events specific for particular process diff --git a/sys/netlink/netlink_generic.h b/sys/netlink/netlink_generic.h --- a/sys/netlink/netlink_generic.h +++ b/sys/netlink/netlink_generic.h @@ -31,6 +31,10 @@ #ifndef _NETLINK_NETLINK_GENERIC_H_ #define _NETLINK_NETLINK_GENERIC_H_ +#include +#include +SDT_PROVIDER_DECLARE(netlink); + #include /* Base header for all of the relevant messages */ diff --git a/sys/netlink/netlink_sysevent.c b/sys/netlink/netlink_sysevent.c --- a/sys/netlink/netlink_sysevent.c +++ b/sys/netlink/netlink_sysevent.c @@ -53,6 +53,9 @@ uint32_t id; } sysevent_groups[MAX_SYSEVENT_GROUPS] = {}; +SDT_PROBE_DEFINE4(netlink, sysevent, , send__failure, "const char *", "const char *", + "const char *", "const char *"); + static const char *devctl_systems[] = { "ACPI", "AEON", @@ -84,16 +87,22 @@ if (!nl_writer_group(&nw, NLMSG_LARGE, NETLINK_GENERIC, se->id, 0, false)) { + SDT_PROBE4(netlink, sysevent, , send__failure, se->name, + subsystem, type, data); NL_LOG(LOG_DEBUG, "error allocating group writer"); return; } struct nlmsghdr hdr = { .nlmsg_type = ctrl_family_id }; if (!nlmsg_reply(&nw, &hdr, sizeof(struct genlmsghdr))) { + SDT_PROBE4(netlink, sysevent, , send__failure, se->name, + subsystem, type, data); return; } struct genlmsghdr *ghdr = nlmsg_reserve_object(&nw, struct genlmsghdr); if (ghdr == NULL) { + SDT_PROBE4(netlink, sysevent, , send__failure, se->name, + subsystem, type, data); NL_LOG(LOG_DEBUG, "unable to allocate memory"); return; } @@ -127,6 +136,15 @@ { for (size_t i = 0; i < MAX_SYSEVENT_GROUPS; i++) { if (sysevent_groups[i].name == NULL) { + /* + * We can be called from non-sleepable contexts, in + * which case we can't register a new event (requires + * both an allocation and taking an sx in genl + * registration). + */ + if (!THREAD_CAN_SLEEP()) + break; + sysevent_new_group(i, system); return (&sysevent_groups[i]); } @@ -144,6 +162,8 @@ struct sysevent_group *se = sysevent_get_group(system); if (se == NULL) { + SDT_PROBE4(netlink, sysevent, , send__failure, system, + subsystem, type, data); NL_LOG(LOG_WARNING, "impossible to add the event %s, " "too many event groups\n", system); return;