forked from mirrors/linux
		
	devlink: protect devlink->dev by the instance lock
devlink->dev is assumed to be always valid as long as any outstanding reference to the devlink instance exists. In prep for weakening of the references take the instance lock. Signed-off-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									7a54a5195b
								
							
						
					
					
						commit
						870c7ad4a5
					
				
					 3 changed files with 11 additions and 8 deletions
				
			
		|  | @ -131,7 +131,8 @@ struct devlink_gen_cmd { | |||
| 
 | ||||
| extern const struct genl_small_ops devlink_nl_ops[56]; | ||||
| 
 | ||||
| struct devlink *devlink_get_from_attrs(struct net *net, struct nlattr **attrs); | ||||
| struct devlink * | ||||
| devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs); | ||||
| 
 | ||||
| void devlink_notify_unregister(struct devlink *devlink); | ||||
| void devlink_notify_register(struct devlink *devlink); | ||||
|  |  | |||
|  | @ -6314,12 +6314,10 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, | |||
| 
 | ||||
| 	start_offset = state->start_offset; | ||||
| 
 | ||||
| 	devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); | ||||
| 	devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs); | ||||
| 	if (IS_ERR(devlink)) | ||||
| 		return PTR_ERR(devlink); | ||||
| 
 | ||||
| 	devl_lock(devlink); | ||||
| 
 | ||||
| 	if (!attrs[DEVLINK_ATTR_REGION_NAME]) { | ||||
| 		NL_SET_ERR_MSG(cb->extack, "No region name provided"); | ||||
| 		err = -EINVAL; | ||||
|  | @ -7735,9 +7733,10 @@ devlink_health_reporter_get_from_cb(struct netlink_callback *cb) | |||
| 	struct nlattr **attrs = info->attrs; | ||||
| 	struct devlink *devlink; | ||||
| 
 | ||||
| 	devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs); | ||||
| 	devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs); | ||||
| 	if (IS_ERR(devlink)) | ||||
| 		return NULL; | ||||
| 	devl_unlock(devlink); | ||||
| 
 | ||||
| 	reporter = devlink_health_reporter_get_from_attrs(devlink, attrs); | ||||
| 	devlink_put(devlink); | ||||
|  |  | |||
|  | @ -82,7 +82,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { | |||
| 	[DEVLINK_ATTR_REGION_DIRECT] = { .type = NLA_FLAG }, | ||||
| }; | ||||
| 
 | ||||
| struct devlink *devlink_get_from_attrs(struct net *net, struct nlattr **attrs) | ||||
| struct devlink * | ||||
| devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs) | ||||
| { | ||||
| 	struct devlink *devlink; | ||||
| 	unsigned long index; | ||||
|  | @ -96,9 +97,11 @@ struct devlink *devlink_get_from_attrs(struct net *net, struct nlattr **attrs) | |||
| 	devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]); | ||||
| 
 | ||||
| 	devlinks_xa_for_each_registered_get(net, index, devlink) { | ||||
| 		devl_lock(devlink); | ||||
| 		if (strcmp(devlink->dev->bus->name, busname) == 0 && | ||||
| 		    strcmp(dev_name(devlink->dev), devname) == 0) | ||||
| 			return devlink; | ||||
| 		devl_unlock(devlink); | ||||
| 		devlink_put(devlink); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -113,10 +116,10 @@ static int devlink_nl_pre_doit(const struct genl_split_ops *ops, | |||
| 	struct devlink *devlink; | ||||
| 	int err; | ||||
| 
 | ||||
| 	devlink = devlink_get_from_attrs(genl_info_net(info), info->attrs); | ||||
| 	devlink = devlink_get_from_attrs_lock(genl_info_net(info), info->attrs); | ||||
| 	if (IS_ERR(devlink)) | ||||
| 		return PTR_ERR(devlink); | ||||
| 	devl_lock(devlink); | ||||
| 
 | ||||
| 	info->user_ptr[0] = devlink; | ||||
| 	if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) { | ||||
| 		devlink_port = devlink_port_get_from_info(devlink, info); | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jakub Kicinski
						Jakub Kicinski