Minor code refactor as a preparation step for suprise removal of CX-4
PCI device(s), changes: - alloc_entry() now clears bit for page slot entry aswell - update of cmd->ent_arr[] is now under cmd->alloc_lock - complete command if alloc_entry() fails MFC after: 1 week Sponsored by: Mellanox Technologies
This commit is contained in:
parent
d0ce5a0da7
commit
8e7e0ce110
@ -39,6 +39,11 @@
|
||||
|
||||
#include "mlx5_core.h"
|
||||
|
||||
static int mlx5_copy_from_msg(void *to, struct mlx5_cmd_msg *from, int size);
|
||||
static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
|
||||
struct mlx5_cmd_msg *msg);
|
||||
static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
|
||||
|
||||
enum {
|
||||
CMD_IF_REV = 5,
|
||||
};
|
||||
@ -110,18 +115,27 @@ static u8 alloc_token(struct mlx5_cmd *cmd)
|
||||
return token;
|
||||
}
|
||||
|
||||
static int alloc_ent(struct mlx5_cmd *cmd)
|
||||
static int alloc_ent(struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
struct mlx5_cmd *cmd = ent->cmd;
|
||||
int ret = cmd->max_reg_cmds;
|
||||
|
||||
spin_lock_irqsave(&cmd->alloc_lock, flags);
|
||||
ret = find_first_bit(&cmd->bitmask, cmd->max_reg_cmds);
|
||||
if (ret < cmd->max_reg_cmds)
|
||||
clear_bit(ret, &cmd->bitmask);
|
||||
if (!ent->page_queue) {
|
||||
ret = find_first_bit(&cmd->bitmask, cmd->max_reg_cmds);
|
||||
if (ret >= cmd->max_reg_cmds)
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if (ret != -1) {
|
||||
ent->idx = ret;
|
||||
clear_bit(ent->idx, &cmd->bitmask);
|
||||
cmd->ent_arr[ent->idx] = ent;
|
||||
}
|
||||
spin_unlock_irqrestore(&cmd->alloc_lock, flags);
|
||||
|
||||
return ret < cmd->max_reg_cmds ? ret : -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void free_ent(struct mlx5_cmd *cmd, int idx)
|
||||
@ -704,6 +718,49 @@ static void dump_command(struct mlx5_core_dev *dev,
|
||||
pr_debug("\n");
|
||||
}
|
||||
|
||||
static void complete_command(struct mlx5_cmd_work_ent *ent)
|
||||
{
|
||||
struct mlx5_cmd *cmd = ent->cmd;
|
||||
struct mlx5_core_dev *dev = container_of(cmd, struct mlx5_core_dev,
|
||||
cmd);
|
||||
s64 ds;
|
||||
struct mlx5_cmd_stats *stats;
|
||||
unsigned long flags;
|
||||
int err;
|
||||
struct semaphore *sem;
|
||||
|
||||
if (ent->page_queue)
|
||||
sem = &cmd->pages_sem;
|
||||
else
|
||||
sem = &cmd->sem;
|
||||
|
||||
if (ent->callback) {
|
||||
ds = ent->ts2 - ent->ts1;
|
||||
if (ent->op < ARRAY_SIZE(cmd->stats)) {
|
||||
stats = &cmd->stats[ent->op];
|
||||
spin_lock_irqsave(&stats->lock, flags);
|
||||
stats->sum += ds;
|
||||
++stats->n;
|
||||
spin_unlock_irqrestore(&stats->lock, flags);
|
||||
}
|
||||
|
||||
err = ent->ret;
|
||||
if (!err)
|
||||
err = mlx5_copy_from_msg(ent->uout,
|
||||
ent->out,
|
||||
ent->uout_size);
|
||||
|
||||
mlx5_free_cmd_msg(dev, ent->out);
|
||||
free_msg(dev, ent->in);
|
||||
|
||||
free_cmd(ent);
|
||||
ent->callback(err, ent->context);
|
||||
} else {
|
||||
complete(&ent->done);
|
||||
}
|
||||
up(sem);
|
||||
}
|
||||
|
||||
static void cmd_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
|
||||
@ -719,19 +776,13 @@ static void cmd_work_handler(struct work_struct *work)
|
||||
}
|
||||
|
||||
down(sem);
|
||||
if (!ent->page_queue) {
|
||||
ent->idx = alloc_ent(cmd);
|
||||
if (ent->idx < 0) {
|
||||
mlx5_core_err(dev, "failed to allocate command entry\n");
|
||||
up(sem);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ent->idx = cmd->max_reg_cmds;
|
||||
|
||||
if (alloc_ent(ent) < 0) {
|
||||
complete_command(ent);
|
||||
return;
|
||||
}
|
||||
|
||||
ent->token = alloc_token(cmd);
|
||||
cmd->ent_arr[ent->idx] = ent;
|
||||
lay = get_inst(cmd, ent->idx);
|
||||
ent->lay = lay;
|
||||
memset(lay, 0, sizeof(*lay));
|
||||
@ -1108,23 +1159,12 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u32 vector)
|
||||
{
|
||||
struct mlx5_cmd *cmd = &dev->cmd;
|
||||
struct mlx5_cmd_work_ent *ent;
|
||||
mlx5_cmd_cbk_t callback;
|
||||
void *context;
|
||||
int err;
|
||||
int i;
|
||||
struct semaphore *sem;
|
||||
s64 ds;
|
||||
struct mlx5_cmd_stats *stats;
|
||||
unsigned long flags;
|
||||
|
||||
while (vector != 0) {
|
||||
i = ffs(vector) - 1;
|
||||
vector &= ~(1U << i);
|
||||
ent = cmd->ent_arr[i];
|
||||
if (ent->page_queue)
|
||||
sem = &cmd->pages_sem;
|
||||
else
|
||||
sem = &cmd->sem;
|
||||
ent->ts2 = ktime_get_ns();
|
||||
memcpy(ent->out->first.data, ent->lay->out,
|
||||
sizeof(ent->lay->out));
|
||||
@ -1142,33 +1182,7 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u32 vector)
|
||||
ent->status);
|
||||
}
|
||||
free_ent(cmd, ent->idx);
|
||||
if (ent->callback) {
|
||||
ds = ent->ts2 - ent->ts1;
|
||||
if (ent->op < ARRAY_SIZE(cmd->stats)) {
|
||||
stats = &cmd->stats[ent->op];
|
||||
spin_lock_irqsave(&stats->lock, flags);
|
||||
stats->sum += ds;
|
||||
++stats->n;
|
||||
spin_unlock_irqrestore(&stats->lock, flags);
|
||||
}
|
||||
|
||||
callback = ent->callback;
|
||||
context = ent->context;
|
||||
err = ent->ret;
|
||||
if (!err)
|
||||
err = mlx5_copy_from_msg(ent->uout,
|
||||
ent->out,
|
||||
ent->uout_size);
|
||||
|
||||
mlx5_free_cmd_msg(dev, ent->out);
|
||||
free_msg(dev, ent->in);
|
||||
|
||||
free_cmd(ent);
|
||||
callback(err, context);
|
||||
} else {
|
||||
complete(&ent->done);
|
||||
}
|
||||
up(sem);
|
||||
complete_command(ent);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(mlx5_cmd_comp_handler);
|
||||
|
Loading…
x
Reference in New Issue
Block a user