mm: create the new vm_fault_t type
[linux-2.6-microblaze.git] / net / core / devlink.c
index 04d9855..78e22ce 100644 (file)
@@ -723,7 +723,7 @@ static int devlink_port_type_set(struct devlink *devlink,
 {
        int err;
 
-       if (devlink->ops && devlink->ops->port_type_set) {
+       if (devlink->ops->port_type_set) {
                if (port_type == DEVLINK_PORT_TYPE_NOTSET)
                        return -EINVAL;
                if (port_type == devlink_port->type)
@@ -760,7 +760,7 @@ static int devlink_port_split(struct devlink *devlink, u32 port_index,
                              u32 count, struct netlink_ext_ack *extack)
 
 {
-       if (devlink->ops && devlink->ops->port_split)
+       if (devlink->ops->port_split)
                return devlink->ops->port_split(devlink, port_index, count,
                                                extack);
        return -EOPNOTSUPP;
@@ -786,7 +786,7 @@ static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
                                struct netlink_ext_ack *extack)
 
 {
-       if (devlink->ops && devlink->ops->port_unsplit)
+       if (devlink->ops->port_unsplit)
                return devlink->ops->port_unsplit(devlink, port_index, extack);
        return -EOPNOTSUPP;
 }
@@ -961,7 +961,7 @@ static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
        if (err)
                return err;
 
-       if (!devlink->ops || !devlink->ops->sb_pool_get)
+       if (!devlink->ops->sb_pool_get)
                return -EOPNOTSUPP;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -1017,7 +1017,7 @@ static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
        mutex_lock(&devlink_mutex);
        list_for_each_entry(devlink, &devlink_list, list) {
                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
-                   !devlink->ops || !devlink->ops->sb_pool_get)
+                   !devlink->ops->sb_pool_get)
                        continue;
                mutex_lock(&devlink->lock);
                list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
@@ -1046,7 +1046,7 @@ static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
 {
        const struct devlink_ops *ops = devlink->ops;
 
-       if (ops && ops->sb_pool_set)
+       if (ops->sb_pool_set)
                return ops->sb_pool_set(devlink, sb_index, pool_index,
                                        size, threshold_type);
        return -EOPNOTSUPP;
@@ -1151,7 +1151,7 @@ static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
        if (err)
                return err;
 
-       if (!devlink->ops || !devlink->ops->sb_port_pool_get)
+       if (!devlink->ops->sb_port_pool_get)
                return -EOPNOTSUPP;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -1213,7 +1213,7 @@ static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
        mutex_lock(&devlink_mutex);
        list_for_each_entry(devlink, &devlink_list, list) {
                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
-                   !devlink->ops || !devlink->ops->sb_port_pool_get)
+                   !devlink->ops->sb_port_pool_get)
                        continue;
                mutex_lock(&devlink->lock);
                list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
@@ -1242,7 +1242,7 @@ static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
 {
        const struct devlink_ops *ops = devlink_port->devlink->ops;
 
-       if (ops && ops->sb_port_pool_set)
+       if (ops->sb_port_pool_set)
                return ops->sb_port_pool_set(devlink_port, sb_index,
                                             pool_index, threshold);
        return -EOPNOTSUPP;
@@ -1355,7 +1355,7 @@ static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
        if (err)
                return err;
 
-       if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
+       if (!devlink->ops->sb_tc_pool_bind_get)
                return -EOPNOTSUPP;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -1439,7 +1439,7 @@ devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
        mutex_lock(&devlink_mutex);
        list_for_each_entry(devlink, &devlink_list, list) {
                if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
-                   !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
+                   !devlink->ops->sb_tc_pool_bind_get)
                        continue;
 
                mutex_lock(&devlink->lock);
@@ -1471,7 +1471,7 @@ static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
 {
        const struct devlink_ops *ops = devlink_port->devlink->ops;
 
-       if (ops && ops->sb_tc_pool_bind_set)
+       if (ops->sb_tc_pool_bind_set)
                return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
                                                tc_index, pool_type,
                                                pool_index, threshold);
@@ -1519,7 +1519,7 @@ static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
        struct devlink_sb *devlink_sb = info->user_ptr[1];
        const struct devlink_ops *ops = devlink->ops;
 
-       if (ops && ops->sb_occ_snapshot)
+       if (ops->sb_occ_snapshot)
                return ops->sb_occ_snapshot(devlink, devlink_sb->index);
        return -EOPNOTSUPP;
 }
@@ -1531,7 +1531,7 @@ static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
        struct devlink_sb *devlink_sb = info->user_ptr[1];
        const struct devlink_ops *ops = devlink->ops;
 
-       if (ops && ops->sb_occ_max_clear)
+       if (ops->sb_occ_max_clear)
                return ops->sb_occ_max_clear(devlink, devlink_sb->index);
        return -EOPNOTSUPP;
 }
@@ -1594,13 +1594,9 @@ static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
                                           struct genl_info *info)
 {
        struct devlink *devlink = info->user_ptr[0];
-       const struct devlink_ops *ops = devlink->ops;
        struct sk_buff *msg;
        int err;
 
-       if (!ops)
-               return -EOPNOTSUPP;
-
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return -ENOMEM;
@@ -1625,9 +1621,6 @@ static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
        int err = 0;
        u16 mode;
 
-       if (!ops)
-               return -EOPNOTSUPP;
-
        if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
                if (!ops->eswitch_mode_set)
                        return -EOPNOTSUPP;
@@ -3869,7 +3862,7 @@ static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
        struct sk_buff *msg;
        int err;
 
-       if (!devlink->ops || !devlink->ops->info_get)
+       if (!devlink->ops->info_get)
                return -EOPNOTSUPP;
 
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -4416,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)
 {
@@ -4505,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)
@@ -4576,16 +4581,19 @@ dump_err:
 int devlink_health_report(struct devlink_health_reporter *reporter,
                          const char *msg, void *priv_ctx)
 {
+       enum devlink_health_reporter_state prev_health_state;
        struct devlink *devlink = reporter->devlink;
 
        /* write a log message of the current error */
        WARN_ON(!msg);
        trace_devlink_health_report(devlink, reporter->ops->name, msg);
        reporter->error_count++;
+       prev_health_state = reporter->health_state;
+       reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
 
        /* abort if the previous error wasn't recovered */
        if (reporter->auto_recover &&
-           (reporter->health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
+           (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
             jiffies - reporter->last_recovery_ts <
             msecs_to_jiffies(reporter->graceful_period))) {
                trace_devlink_health_recover_aborted(devlink,
@@ -4650,17 +4658,19 @@ devlink_nl_health_reporter_fill(struct sk_buff *msg,
        if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
                       reporter->health_state))
                goto reporter_nest_cancel;
-       if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR,
+       if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
                              reporter->error_count, DEVLINK_ATTR_PAD))
                goto reporter_nest_cancel;
-       if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER,
+       if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
                              reporter->recovery_count, DEVLINK_ATTR_PAD))
                goto reporter_nest_cancel;
-       if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
+       if (reporter->ops->recover &&
+           nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
                              reporter->graceful_period,
                              DEVLINK_ATTR_PAD))
                goto reporter_nest_cancel;
-       if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
+       if (reporter->ops->recover &&
+           nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
                       reporter->auto_recover))
                goto reporter_nest_cancel;
        if (reporter->dump_fmsg &&
@@ -5230,6 +5240,9 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
 {
        struct devlink *devlink;
 
+       if (WARN_ON(!ops))
+               return NULL;
+
        devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
        if (!devlink)
                return NULL;
@@ -5251,6 +5264,7 @@ EXPORT_SYMBOL_GPL(devlink_alloc);
  *     devlink_register - Register devlink instance
  *
  *     @devlink: devlink
+ *     @dev: parent device
  */
 int devlink_register(struct devlink *devlink, struct device *dev)
 {
@@ -5301,7 +5315,7 @@ EXPORT_SYMBOL_GPL(devlink_free);
  *
  *     @devlink: devlink
  *     @devlink_port: devlink port
- *     @port_index
+ *     @port_index: driver-specific numerical identifier of the port
  *
  *     Register devlink port with provided port index. User can use
  *     any indexing, even hw-related one. devlink_port structure
@@ -5631,13 +5645,10 @@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
  *
  *     @devlink: devlink
  *     @resource_name: resource's name
- *     @top_hierarchy: top hierarchy
- *     @reload_required: reload is required for new configuration to
- *                       apply
  *     @resource_size: resource's size
  *     @resource_id: resource's id
- *     @parent_reosurce_id: resource's parent id
- *     @size params: size parameters
+ *     @parent_resource_id: resource's parent id
+ *     @size_params: size parameters
  */
 int devlink_resource_register(struct devlink *devlink,
                              const char *resource_name,
@@ -6089,7 +6100,7 @@ __devlink_param_driverinit_value_set(struct devlink *devlink,
 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
                                       union devlink_param_value *init_val)
 {
-       if (!devlink->ops || !devlink->ops->reload)
+       if (!devlink->ops->reload)
                return -EOPNOTSUPP;
 
        return __devlink_param_driverinit_value_get(&devlink->param_list,
@@ -6136,7 +6147,7 @@ int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
 {
        struct devlink *devlink = devlink_port->devlink;
 
-       if (!devlink->ops || !devlink->ops->reload)
+       if (!devlink->ops->reload)
                return -EOPNOTSUPP;
 
        return __devlink_param_driverinit_value_get(&devlink_port->param_list,
@@ -6334,7 +6345,7 @@ EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get);
  *     Multiple snapshots can be created on a region.
  *     The @snapshot_id should be obtained using the getter function.
  *
- *     @devlink_region: devlink region of the snapshot
+ *     @region: devlink region of the snapshot
  *     @data_len: size of snapshot data
  *     @data: snapshot data
  *     @snapshot_id: snapshot id to be created
@@ -6395,9 +6406,6 @@ static void __devlink_compat_running_version(struct devlink *devlink,
        struct sk_buff *msg;
        int rem, err;
 
-       if (!devlink->ops->info_get)
-               return;
-
        msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
@@ -6429,71 +6437,54 @@ free_msg:
 void devlink_compat_running_version(struct net_device *dev,
                                    char *buf, size_t len)
 {
-       struct devlink_port *devlink_port;
        struct devlink *devlink;
 
+       dev_hold(dev);
+       rtnl_unlock();
+
        mutex_lock(&devlink_mutex);
-       list_for_each_entry(devlink, &devlink_list, list) {
-               mutex_lock(&devlink->lock);
-               list_for_each_entry(devlink_port, &devlink->port_list, list) {
-                       if (devlink_port->type == DEVLINK_PORT_TYPE_ETH &&
-                           devlink_port->type_dev == dev) {
-                               __devlink_compat_running_version(devlink,
-                                                                buf, len);
-                               mutex_unlock(&devlink->lock);
-                               goto out;
-                       }
-               }
-               mutex_unlock(&devlink->lock);
-       }
-out:
+       devlink = netdev_to_devlink(dev);
+       if (!devlink || !devlink->ops->info_get)
+               goto unlock_list;
+
+       mutex_lock(&devlink->lock);
+       __devlink_compat_running_version(devlink, buf, len);
+       mutex_unlock(&devlink->lock);
+unlock_list:
        mutex_unlock(&devlink_mutex);
+
+       rtnl_lock();
+       dev_put(dev);
 }
 
 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
 {
-       struct devlink_port *devlink_port;
        struct devlink *devlink;
+       int ret = -EOPNOTSUPP;
 
-       mutex_lock(&devlink_mutex);
-       list_for_each_entry(devlink, &devlink_list, list) {
-               mutex_lock(&devlink->lock);
-               list_for_each_entry(devlink_port, &devlink->port_list, list) {
-                       int ret = -EOPNOTSUPP;
+       dev_hold(dev);
+       rtnl_unlock();
 
-                       if (devlink_port->type != DEVLINK_PORT_TYPE_ETH ||
-                           devlink_port->type_dev != dev)
-                               continue;
+       mutex_lock(&devlink_mutex);
+       devlink = netdev_to_devlink(dev);
+       if (!devlink || !devlink->ops->flash_update)
+               goto unlock_list;
 
-                       mutex_unlock(&devlink_mutex);
-                       if (devlink->ops->flash_update)
-                               ret = devlink->ops->flash_update(devlink,
-                                                                file_name,
-                                                                NULL, NULL);
-                       mutex_unlock(&devlink->lock);
-                       return ret;
-               }
-               mutex_unlock(&devlink->lock);
-       }
+       mutex_lock(&devlink->lock);
+       ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
+       mutex_unlock(&devlink->lock);
+unlock_list:
        mutex_unlock(&devlink_mutex);
 
-       return -EOPNOTSUPP;
-}
+       rtnl_lock();
+       dev_put(dev);
 
-static int __init devlink_module_init(void)
-{
-       return genl_register_family(&devlink_nl_family);
+       return ret;
 }
 
-static void __exit devlink_module_exit(void)
+static int __init devlink_init(void)
 {
-       genl_unregister_family(&devlink_nl_family);
+       return genl_register_family(&devlink_nl_family);
 }
 
-module_init(devlink_module_init);
-module_exit(devlink_module_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
-MODULE_DESCRIPTION("Network physical device Netlink interface");
-MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);
+subsys_initcall(devlink_init);