diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/core/devlink.c | 97 |
1 files changed, 74 insertions, 23 deletions
diff --git a/net/core/devlink.c b/net/core/devlink.c index 4e28d04c0165..d43bc52b8840 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 21 | #include <linux/netdevice.h> | 21 | #include <linux/netdevice.h> |
| 22 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
| 23 | #include <linux/refcount.h> | ||
| 23 | #include <rdma/ib_verbs.h> | 24 | #include <rdma/ib_verbs.h> |
| 24 | #include <net/netlink.h> | 25 | #include <net/netlink.h> |
| 25 | #include <net/genetlink.h> | 26 | #include <net/genetlink.h> |
| @@ -4432,6 +4433,7 @@ struct devlink_health_reporter { | |||
| 4432 | u64 error_count; | 4433 | u64 error_count; |
| 4433 | u64 recovery_count; | 4434 | u64 recovery_count; |
| 4434 | u64 last_recovery_ts; | 4435 | u64 last_recovery_ts; |
| 4436 | refcount_t refcount; | ||
| 4435 | }; | 4437 | }; |
| 4436 | 4438 | ||
| 4437 | void * | 4439 | void * |
| @@ -4447,6 +4449,7 @@ devlink_health_reporter_find_by_name(struct devlink *devlink, | |||
| 4447 | { | 4449 | { |
| 4448 | struct devlink_health_reporter *reporter; | 4450 | struct devlink_health_reporter *reporter; |
| 4449 | 4451 | ||
| 4452 | lockdep_assert_held(&devlink->reporters_lock); | ||
| 4450 | list_for_each_entry(reporter, &devlink->reporter_list, list) | 4453 | list_for_each_entry(reporter, &devlink->reporter_list, list) |
| 4451 | if (!strcmp(reporter->ops->name, reporter_name)) | 4454 | if (!strcmp(reporter->ops->name, reporter_name)) |
| 4452 | return reporter; | 4455 | return reporter; |
| @@ -4470,7 +4473,7 @@ devlink_health_reporter_create(struct devlink *devlink, | |||
| 4470 | { | 4473 | { |
| 4471 | struct devlink_health_reporter *reporter; | 4474 | struct devlink_health_reporter *reporter; |
| 4472 | 4475 | ||
| 4473 | mutex_lock(&devlink->lock); | 4476 | mutex_lock(&devlink->reporters_lock); |
| 4474 | if (devlink_health_reporter_find_by_name(devlink, ops->name)) { | 4477 | if (devlink_health_reporter_find_by_name(devlink, ops->name)) { |
| 4475 | reporter = ERR_PTR(-EEXIST); | 4478 | reporter = ERR_PTR(-EEXIST); |
| 4476 | goto unlock; | 4479 | goto unlock; |
| @@ -4494,9 +4497,10 @@ devlink_health_reporter_create(struct devlink *devlink, | |||
| 4494 | reporter->graceful_period = graceful_period; | 4497 | reporter->graceful_period = graceful_period; |
| 4495 | reporter->auto_recover = auto_recover; | 4498 | reporter->auto_recover = auto_recover; |
| 4496 | mutex_init(&reporter->dump_lock); | 4499 | mutex_init(&reporter->dump_lock); |
| 4500 | refcount_set(&reporter->refcount, 1); | ||
| 4497 | list_add_tail(&reporter->list, &devlink->reporter_list); | 4501 | list_add_tail(&reporter->list, &devlink->reporter_list); |
| 4498 | unlock: | 4502 | unlock: |
| 4499 | mutex_unlock(&devlink->lock); | 4503 | mutex_unlock(&devlink->reporters_lock); |
| 4500 | return reporter; | 4504 | return reporter; |
| 4501 | } | 4505 | } |
| 4502 | EXPORT_SYMBOL_GPL(devlink_health_reporter_create); | 4506 | EXPORT_SYMBOL_GPL(devlink_health_reporter_create); |
| @@ -4509,10 +4513,12 @@ EXPORT_SYMBOL_GPL(devlink_health_reporter_create); | |||
| 4509 | void | 4513 | void |
| 4510 | devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) | 4514 | devlink_health_reporter_destroy(struct devlink_health_reporter *reporter) |
| 4511 | { | 4515 | { |
| 4512 | mutex_lock(&reporter->devlink->lock); | 4516 | mutex_lock(&reporter->devlink->reporters_lock); |
| 4513 | list_del(&reporter->list); | 4517 | list_del(&reporter->list); |
| 4518 | mutex_unlock(&reporter->devlink->reporters_lock); | ||
| 4519 | while (refcount_read(&reporter->refcount) > 1) | ||
| 4520 | msleep(100); | ||
| 4514 | mutex_destroy(&reporter->dump_lock); | 4521 | mutex_destroy(&reporter->dump_lock); |
| 4515 | mutex_unlock(&reporter->devlink->lock); | ||
| 4516 | if (reporter->dump_fmsg) | 4522 | if (reporter->dump_fmsg) |
| 4517 | devlink_fmsg_free(reporter->dump_fmsg); | 4523 | devlink_fmsg_free(reporter->dump_fmsg); |
| 4518 | kfree(reporter); | 4524 | kfree(reporter); |
| @@ -4648,6 +4654,7 @@ static struct devlink_health_reporter * | |||
| 4648 | devlink_health_reporter_get_from_info(struct devlink *devlink, | 4654 | devlink_health_reporter_get_from_info(struct devlink *devlink, |
| 4649 | struct genl_info *info) | 4655 | struct genl_info *info) |
| 4650 | { | 4656 | { |
| 4657 | struct devlink_health_reporter *reporter; | ||
| 4651 | char *reporter_name; | 4658 | char *reporter_name; |
| 4652 | 4659 | ||
| 4653 | if (!info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]) | 4660 | if (!info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]) |
| @@ -4655,7 +4662,18 @@ devlink_health_reporter_get_from_info(struct devlink *devlink, | |||
| 4655 | 4662 | ||
| 4656 | reporter_name = | 4663 | reporter_name = |
| 4657 | nla_data(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]); | 4664 | nla_data(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]); |
| 4658 | return devlink_health_reporter_find_by_name(devlink, reporter_name); | 4665 | mutex_lock(&devlink->reporters_lock); |
| 4666 | reporter = devlink_health_reporter_find_by_name(devlink, reporter_name); | ||
| 4667 | if (reporter) | ||
| 4668 | refcount_inc(&reporter->refcount); | ||
| 4669 | mutex_unlock(&devlink->reporters_lock); | ||
| 4670 | return reporter; | ||
| 4671 | } | ||
| 4672 | |||
| 4673 | static void | ||
| 4674 | devlink_health_reporter_put(struct devlink_health_reporter *reporter) | ||
| 4675 | { | ||
| 4676 | refcount_dec(&reporter->refcount); | ||
| 4659 | } | 4677 | } |
| 4660 | 4678 | ||
| 4661 | static int | 4679 | static int |
| @@ -4730,8 +4748,10 @@ static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, | |||
| 4730 | return -EINVAL; | 4748 | return -EINVAL; |
| 4731 | 4749 | ||
| 4732 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 4750 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
| 4733 | if (!msg) | 4751 | if (!msg) { |
| 4734 | return -ENOMEM; | 4752 | err = -ENOMEM; |
| 4753 | goto out; | ||
| 4754 | } | ||
| 4735 | 4755 | ||
| 4736 | err = devlink_nl_health_reporter_fill(msg, devlink, reporter, | 4756 | err = devlink_nl_health_reporter_fill(msg, devlink, reporter, |
| 4737 | DEVLINK_CMD_HEALTH_REPORTER_GET, | 4757 | DEVLINK_CMD_HEALTH_REPORTER_GET, |
| @@ -4739,10 +4759,13 @@ static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, | |||
| 4739 | 0); | 4759 | 0); |
| 4740 | if (err) { | 4760 | if (err) { |
| 4741 | nlmsg_free(msg); | 4761 | nlmsg_free(msg); |
| 4742 | return err; | 4762 | goto out; |
| 4743 | } | 4763 | } |
| 4744 | 4764 | ||
| 4745 | return genlmsg_reply(msg, info); | 4765 | err = genlmsg_reply(msg, info); |
| 4766 | out: | ||
| 4767 | devlink_health_reporter_put(reporter); | ||
| 4768 | return err; | ||
| 4746 | } | 4769 | } |
| 4747 | 4770 | ||
| 4748 | static int | 4771 | static int |
| @@ -4759,7 +4782,7 @@ devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg, | |||
| 4759 | list_for_each_entry(devlink, &devlink_list, list) { | 4782 | list_for_each_entry(devlink, &devlink_list, list) { |
| 4760 | if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) | 4783 | if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) |
| 4761 | continue; | 4784 | continue; |
| 4762 | mutex_lock(&devlink->lock); | 4785 | mutex_lock(&devlink->reporters_lock); |
| 4763 | list_for_each_entry(reporter, &devlink->reporter_list, | 4786 | list_for_each_entry(reporter, &devlink->reporter_list, |
| 4764 | list) { | 4787 | list) { |
| 4765 | if (idx < start) { | 4788 | if (idx < start) { |
| @@ -4773,12 +4796,12 @@ devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg, | |||
| 4773 | cb->nlh->nlmsg_seq, | 4796 | cb->nlh->nlmsg_seq, |
| 4774 | NLM_F_MULTI); | 4797 | NLM_F_MULTI); |
| 4775 | if (err) { | 4798 | if (err) { |
| 4776 | mutex_unlock(&devlink->lock); | 4799 | mutex_unlock(&devlink->reporters_lock); |
| 4777 | goto out; | 4800 | goto out; |
| 4778 | } | 4801 | } |
| 4779 | idx++; | 4802 | idx++; |
| 4780 | } | 4803 | } |
| 4781 | mutex_unlock(&devlink->lock); | 4804 | mutex_unlock(&devlink->reporters_lock); |
| 4782 | } | 4805 | } |
| 4783 | out: | 4806 | out: |
| 4784 | mutex_unlock(&devlink_mutex); | 4807 | mutex_unlock(&devlink_mutex); |
| @@ -4793,6 +4816,7 @@ devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, | |||
| 4793 | { | 4816 | { |
| 4794 | struct devlink *devlink = info->user_ptr[0]; | 4817 | struct devlink *devlink = info->user_ptr[0]; |
| 4795 | struct devlink_health_reporter *reporter; | 4818 | struct devlink_health_reporter *reporter; |
| 4819 | int err; | ||
| 4796 | 4820 | ||
| 4797 | reporter = devlink_health_reporter_get_from_info(devlink, info); | 4821 | reporter = devlink_health_reporter_get_from_info(devlink, info); |
| 4798 | if (!reporter) | 4822 | if (!reporter) |
| @@ -4800,8 +4824,10 @@ devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, | |||
| 4800 | 4824 | ||
| 4801 | if (!reporter->ops->recover && | 4825 | if (!reporter->ops->recover && |
| 4802 | (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] || | 4826 | (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] || |
| 4803 | info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) | 4827 | info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])) { |
| 4804 | return -EOPNOTSUPP; | 4828 | err = -EOPNOTSUPP; |
| 4829 | goto out; | ||
| 4830 | } | ||
| 4805 | 4831 | ||
| 4806 | if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]) | 4832 | if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]) |
| 4807 | reporter->graceful_period = | 4833 | reporter->graceful_period = |
| @@ -4811,7 +4837,11 @@ devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb, | |||
| 4811 | reporter->auto_recover = | 4837 | reporter->auto_recover = |
| 4812 | nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]); | 4838 | nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]); |
| 4813 | 4839 | ||
| 4840 | devlink_health_reporter_put(reporter); | ||
| 4814 | return 0; | 4841 | return 0; |
| 4842 | out: | ||
| 4843 | devlink_health_reporter_put(reporter); | ||
| 4844 | return err; | ||
| 4815 | } | 4845 | } |
| 4816 | 4846 | ||
| 4817 | static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, | 4847 | static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, |
| @@ -4819,12 +4849,16 @@ static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, | |||
| 4819 | { | 4849 | { |
| 4820 | struct devlink *devlink = info->user_ptr[0]; | 4850 | struct devlink *devlink = info->user_ptr[0]; |
| 4821 | struct devlink_health_reporter *reporter; | 4851 | struct devlink_health_reporter *reporter; |
| 4852 | int err; | ||
| 4822 | 4853 | ||
| 4823 | reporter = devlink_health_reporter_get_from_info(devlink, info); | 4854 | reporter = devlink_health_reporter_get_from_info(devlink, info); |
| 4824 | if (!reporter) | 4855 | if (!reporter) |
| 4825 | return -EINVAL; | 4856 | return -EINVAL; |
| 4826 | 4857 | ||
| 4827 | return devlink_health_reporter_recover(reporter, NULL); | 4858 | err = devlink_health_reporter_recover(reporter, NULL); |
| 4859 | |||
| 4860 | devlink_health_reporter_put(reporter); | ||
| 4861 | return err; | ||
| 4828 | } | 4862 | } |
| 4829 | 4863 | ||
| 4830 | static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, | 4864 | static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, |
| @@ -4839,12 +4873,16 @@ static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, | |||
| 4839 | if (!reporter) | 4873 | if (!reporter) |
| 4840 | return -EINVAL; | 4874 | return -EINVAL; |
| 4841 | 4875 | ||
| 4842 | if (!reporter->ops->diagnose) | 4876 | if (!reporter->ops->diagnose) { |
| 4877 | devlink_health_reporter_put(reporter); | ||
| 4843 | return -EOPNOTSUPP; | 4878 | return -EOPNOTSUPP; |
| 4879 | } | ||
| 4844 | 4880 | ||
| 4845 | fmsg = devlink_fmsg_alloc(); | 4881 | fmsg = devlink_fmsg_alloc(); |
| 4846 | if (!fmsg) | 4882 | if (!fmsg) { |
| 4883 | devlink_health_reporter_put(reporter); | ||
| 4847 | return -ENOMEM; | 4884 | return -ENOMEM; |
| 4885 | } | ||
| 4848 | 4886 | ||
| 4849 | err = devlink_fmsg_obj_nest_start(fmsg); | 4887 | err = devlink_fmsg_obj_nest_start(fmsg); |
| 4850 | if (err) | 4888 | if (err) |
| @@ -4863,6 +4901,7 @@ static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, | |||
| 4863 | 4901 | ||
| 4864 | out: | 4902 | out: |
| 4865 | devlink_fmsg_free(fmsg); | 4903 | devlink_fmsg_free(fmsg); |
| 4904 | devlink_health_reporter_put(reporter); | ||
| 4866 | return err; | 4905 | return err; |
| 4867 | } | 4906 | } |
| 4868 | 4907 | ||
| @@ -4877,8 +4916,10 @@ static int devlink_nl_cmd_health_reporter_dump_get_doit(struct sk_buff *skb, | |||
| 4877 | if (!reporter) | 4916 | if (!reporter) |
| 4878 | return -EINVAL; | 4917 | return -EINVAL; |
| 4879 | 4918 | ||
| 4880 | if (!reporter->ops->dump) | 4919 | if (!reporter->ops->dump) { |
| 4920 | devlink_health_reporter_put(reporter); | ||
| 4881 | return -EOPNOTSUPP; | 4921 | return -EOPNOTSUPP; |
| 4922 | } | ||
| 4882 | 4923 | ||
| 4883 | mutex_lock(&reporter->dump_lock); | 4924 | mutex_lock(&reporter->dump_lock); |
| 4884 | err = devlink_health_do_dump(reporter, NULL); | 4925 | err = devlink_health_do_dump(reporter, NULL); |
| @@ -4890,6 +4931,7 @@ static int devlink_nl_cmd_health_reporter_dump_get_doit(struct sk_buff *skb, | |||
| 4890 | 4931 | ||
| 4891 | out: | 4932 | out: |
| 4892 | mutex_unlock(&reporter->dump_lock); | 4933 | mutex_unlock(&reporter->dump_lock); |
| 4934 | devlink_health_reporter_put(reporter); | ||
| 4893 | return err; | 4935 | return err; |
| 4894 | } | 4936 | } |
| 4895 | 4937 | ||
| @@ -4904,12 +4946,15 @@ devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb, | |||
| 4904 | if (!reporter) | 4946 | if (!reporter) |
| 4905 | return -EINVAL; | 4947 | return -EINVAL; |
| 4906 | 4948 | ||
| 4907 | if (!reporter->ops->dump) | 4949 | if (!reporter->ops->dump) { |
| 4950 | devlink_health_reporter_put(reporter); | ||
| 4908 | return -EOPNOTSUPP; | 4951 | return -EOPNOTSUPP; |
| 4952 | } | ||
| 4909 | 4953 | ||
| 4910 | mutex_lock(&reporter->dump_lock); | 4954 | mutex_lock(&reporter->dump_lock); |
| 4911 | devlink_health_dump_clear(reporter); | 4955 | devlink_health_dump_clear(reporter); |
| 4912 | mutex_unlock(&reporter->dump_lock); | 4956 | mutex_unlock(&reporter->dump_lock); |
| 4957 | devlink_health_reporter_put(reporter); | ||
| 4913 | return 0; | 4958 | return 0; |
| 4914 | } | 4959 | } |
| 4915 | 4960 | ||
| @@ -5191,7 +5236,8 @@ static const struct genl_ops devlink_nl_ops[] = { | |||
| 5191 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 5236 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
| 5192 | .doit = devlink_nl_cmd_health_reporter_get_doit, | 5237 | .doit = devlink_nl_cmd_health_reporter_get_doit, |
| 5193 | .dumpit = devlink_nl_cmd_health_reporter_get_dumpit, | 5238 | .dumpit = devlink_nl_cmd_health_reporter_get_dumpit, |
| 5194 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, | 5239 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | |
| 5240 | DEVLINK_NL_FLAG_NO_LOCK, | ||
| 5195 | /* can be retrieved by unprivileged users */ | 5241 | /* can be retrieved by unprivileged users */ |
| 5196 | }, | 5242 | }, |
| 5197 | { | 5243 | { |
| @@ -5199,21 +5245,24 @@ static const struct genl_ops devlink_nl_ops[] = { | |||
| 5199 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 5245 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
| 5200 | .doit = devlink_nl_cmd_health_reporter_set_doit, | 5246 | .doit = devlink_nl_cmd_health_reporter_set_doit, |
| 5201 | .flags = GENL_ADMIN_PERM, | 5247 | .flags = GENL_ADMIN_PERM, |
| 5202 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, | 5248 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | |
| 5249 | DEVLINK_NL_FLAG_NO_LOCK, | ||
| 5203 | }, | 5250 | }, |
| 5204 | { | 5251 | { |
| 5205 | .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, | 5252 | .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER, |
| 5206 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 5253 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
| 5207 | .doit = devlink_nl_cmd_health_reporter_recover_doit, | 5254 | .doit = devlink_nl_cmd_health_reporter_recover_doit, |
| 5208 | .flags = GENL_ADMIN_PERM, | 5255 | .flags = GENL_ADMIN_PERM, |
| 5209 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, | 5256 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | |
| 5257 | DEVLINK_NL_FLAG_NO_LOCK, | ||
| 5210 | }, | 5258 | }, |
| 5211 | { | 5259 | { |
| 5212 | .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, | 5260 | .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, |
| 5213 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, | 5261 | .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
| 5214 | .doit = devlink_nl_cmd_health_reporter_diagnose_doit, | 5262 | .doit = devlink_nl_cmd_health_reporter_diagnose_doit, |
| 5215 | .flags = GENL_ADMIN_PERM, | 5263 | .flags = GENL_ADMIN_PERM, |
| 5216 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK, | 5264 | .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK | |
| 5265 | DEVLINK_NL_FLAG_NO_LOCK, | ||
| 5217 | }, | 5266 | }, |
| 5218 | { | 5267 | { |
| 5219 | .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, | 5268 | .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, |
| @@ -5284,6 +5333,7 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) | |||
| 5284 | INIT_LIST_HEAD(&devlink->region_list); | 5333 | INIT_LIST_HEAD(&devlink->region_list); |
| 5285 | INIT_LIST_HEAD(&devlink->reporter_list); | 5334 | INIT_LIST_HEAD(&devlink->reporter_list); |
| 5286 | mutex_init(&devlink->lock); | 5335 | mutex_init(&devlink->lock); |
| 5336 | mutex_init(&devlink->reporters_lock); | ||
| 5287 | return devlink; | 5337 | return devlink; |
| 5288 | } | 5338 | } |
| 5289 | EXPORT_SYMBOL_GPL(devlink_alloc); | 5339 | EXPORT_SYMBOL_GPL(devlink_alloc); |
| @@ -5326,6 +5376,7 @@ EXPORT_SYMBOL_GPL(devlink_unregister); | |||
| 5326 | */ | 5376 | */ |
| 5327 | void devlink_free(struct devlink *devlink) | 5377 | void devlink_free(struct devlink *devlink) |
| 5328 | { | 5378 | { |
| 5379 | mutex_destroy(&devlink->reporters_lock); | ||
| 5329 | mutex_destroy(&devlink->lock); | 5380 | mutex_destroy(&devlink->lock); |
| 5330 | WARN_ON(!list_empty(&devlink->reporter_list)); | 5381 | WARN_ON(!list_empty(&devlink->reporter_list)); |
| 5331 | WARN_ON(!list_empty(&devlink->region_list)); | 5382 | WARN_ON(!list_empty(&devlink->region_list)); |
