net: thunderx: add mutex to protect mailbox from concurrent calls for same VF [Linux 5.0]

net: thunderx: add mutex to protect mailbox from concurrent calls for same VF [Linux 5.0]

This Linux kernel change "net: thunderx: add mutex to protect mailbox from concurrent calls for same VF" is included in the Linux 5.0 release. This change is authored by Vadim Lomovtsev <vlomovtsev [at] marvell.com> on Wed Feb 20 11:02:44 2019 +0000. The commit for this change in Linux stable tree is 609ea65 (patch).

net: thunderx: add mutex to protect mailbox from concurrent calls for same VF

In some cases it could happen that nicvf_send_msg_to_pf() could be called
concurrently for the same NIC VF, and thus re-writing mailbox contents and
breaking messaging sequence with PF by re-writing NICVF data.

This commit is to implement mutex for NICVF to protect mailbox registers
and NICVF messaging control data from concurrent access.

Signed-off-by: Vadim Lomovtsev <[email protected]>
Signed-off-by: David S. Miller <[email protected]>

There are 15 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/ethernet/cavium/thunder/nic.h        |  2 ++
 drivers/net/ethernet/cavium/thunder/nicvf_main.c | 13 ++++++++++---
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/cavium/thunder/nic.h b/drivers/net/ethernet/cavium/thunder/nic.h
index 2273436..86cda3f 100644
--- a/drivers/net/ethernet/cavium/thunder/nic.h
+++ b/drivers/net/ethernet/cavium/thunder/nic.h
@@ -329,6 +329,8 @@ struct nicvf {
    spinlock_t              rx_mode_wq_lock;
    /* workqueue for handling kernel ndo_set_rx_mode() calls */
    struct workqueue_struct *nicvf_rx_mode_wq;
+   /* mutex to protect VF's mailbox contents from concurrent access */
+   struct mutex            rx_mode_mtx;

    /* PTP timestamp */
    struct cavium_ptp   *ptp_clock;
diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
index da5986c..2332e3e 100644
--- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c
+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c
@@ -124,6 +124,9 @@ int nicvf_send_msg_to_pf(struct nicvf *nic, union nic_mbx *mbx)
 {
    int timeout = NIC_MBOX_MSG_TIMEOUT;
    int sleep = 10;
+   int ret = 0;
+
+   mutex_lock(&nic->rx_mode_mtx);

    nic->pf_acked = false;
    nic->pf_nacked = false;
@@ -136,7 +139,8 @@ int nicvf_send_msg_to_pf(struct nicvf *nic, union nic_mbx *mbx)
            netdev_err(nic->netdev,
                   "PF NACK to mbox msg 0x%02x from VF%d\n",
                   (mbx->msg.msg & 0xFF), nic->vf_id);
-           return -EINVAL;
+           ret = -EINVAL;
+           break;
        }
        msleep(sleep);
        if (nic->pf_acked)
@@ -146,10 +150,12 @@ int nicvf_send_msg_to_pf(struct nicvf *nic, union nic_mbx *mbx)
            netdev_err(nic->netdev,
                   "PF didn't ACK to mbox msg 0x%02x from VF%d\n",
                   (mbx->msg.msg & 0xFF), nic->vf_id);
-           return -EBUSY;
+           ret = -EBUSY;
+           break;
        }
    }
-   return 0;
+   mutex_unlock(&nic->rx_mode_mtx);
+   return ret;
 }

 /* Checks if VF is able to comminicate with PF
@@ -2208,6 +2214,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                            nic->vf_id);
    INIT_WORK(&nic->rx_mode_work.work, nicvf_set_rx_mode_task);
    spin_lock_init(&nic->rx_mode_wq_lock);
+   mutex_init(&nic->rx_mode_mtx);

    err = register_netdev(netdev);
    if (err) {

Leave a Reply

Your email address will not be published. Required fields are marked *