Skip to content

Commit 49721da

Browse files
liuyonglong86jfvogel
authored andcommitted
net: hns3: fix an interrupt residual problem
[ Upstream commit 8e6b9c6ea5a55045eed6526d8ee49e93192d1a58 ] When a VF is passthrough to a VM, and the VM is killed, the reported interrupt may not been handled, it will remain, and won't be clear by the nic engine even with a flr or tqp reset. When the VM restart, the interrupt of the first vector may be dropped by the second enable_irq in vfio, see the issue below: https://gitlab.com/qemu-project/qemu/-/issues/2884#note_2423361621 We notice that the vfio has always behaved this way, and the interrupt is a residue of the nic engine, so we fix the problem by moving the vector enable process out of the enable_irq loop. Fixes: 08a1006 ("net: hns3: re-organize vector handle") Signed-off-by: Yonglong Liu <[email protected]> Signed-off-by: Jijie Shao <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit ee2642bbae842de4cc1f89505ddf50bd4117be62) Signed-off-by: Jack Vogel <[email protected]>
1 parent 3f28cc2 commit 49721da

File tree

1 file changed

+39
-43
lines changed

1 file changed

+39
-43
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

Lines changed: 39 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -473,20 +473,14 @@ static void hns3_mask_vector_irq(struct hns3_enet_tqp_vector *tqp_vector,
473473
writel(mask_en, tqp_vector->mask_addr);
474474
}
475475

476-
static void hns3_vector_enable(struct hns3_enet_tqp_vector *tqp_vector)
476+
static void hns3_irq_enable(struct hns3_enet_tqp_vector *tqp_vector)
477477
{
478478
napi_enable(&tqp_vector->napi);
479479
enable_irq(tqp_vector->vector_irq);
480-
481-
/* enable vector */
482-
hns3_mask_vector_irq(tqp_vector, 1);
483480
}
484481

485-
static void hns3_vector_disable(struct hns3_enet_tqp_vector *tqp_vector)
482+
static void hns3_irq_disable(struct hns3_enet_tqp_vector *tqp_vector)
486483
{
487-
/* disable vector */
488-
hns3_mask_vector_irq(tqp_vector, 0);
489-
490484
disable_irq(tqp_vector->vector_irq);
491485
napi_disable(&tqp_vector->napi);
492486
cancel_work_sync(&tqp_vector->rx_group.dim.work);
@@ -707,11 +701,42 @@ static int hns3_set_rx_cpu_rmap(struct net_device *netdev)
707701
return 0;
708702
}
709703

704+
static void hns3_enable_irqs_and_tqps(struct net_device *netdev)
705+
{
706+
struct hns3_nic_priv *priv = netdev_priv(netdev);
707+
struct hnae3_handle *h = priv->ae_handle;
708+
u16 i;
709+
710+
for (i = 0; i < priv->vector_num; i++)
711+
hns3_irq_enable(&priv->tqp_vector[i]);
712+
713+
for (i = 0; i < priv->vector_num; i++)
714+
hns3_mask_vector_irq(&priv->tqp_vector[i], 1);
715+
716+
for (i = 0; i < h->kinfo.num_tqps; i++)
717+
hns3_tqp_enable(h->kinfo.tqp[i]);
718+
}
719+
720+
static void hns3_disable_irqs_and_tqps(struct net_device *netdev)
721+
{
722+
struct hns3_nic_priv *priv = netdev_priv(netdev);
723+
struct hnae3_handle *h = priv->ae_handle;
724+
u16 i;
725+
726+
for (i = 0; i < h->kinfo.num_tqps; i++)
727+
hns3_tqp_disable(h->kinfo.tqp[i]);
728+
729+
for (i = 0; i < priv->vector_num; i++)
730+
hns3_mask_vector_irq(&priv->tqp_vector[i], 0);
731+
732+
for (i = 0; i < priv->vector_num; i++)
733+
hns3_irq_disable(&priv->tqp_vector[i]);
734+
}
735+
710736
static int hns3_nic_net_up(struct net_device *netdev)
711737
{
712738
struct hns3_nic_priv *priv = netdev_priv(netdev);
713739
struct hnae3_handle *h = priv->ae_handle;
714-
int i, j;
715740
int ret;
716741

717742
ret = hns3_nic_reset_all_ring(h);
@@ -720,23 +745,13 @@ static int hns3_nic_net_up(struct net_device *netdev)
720745

721746
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
722747

723-
/* enable the vectors */
724-
for (i = 0; i < priv->vector_num; i++)
725-
hns3_vector_enable(&priv->tqp_vector[i]);
726-
727-
/* enable rcb */
728-
for (j = 0; j < h->kinfo.num_tqps; j++)
729-
hns3_tqp_enable(h->kinfo.tqp[j]);
748+
hns3_enable_irqs_and_tqps(netdev);
730749

731750
/* start the ae_dev */
732751
ret = h->ae_algo->ops->start ? h->ae_algo->ops->start(h) : 0;
733752
if (ret) {
734753
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
735-
while (j--)
736-
hns3_tqp_disable(h->kinfo.tqp[j]);
737-
738-
for (j = i - 1; j >= 0; j--)
739-
hns3_vector_disable(&priv->tqp_vector[j]);
754+
hns3_disable_irqs_and_tqps(netdev);
740755
}
741756

742757
return ret;
@@ -823,17 +838,9 @@ static void hns3_reset_tx_queue(struct hnae3_handle *h)
823838
static void hns3_nic_net_down(struct net_device *netdev)
824839
{
825840
struct hns3_nic_priv *priv = netdev_priv(netdev);
826-
struct hnae3_handle *h = hns3_get_handle(netdev);
827841
const struct hnae3_ae_ops *ops;
828-
int i;
829842

830-
/* disable vectors */
831-
for (i = 0; i < priv->vector_num; i++)
832-
hns3_vector_disable(&priv->tqp_vector[i]);
833-
834-
/* disable rcb */
835-
for (i = 0; i < h->kinfo.num_tqps; i++)
836-
hns3_tqp_disable(h->kinfo.tqp[i]);
843+
hns3_disable_irqs_and_tqps(netdev);
837844

838845
/* stop ae_dev */
839846
ops = priv->ae_handle->ae_algo->ops;
@@ -5864,8 +5871,6 @@ int hns3_set_channels(struct net_device *netdev,
58645871
void hns3_external_lb_prepare(struct net_device *ndev, bool if_running)
58655872
{
58665873
struct hns3_nic_priv *priv = netdev_priv(ndev);
5867-
struct hnae3_handle *h = priv->ae_handle;
5868-
int i;
58695874

58705875
if (!if_running)
58715876
return;
@@ -5876,11 +5881,7 @@ void hns3_external_lb_prepare(struct net_device *ndev, bool if_running)
58765881
netif_carrier_off(ndev);
58775882
netif_tx_disable(ndev);
58785883

5879-
for (i = 0; i < priv->vector_num; i++)
5880-
hns3_vector_disable(&priv->tqp_vector[i]);
5881-
5882-
for (i = 0; i < h->kinfo.num_tqps; i++)
5883-
hns3_tqp_disable(h->kinfo.tqp[i]);
5884+
hns3_disable_irqs_and_tqps(ndev);
58845885

58855886
/* delay ring buffer clearing to hns3_reset_notify_uninit_enet
58865887
* during reset process, because driver may not be able
@@ -5896,7 +5897,6 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running)
58965897
{
58975898
struct hns3_nic_priv *priv = netdev_priv(ndev);
58985899
struct hnae3_handle *h = priv->ae_handle;
5899-
int i;
59005900

59015901
if (!if_running)
59025902
return;
@@ -5912,11 +5912,7 @@ void hns3_external_lb_restore(struct net_device *ndev, bool if_running)
59125912

59135913
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
59145914

5915-
for (i = 0; i < priv->vector_num; i++)
5916-
hns3_vector_enable(&priv->tqp_vector[i]);
5917-
5918-
for (i = 0; i < h->kinfo.num_tqps; i++)
5919-
hns3_tqp_enable(h->kinfo.tqp[i]);
5915+
hns3_enable_irqs_and_tqps(ndev);
59205916

59215917
netif_tx_wake_all_queues(ndev);
59225918

0 commit comments

Comments
 (0)