From: Ido Schimmel <ido...@mellanox.com> If we lost an event, there is nothing we can do in order to recover it. Set above mentioned socket option on the netlink socket when monitoring devlink events, so that `devlink monitor` will not abort in case we are not draining the receive buffer fast enough.
The number of events we lost can be retrieved using: # cat /proc/net/netlink | grep `pidof devlink` | awk '{ print $9 }' Signed-off-by: Ido Schimmel <ido...@mellanox.com> Acked-by: Jiri Pirko <j...@mellanox.com> --- devlink/devlink.c | 22 +++++++++++++++++++++- devlink/mnlg.c | 12 ++++++++++++ devlink/mnlg.h | 2 ++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/devlink/devlink.c b/devlink/devlink.c index b9fce850ee00..817b74259ec3 100644 --- a/devlink/devlink.c +++ b/devlink/devlink.c @@ -140,6 +140,19 @@ static int _mnlg_socket_group_add(struct mnlg_socket *nlg, return 0; } +static int _mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type, + void *buf, socklen_t len) +{ + int err; + + err = mnlg_socket_setsockopt(nlg, type, buf, len); + if (err < 0) { + pr_err("Failed to call mnlg_socket_setsockopt\n"); + return -errno; + } + return 0; +} + struct ifname_map { struct list_head list; char *bus_name; @@ -4020,7 +4033,7 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data) static int cmd_mon_show(struct dl *dl) { - int err; + int err, one = 1; unsigned int index = 0; const char *cur_obj; @@ -4035,6 +4048,13 @@ static int cmd_mon_show(struct dl *dl) return -EINVAL; } } + /* It is possible to lose some events if we are not draining the socket + * receive buffer fast enough. Keep processing events and do not abort. + */ + err = _mnlg_socket_setsockopt(dl->nlg, NETLINK_NO_ENOBUFS, &one, + sizeof(one)); + if (err) + return err; err = _mnlg_socket_group_add(dl->nlg, DEVLINK_GENL_MCGRP_CONFIG_NAME); if (err) return err; diff --git a/devlink/mnlg.c b/devlink/mnlg.c index ee125df042f0..23e6e794b508 100644 --- a/devlink/mnlg.c +++ b/devlink/mnlg.c @@ -231,6 +231,18 @@ int mnlg_socket_group_add(struct mnlg_socket *nlg, const char *group_name) return 0; } +int mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type, void *buf, + socklen_t len) +{ + int err; + + err = mnl_socket_setsockopt(nlg->nl, type, buf, len); + if (err < 0) + return err; + + return 0; +} + static int get_family_id_attr_cb(const struct nlattr *attr, void *data) { const struct nlattr **tb = data; diff --git a/devlink/mnlg.h b/devlink/mnlg.h index 4d1babf3b4c2..49154215729e 100644 --- a/devlink/mnlg.h +++ b/devlink/mnlg.h @@ -21,6 +21,8 @@ struct nlmsghdr *mnlg_msg_prepare(struct mnlg_socket *nlg, uint8_t cmd, int mnlg_socket_send(struct mnlg_socket *nlg, const struct nlmsghdr *nlh); int mnlg_socket_recv_run(struct mnlg_socket *nlg, mnl_cb_t data_cb, void *data); int mnlg_socket_group_add(struct mnlg_socket *nlg, const char *group_name); +int mnlg_socket_setsockopt(struct mnlg_socket *nlg, int type, void *buf, + socklen_t len); struct mnlg_socket *mnlg_socket_open(const char *family_name, uint8_t version); void mnlg_socket_close(struct mnlg_socket *nlg); -- 2.20.1