aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMoshe Shemesh <moshe@mellanox.com>2017-06-25 11:45:32 -0400
committerSaeed Mahameed <saeedm@mellanox.com>2017-07-27 09:40:16 -0400
commit219c81f7d1d5a89656cb3b53d3b4e11e93608d80 (patch)
tree605f7e1c31bd02226eccc69abd48b8e8d25f33aa
parent061870800efb4e3d1ad4082a2569363629bdfcfc (diff)
net/mlx5: Fix command bad flow on command entry allocation failure
When driver fail to allocate an entry to send command to FW, it must notify the calling function and release the memory allocated for this command. Fixes: e126ba97dba9e ('mlx5: Add driver for Mellanox Connect-IB adapters') Signed-off-by: Moshe Shemesh <moshe@mellanox.com> Cc: kernel-team@fb.com Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/cmd.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
index 25fd32fcdf79..31cbe5e86a01 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c
@@ -786,6 +786,10 @@ static void cb_timeout_handler(struct work_struct *work)
786 mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true); 786 mlx5_cmd_comp_handler(dev, 1UL << ent->idx, true);
787} 787}
788 788
789static void free_msg(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *msg);
790static void mlx5_free_cmd_msg(struct mlx5_core_dev *dev,
791 struct mlx5_cmd_msg *msg);
792
789static void cmd_work_handler(struct work_struct *work) 793static void cmd_work_handler(struct work_struct *work)
790{ 794{
791 struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work); 795 struct mlx5_cmd_work_ent *ent = container_of(work, struct mlx5_cmd_work_ent, work);
@@ -796,17 +800,28 @@ static void cmd_work_handler(struct work_struct *work)
796 struct semaphore *sem; 800 struct semaphore *sem;
797 unsigned long flags; 801 unsigned long flags;
798 bool poll_cmd = ent->polling; 802 bool poll_cmd = ent->polling;
803 int alloc_ret;
799 804
800 805
801 sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; 806 sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem;
802 down(sem); 807 down(sem);
803 if (!ent->page_queue) { 808 if (!ent->page_queue) {
804 ent->idx = alloc_ent(cmd); 809 alloc_ret = alloc_ent(cmd);
805 if (ent->idx < 0) { 810 if (alloc_ret < 0) {
806 mlx5_core_err(dev, "failed to allocate command entry\n"); 811 mlx5_core_err(dev, "failed to allocate command entry\n");
812 if (ent->callback) {
813 ent->callback(-EAGAIN, ent->context);
814 mlx5_free_cmd_msg(dev, ent->out);
815 free_msg(dev, ent->in);
816 free_cmd(ent);
817 } else {
818 ent->ret = -EAGAIN;
819 complete(&ent->done);
820 }
807 up(sem); 821 up(sem);
808 return; 822 return;
809 } 823 }
824 ent->idx = alloc_ret;
810 } else { 825 } else {
811 ent->idx = cmd->max_reg_cmds; 826 ent->idx = cmd->max_reg_cmds;
812 spin_lock_irqsave(&cmd->alloc_lock, flags); 827 spin_lock_irqsave(&cmd->alloc_lock, flags);