net/hns3: fix setting default MAC address in bonding of VF
authorChengwen Feng <fengchengwen@huawei.com>
Wed, 31 Mar 2021 10:01:36 +0000 (18:01 +0800)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 8 Apr 2021 16:57:09 +0000 (18:57 +0200)
commit76a3836b98c4af6b9aaeaaa50907fe6143d31c55
treedb59983cedf58ef48679ffdc2a4153bdb41dc740
parent85a2dc75af38c384e526528272d69eb404e8956c
net/hns3: fix setting default MAC address in bonding of VF

When start testpmd with two hns3 VFs(0000:bd:01.0, 0000:bd:01.7), and
then execute the following commands:
testpmd> create bonded device 1 0
testpmd> set bonding mac_addr 2 3c:12:34:56:78:9a
testpmd> add bonding slave 0 2
testpmd> add bonding slave 1 2
testpmd> set portmask 0x4
testpmd> port start 2

It will occurs the following error in a low probability:
0000:bd:01.0 hns3_get_mbx_resp(): VF could not get mbx(3,0)
head(16) tail(15) lost(1) from PF in_irq:0
0000:bd:01.0 hns3vf_set_default_mac_addr(): Failed to set mac
addr(3C:**:**:**:78:9A) for vf: -62
mac_address_slaves_update(1541) - Failed to update port Id 0
MAC address

The problem replay:
1. The 'port start 2' command will start slave ports and then set slave
   mac address, the function call flow: bond_ethdev_start ->
   mac_address_slaves_update.
2. There are also a monitor task which running in intr thread will check
   slave ports link status and update slave ports mac address, the
   function call flow: bond_ethdev_slave_link_status_change_monitor ->
   bond_ethdev_lsc_event_callback -> mac_address_slaves_update.
3. Because the above step1&2 running on different threads, they may both
   call drivers ops mac_addr_set which is hns3vf_set_default_mac_addr.
4. hns3vf_set_default_mac_addr will first acquire hw.lock and then send
   mailbox to PF and wait PF's response message.  Note: the PF's
   response is an independent message which will received in hw.cmq.crq,
   the receiving operation can only performed in intr thread.
5. So if the step1 operation hold the hw.lock and try get response
   message, and step2 operation try acquire the hw.lock and so it can't
   process the response message, this will lead to step1 fail.

The solution:
1. make all threads could process the mailbox response message, which
   protected by the hw.cmq.crq.lock.
2. use the following rules to avoid deadlock:
2.1. ensure use the correct locking sequence: hw.lock >
     hw.mbx_resp.lock > hw.cmq.crq.lock.
2.2. make sure don't acquire such as hw.lock & hw.mbx_resp.lock again
     when process mailbox response message.

Fixes: 463e748964f5 ("net/hns3: support mailbox")
Cc: stable@dpdk.org
Signed-off-by: Chengwen Feng <fengchengwen@huawei.com>
Signed-off-by: Min Hu (Connor) <humin29@huawei.com>
drivers/net/hns3/hns3_ethdev.h
drivers/net/hns3/hns3_ethdev_vf.c
drivers/net/hns3/hns3_mbx.c