Skip to content

Commit

Permalink
hinic: fix a bug of waitting for IO stopped
Browse files Browse the repository at this point in the history
it's unreliable for fw to check whether IO is stopped, so driver
wait for enough time to ensure IO process is done in hw before
freeing resources

Signed-off-by: Luo bin <luobin9@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Luo bin authored and davem330 committed Mar 22, 2020
1 parent 07f8e4d commit 9675811
Showing 1 changed file with 2 additions and 49 deletions.
51 changes: 2 additions & 49 deletions drivers/net/ethernet/huawei/hinic/hinic_hw_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,50 +360,6 @@ static int wait_for_db_state(struct hinic_hwdev *hwdev)
return -EFAULT;
}

static int wait_for_io_stopped(struct hinic_hwdev *hwdev)
{
struct hinic_cmd_io_status cmd_io_status;
struct hinic_hwif *hwif = hwdev->hwif;
struct pci_dev *pdev = hwif->pdev;
struct hinic_pfhwdev *pfhwdev;
unsigned long end;
u16 out_size;
int err;

if (!HINIC_IS_PF(hwif) && !HINIC_IS_PPF(hwif)) {
dev_err(&pdev->dev, "Unsupported PCI Function type\n");
return -EINVAL;
}

pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);

cmd_io_status.func_idx = HINIC_HWIF_FUNC_IDX(hwif);

end = jiffies + msecs_to_jiffies(IO_STATUS_TIMEOUT);
do {
err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
HINIC_COMM_CMD_IO_STATUS_GET,
&cmd_io_status, sizeof(cmd_io_status),
&cmd_io_status, &out_size,
HINIC_MGMT_MSG_SYNC);
if ((err) || (out_size != sizeof(cmd_io_status))) {
dev_err(&pdev->dev, "Failed to get IO status, ret = %d\n",
err);
return err;
}

if (cmd_io_status.status == IO_STOPPED) {
dev_info(&pdev->dev, "IO stopped\n");
return 0;
}

msleep(20);
} while (time_before(jiffies, end));

dev_err(&pdev->dev, "Wait for IO stopped - Timeout\n");
return -ETIMEDOUT;
}

/**
* clear_io_resource - set the IO resources as not active in the NIC
* @hwdev: the NIC HW device
Expand All @@ -423,11 +379,8 @@ static int clear_io_resources(struct hinic_hwdev *hwdev)
return -EINVAL;
}

err = wait_for_io_stopped(hwdev);
if (err) {
dev_err(&pdev->dev, "IO has not stopped yet\n");
return err;
}
/* sleep 100ms to wait for firmware stopping I/O */
msleep(100);

cmd_clear_io_res.func_idx = HINIC_HWIF_FUNC_IDX(hwif);

Expand Down

0 comments on commit 9675811

Please sign in to comment.