forked from mirrors/linux
		
	devlink: Rework devlink health reporter destructor
Devlink keeps its own reference to every reporter in a list and inits refcount to 1 upon reporter's creation. Existing destructor waits to free the memory indefinitely using msleep() until all references except devlink's own are put. Rework this mechanism by moving memory free routine to a separate function, which is called when the last reporter reference is put. Besides, it allows to call __devlink_health_reporter_destroy() while locked on a reporters list mutex in symmetry to __devlink_health_reporter_create(), which is required in follow-up patch. Signed-off-by: Vladyslav Tarasiuk <vladyslavt@mellanox.com> Reviewed-by: Moshe Shemesh <moshe@mellanox.com> Reviewed-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									c57544b3de
								
							
						
					
					
						commit
						3c5584bf0a
					
				
					 1 changed files with 24 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -5379,6 +5379,29 @@ devlink_health_reporter_create(struct devlink *devlink,
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
devlink_health_reporter_free(struct devlink_health_reporter *reporter)
 | 
			
		||||
{
 | 
			
		||||
	mutex_destroy(&reporter->dump_lock);
 | 
			
		||||
	if (reporter->dump_fmsg)
 | 
			
		||||
		devlink_fmsg_free(reporter->dump_fmsg);
 | 
			
		||||
	kfree(reporter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
devlink_health_reporter_put(struct devlink_health_reporter *reporter)
 | 
			
		||||
{
 | 
			
		||||
	if (refcount_dec_and_test(&reporter->refcount))
 | 
			
		||||
		devlink_health_reporter_free(reporter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
__devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
 | 
			
		||||
{
 | 
			
		||||
	list_del(&reporter->list);
 | 
			
		||||
	devlink_health_reporter_put(reporter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *	devlink_health_reporter_destroy - destroy devlink health reporter
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -5388,14 +5411,8 @@ void
 | 
			
		|||
devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
 | 
			
		||||
{
 | 
			
		||||
	mutex_lock(&reporter->devlink->reporters_lock);
 | 
			
		||||
	list_del(&reporter->list);
 | 
			
		||||
	__devlink_health_reporter_destroy(reporter);
 | 
			
		||||
	mutex_unlock(&reporter->devlink->reporters_lock);
 | 
			
		||||
	while (refcount_read(&reporter->refcount) > 1)
 | 
			
		||||
		msleep(100);
 | 
			
		||||
	mutex_destroy(&reporter->dump_lock);
 | 
			
		||||
	if (reporter->dump_fmsg)
 | 
			
		||||
		devlink_fmsg_free(reporter->dump_fmsg);
 | 
			
		||||
	kfree(reporter);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5665,12 +5682,6 @@ devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
devlink_health_reporter_put(struct devlink_health_reporter *reporter)
 | 
			
		||||
{
 | 
			
		||||
	refcount_dec(&reporter->refcount);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
 | 
			
		||||
				     enum devlink_health_reporter_state state)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue