OSDN Git Service

devlink: Add support for direct reporter health state update
authorEran Ben Elisha <eranbe@mellanox.com>
Sun, 3 Mar 2019 08:57:30 +0000 (10:57 +0200)
committerDavid S. Miller <davem@davemloft.net>
Mon, 4 Mar 2019 19:00:43 +0000 (11:00 -0800)
It is possible that a reporter state will be updated due to a recover flow
which is not triggered by a devlink health related operation, but as a side
effect of some other operation in the system.

Expose devlink health API for a direct update of a reporter status.

Move devlink_health_reporter_state enum definition to devlink.h so it could
be used from drivers as a parameter of devlink_health_reporter_state_update.

In addition, add trace_devlink_health_reporter_state_update to provide user
notification for reporter state change.

Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/devlink.h
include/trace/events/devlink.h
net/core/devlink.c

index 7f5a0bd..63de99e 100644 (file)
@@ -447,6 +447,11 @@ typedef void devlink_snapshot_data_dest_t(const void *data);
 struct devlink_fmsg;
 struct devlink_health_reporter;
 
+enum devlink_health_reporter_state {
+       DEVLINK_HEALTH_REPORTER_STATE_HEALTHY,
+       DEVLINK_HEALTH_REPORTER_STATE_ERROR,
+};
+
 /**
  * struct devlink_health_reporter_ops - Reporter operations
  * @name: reporter name
@@ -715,6 +720,9 @@ void *
 devlink_health_reporter_priv(struct devlink_health_reporter *reporter);
 int devlink_health_report(struct devlink_health_reporter *reporter,
                          const char *msg, void *priv_ctx);
+void
+devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
+                                    enum devlink_health_reporter_state state);
 
 void devlink_compat_running_version(struct net_device *dev,
                                    char *buf, size_t len);
@@ -1205,6 +1213,12 @@ devlink_health_report(struct devlink_health_reporter *reporter,
 }
 
 static inline void
+devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
+                                    enum devlink_health_reporter_state state)
+{
+}
+
+static inline void
 devlink_compat_running_version(struct net_device *dev, char *buf, size_t len)
 {
 }
index 191ddf6..6f60a78 100644 (file)
@@ -140,6 +140,37 @@ TRACE_EVENT(devlink_health_recover_aborted,
                  __entry->time_since_last_recover)
 );
 
+/*
+ * Tracepoint for devlink health reporter state update:
+ */
+TRACE_EVENT(devlink_health_reporter_state_update,
+       TP_PROTO(const struct devlink *devlink, const char *reporter_name,
+                bool new_state),
+
+       TP_ARGS(devlink, reporter_name, new_state),
+
+       TP_STRUCT__entry(
+               __string(bus_name, devlink->dev->bus->name)
+               __string(dev_name, dev_name(devlink->dev))
+               __string(driver_name, devlink->dev->driver->name)
+               __string(reporter_name, reporter_name)
+               __field(u8, new_state)
+       ),
+
+       TP_fast_assign(
+               __assign_str(bus_name, devlink->dev->bus->name);
+               __assign_str(dev_name, dev_name(devlink->dev));
+               __assign_str(driver_name, devlink->dev->driver->name);
+               __assign_str(reporter_name, reporter_name);
+               __entry->new_state = new_state;
+       ),
+
+       TP_printk("bus_name=%s dev_name=%s driver_name=%s reporter_name=%s: new_state=%d",
+                 __get_str(bus_name), __get_str(dev_name),
+                 __get_str(driver_name), __get_str(reporter_name),
+                 __entry->new_state)
+);
+
 #endif /* _TRACE_DEVLINK_H */
 
 /* This part must be outside protection */
index 376e01a..78e22ce 100644 (file)
@@ -4409,11 +4409,6 @@ struct devlink_health_reporter {
        u64 last_recovery_ts;
 };
 
-enum devlink_health_reporter_state {
-       DEVLINK_HEALTH_REPORTER_STATE_HEALTHY,
-       DEVLINK_HEALTH_REPORTER_STATE_ERROR,
-};
-
 void *
 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
 {
@@ -4498,6 +4493,23 @@ devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
 }
 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
 
+void
+devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
+                                    enum devlink_health_reporter_state state)
+{
+       if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
+                   state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
+               return;
+
+       if (reporter->health_state == state)
+               return;
+
+       reporter->health_state = state;
+       trace_devlink_health_reporter_state_update(reporter->devlink,
+                                                  reporter->ops->name, state);
+}
+EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
+
 static int
 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
                                void *priv_ctx)