Commit 020446e0 authored by Eli Cohen's avatar Eli Cohen Committed by David S. Miller

net/mlx5_core: Prepare cmd interface to system errors handling

In preparation to handling system errors at the mlx5_core level, change the
interface of cmd_work_handler to accept a 64 bit argument for the vector.

This allows to encode a flag that signifies when the handler is called
as a result of a driver logic that wishes to terminate commands that
the hardware may not be able to terminate. Such command completions
are detected at the handler and proper return status is encoded.

To be able to terminate page handler commands, we make sure to set
the corresponding bit in the bitmask.
Signed-off-by: default avatarEli Cohen <eli@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5a788398
...@@ -254,6 +254,10 @@ static void dump_buf(void *buf, int size, int data_only, int offset) ...@@ -254,6 +254,10 @@ static void dump_buf(void *buf, int size, int data_only, int offset)
pr_debug("\n"); pr_debug("\n");
} }
enum {
MLX5_DRIVER_STATUS_ABORTED = 0xfe,
};
const char *mlx5_command_str(int command) const char *mlx5_command_str(int command)
{ {
switch (command) { switch (command) {
...@@ -473,6 +477,7 @@ static void cmd_work_handler(struct work_struct *work) ...@@ -473,6 +477,7 @@ static void cmd_work_handler(struct work_struct *work)
struct mlx5_core_dev *dev = container_of(cmd, struct mlx5_core_dev, cmd); struct mlx5_core_dev *dev = container_of(cmd, struct mlx5_core_dev, cmd);
struct mlx5_cmd_layout *lay; struct mlx5_cmd_layout *lay;
struct semaphore *sem; struct semaphore *sem;
unsigned long flags;
sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
down(sem); down(sem);
...@@ -485,6 +490,9 @@ static void cmd_work_handler(struct work_struct *work) ...@@ -485,6 +490,9 @@ static void cmd_work_handler(struct work_struct *work)
} }
} else { } else {
ent->idx = cmd->max_reg_cmds; ent->idx = cmd->max_reg_cmds;
spin_lock_irqsave(&cmd->alloc_lock, flags);
clear_bit(ent->idx, &cmd->bitmask);
spin_unlock_irqrestore(&cmd->alloc_lock, flags);
} }
ent->token = alloc_token(cmd); ent->token = alloc_token(cmd);
...@@ -1081,7 +1089,7 @@ static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg) ...@@ -1081,7 +1089,7 @@ static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg)
} }
} }
void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector) void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec)
{ {
struct mlx5_cmd *cmd = &dev->cmd; struct mlx5_cmd *cmd = &dev->cmd;
struct mlx5_cmd_work_ent *ent; struct mlx5_cmd_work_ent *ent;
...@@ -1092,7 +1100,10 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector) ...@@ -1092,7 +1100,10 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector)
s64 ds; s64 ds;
struct mlx5_cmd_stats *stats; struct mlx5_cmd_stats *stats;
unsigned long flags; unsigned long flags;
unsigned long vector;
/* there can be at most 32 command queues */
vector = vec & 0xffffffff;
for (i = 0; i < (1 << cmd->log_sz); i++) { for (i = 0; i < (1 << cmd->log_sz); i++) {
if (test_bit(i, &vector)) { if (test_bit(i, &vector)) {
struct semaphore *sem; struct semaphore *sem;
...@@ -1110,11 +1121,16 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector) ...@@ -1110,11 +1121,16 @@ void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector)
ent->ret = verify_signature(ent); ent->ret = verify_signature(ent);
else else
ent->ret = 0; ent->ret = 0;
ent->status = ent->lay->status_own >> 1; if (vec & MLX5_TRIGGERED_CMD_COMP)
ent->status = MLX5_DRIVER_STATUS_ABORTED;
else
ent->status = ent->lay->status_own >> 1;
mlx5_core_dbg(dev, "command completed. ret 0x%x, delivery status %s(0x%x)\n", mlx5_core_dbg(dev, "command completed. ret 0x%x, delivery status %s(0x%x)\n",
ent->ret, deliv_status_to_str(ent->status), ent->status); ent->ret, deliv_status_to_str(ent->status), ent->status);
} }
free_ent(cmd, ent->idx); free_ent(cmd, ent->idx);
if (ent->callback) { if (ent->callback) {
ds = ent->ts2 - ent->ts1; ds = ent->ts2 - ent->ts1;
if (ent->op < ARRAY_SIZE(cmd->stats)) { if (ent->op < ARRAY_SIZE(cmd->stats)) {
......
...@@ -731,7 +731,7 @@ void mlx5_eq_pagefault(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe); ...@@ -731,7 +731,7 @@ void mlx5_eq_pagefault(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe);
#endif #endif
void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type); void mlx5_srq_event(struct mlx5_core_dev *dev, u32 srqn, int event_type);
struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn); struct mlx5_core_srq *mlx5_core_get_srq(struct mlx5_core_dev *dev, u32 srqn);
void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, unsigned long vector); void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec);
void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type); void mlx5_cq_event(struct mlx5_core_dev *dev, u32 cqn, int event_type);
int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx, int mlx5_create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq, u8 vecidx,
int nent, u64 mask, const char *name, struct mlx5_uar *uar); int nent, u64 mask, const char *name, struct mlx5_uar *uar);
...@@ -865,4 +865,8 @@ static inline int mlx5_get_gid_table_len(u16 param) ...@@ -865,4 +865,8 @@ static inline int mlx5_get_gid_table_len(u16 param)
return 8 * (1 << param); return 8 * (1 << param);
} }
enum {
MLX5_TRIGGERED_CMD_COMP = (u64)1 << 32,
};
#endif /* MLX5_DRIVER_H */ #endif /* MLX5_DRIVER_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment