Make command workqueue persistant in mlx5core.

There is no reason to re-create the command workqueue during healthcare.
This also fixes an issue where a previous work struct may refer to a
destroyed workqueue.

MFC after:	3 days
Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2019-05-08 11:09:08 +00:00
parent cf551f955d
commit 8d1eeedb5d
3 changed files with 23 additions and 34 deletions

View File

@ -56,7 +56,6 @@ enum {
enum {
MLX5_CMD_TIMEOUT_MSEC = 60 * 1000,
MLX5_CMD_WQ_MAX_NAME = 32,
};
enum {
@ -353,8 +352,6 @@ struct mlx5_cmd {
spinlock_t token_lock;
u8 token;
unsigned long bitmask;
char wq_name[MLX5_CMD_WQ_MAX_NAME];
struct workqueue_struct *wq;
struct semaphore sem;
struct semaphore pages_sem;
enum mlx5_cmd_mode mode;
@ -516,6 +513,7 @@ struct mlx5_core_health {
struct delayed_work recover_work;
unsigned int last_reset_req;
struct work_struct work_cmd_completion;
struct workqueue_struct *wq_cmd;
};
#ifdef RATELIMIT

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2013-2017, Mellanox Technologies, Ltd. All rights reserved.
* Copyright (c) 2013-2019, Mellanox Technologies, Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -997,7 +997,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
INIT_WORK(&ent->work, cmd_work_handler);
if (page_queue) {
cmd_work_handler(&ent->work);
} else if (!queue_work(cmd->wq, &ent->work)) {
} else if (!queue_work(dev->priv.health.wq_cmd, &ent->work)) {
mlx5_core_warn(dev, "failed to queue work\n");
err = -ENOMEM;
goto out_free;
@ -1127,14 +1127,6 @@ mlx5_free_cmd_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg)
mlx5_fwp_free(msg);
}
static void set_wqname(struct mlx5_core_dev *dev)
{
struct mlx5_cmd *cmd = &dev->cmd;
snprintf(cmd->wq_name, sizeof(cmd->wq_name), "mlx5_cmd_%s",
dev_name(&dev->pdev->dev));
}
static void clean_debug_files(struct mlx5_core_dev *dev)
{
}
@ -1562,20 +1554,8 @@ int mlx5_cmd_init(struct mlx5_core_dev *dev)
device_printf((&dev->pdev->dev)->bsddev, "ERR: ""failed to create command cache\n");
goto err_free_page;
}
set_wqname(dev);
cmd->wq = create_singlethread_workqueue(cmd->wq_name);
if (!cmd->wq) {
device_printf((&dev->pdev->dev)->bsddev, "ERR: ""failed to create command workqueue\n");
err = -ENOMEM;
goto err_cache;
}
return 0;
err_cache:
destroy_msg_cache(dev);
err_free_page:
free_cmd_page(dev, cmd);
@ -1589,7 +1569,7 @@ void mlx5_cmd_cleanup(struct mlx5_core_dev *dev)
struct mlx5_cmd *cmd = &dev->cmd;
clean_debug_files(dev);
destroy_workqueue(cmd->wq);
flush_workqueue(dev->priv.health.wq_cmd);
destroy_msg_cache(dev);
free_cmd_page(dev, cmd);
}

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2013-2017, Mellanox Technologies, Ltd. All rights reserved.
* Copyright (c) 2013-2019, Mellanox Technologies, Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -280,8 +280,8 @@ void mlx5_enter_error_state(struct mlx5_core_dev *dev, bool force)
* completion handler and then wait for it to
* complete:
*/
queue_work(dev->cmd.wq, &dev->priv.health.work_cmd_completion);
flush_workqueue(dev->cmd.wq);
queue_work(dev->priv.health.wq_cmd, &dev->priv.health.work_cmd_completion);
flush_workqueue(dev->priv.health.wq_cmd);
}
mutex_lock(&dev->intf_state_mutex);
@ -679,6 +679,7 @@ void mlx5_health_cleanup(struct mlx5_core_dev *dev)
destroy_workqueue(health->wq);
destroy_workqueue(health->wq_watchdog);
destroy_workqueue(health->wq_cmd);
}
int mlx5_health_init(struct mlx5_core_dev *dev)
@ -691,14 +692,17 @@ int mlx5_health_init(struct mlx5_core_dev *dev)
snprintf(name, sizeof(name), "%s-rec", dev_name(&dev->pdev->dev));
health->wq = create_singlethread_workqueue(name);
if (!health->wq)
return -ENOMEM;
goto err_recovery;
snprintf(name, sizeof(name), "%s-wdg", dev_name(&dev->pdev->dev));
health->wq_watchdog = create_singlethread_workqueue(name);
if (!health->wq_watchdog) {
destroy_workqueue(health->wq);
return -ENOMEM;
}
if (!health->wq_watchdog)
goto err_watchdog;
snprintf(name, sizeof(name), "%s-cmd", dev_name(&dev->pdev->dev));
health->wq_cmd = create_singlethread_workqueue(name);
if (!health->wq_cmd)
goto err_cmd;
spin_lock_init(&health->wq_lock);
INIT_WORK(&health->work, health_care);
@ -707,4 +711,11 @@ int mlx5_health_init(struct mlx5_core_dev *dev)
INIT_DELAYED_WORK(&health->recover_work, health_recover);
return 0;
err_cmd:
destroy_workqueue(health->wq_watchdog);
err_watchdog:
destroy_workqueue(health->wq);
err_recovery:
return -ENOMEM;
}