提交 92023476 编写于 作者: S shenjian 提交者: Xie XiuQi

net: hns3: fix cpu rmap handle issue

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

Currently, driver regists affinity notifier twice for each irq,
which may case use-afer-free and double free issue. This patch
fixes it.

Feature or Bugfix:Bugfix
Signed-off-by: Nshenjian (K) <shenjian15@huawei.com>
Reviewed-by: Nlipeng <lipeng321@huawei.com>
Reviewed-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 858f38ef
...@@ -82,22 +82,6 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector) ...@@ -82,22 +82,6 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
/* This callback function is used to set affinity changes to the irq affinity
* masks when the irq_set_affinity_notifier function is used.
*/
static void hns3_nic_irq_affinity_notify(struct irq_affinity_notify *notify,
const cpumask_t *mask)
{
struct hns3_enet_tqp_vector *tqp_vectors =
container_of(notify, struct hns3_enet_tqp_vector,
affinity_notify);
tqp_vectors->affinity_mask = *mask;
}
static void hns3_nic_irq_affinity_release(struct kref *ref)
{
}
static void hns3_nic_uninit_irq(struct hns3_nic_priv *priv) static void hns3_nic_uninit_irq(struct hns3_nic_priv *priv)
{ {
...@@ -110,8 +94,7 @@ static void hns3_nic_uninit_irq(struct hns3_nic_priv *priv) ...@@ -110,8 +94,7 @@ static void hns3_nic_uninit_irq(struct hns3_nic_priv *priv)
if (tqp_vectors->irq_init_flag != HNS3_VECTOR_INITED) if (tqp_vectors->irq_init_flag != HNS3_VECTOR_INITED)
continue; continue;
/* clear the affinity notifier and affinity mask */ /* clear the affinity mask */
irq_set_affinity_notifier(tqp_vectors->vector_irq, NULL);
irq_set_affinity_hint(tqp_vectors->vector_irq, NULL); irq_set_affinity_hint(tqp_vectors->vector_irq, NULL);
/* release the irq resource */ /* release the irq resource */
...@@ -163,14 +146,8 @@ static int hns3_nic_init_irq(struct hns3_nic_priv *priv) ...@@ -163,14 +146,8 @@ static int hns3_nic_init_irq(struct hns3_nic_priv *priv)
return ret; return ret;
} }
tqp_vectors->affinity_notify.notify =
hns3_nic_irq_affinity_notify;
tqp_vectors->affinity_notify.release =
hns3_nic_irq_affinity_release;
irq_set_affinity_hint(tqp_vectors->vector_irq, irq_set_affinity_hint(tqp_vectors->vector_irq,
&tqp_vectors->affinity_mask); &tqp_vectors->affinity_mask);
irq_set_affinity_notifier(tqp_vectors->vector_irq,
&tqp_vectors->affinity_notify);
tqp_vectors->irq_init_flag = HNS3_VECTOR_INITED; tqp_vectors->irq_init_flag = HNS3_VECTOR_INITED;
} }
...@@ -341,28 +318,33 @@ static void hns3_tqp_disable(struct hnae3_queue *tqp) ...@@ -341,28 +318,33 @@ static void hns3_tqp_disable(struct hnae3_queue *tqp)
hns3_write_dev(tqp, HNS3_RING_EN_REG, rcb_reg); hns3_write_dev(tqp, HNS3_RING_EN_REG, rcb_reg);
} }
static int hns3_set_rx_cpu_rmap(struct hnae3_handle *h) static void hns3_free_rx_cpu_rmap(struct net_device *netdev)
{
#ifdef CONFIG_RFS_ACCEL
free_irq_cpu_rmap(netdev->rx_cpu_rmap);
netdev->rx_cpu_rmap = NULL;
#endif
}
static int hns3_set_rx_cpu_rmap(struct net_device *netdev)
{ {
#ifdef CONFIG_RFS_ACCEL #ifdef CONFIG_RFS_ACCEL
struct net_device *netdev = h->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(netdev); struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hns3_enet_tqp_vector *tqp_vector; struct hns3_enet_tqp_vector *tqp_vector;
int i, ret; int i, ret;
if (!netdev->rx_cpu_rmap) { if (!netdev->rx_cpu_rmap) {
netdev->rx_cpu_rmap = alloc_irq_cpu_rmap(h->kinfo.num_tqps); netdev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->vector_num);
if (!netdev->rx_cpu_rmap) if (!netdev->rx_cpu_rmap)
return -ENOMEM; return -ENOMEM;
} }
for (i = 0; i < h->kinfo.num_tqps; i++) { for (i = 0; i < priv->vector_num; i++) {
tqp_vector = tqp_vector = &priv->tqp_vector[i];
priv->ring_data[i + h->kinfo.num_tqps].ring->tqp_vector;
ret = irq_cpu_rmap_add(netdev->rx_cpu_rmap, ret = irq_cpu_rmap_add(netdev->rx_cpu_rmap,
tqp_vector->vector_irq); tqp_vector->vector_irq);
if (ret) { if (ret) {
free_irq_cpu_rmap(netdev->rx_cpu_rmap); hns3_free_rx_cpu_rmap(netdev);
netdev->rx_cpu_rmap = NULL;
return ret; return ret;
} }
} }
...@@ -370,18 +352,6 @@ static int hns3_set_rx_cpu_rmap(struct hnae3_handle *h) ...@@ -370,18 +352,6 @@ static int hns3_set_rx_cpu_rmap(struct hnae3_handle *h)
return 0; return 0;
} }
static void hns3_free_rx_cpu_rmap(struct hnae3_handle *h)
{
#ifdef CONFIG_RFS_ACCEL
struct net_device *netdev = h->kinfo.netdev;
if (netdev->rx_cpu_rmap) {
free_irq_cpu_rmap(netdev->rx_cpu_rmap);
netdev->rx_cpu_rmap = NULL;
}
#endif
}
static int hns3_nic_net_up(struct net_device *netdev) static int hns3_nic_net_up(struct net_device *netdev)
{ {
struct hns3_nic_priv *priv = netdev_priv(netdev); struct hns3_nic_priv *priv = netdev_priv(netdev);
...@@ -394,7 +364,7 @@ static int hns3_nic_net_up(struct net_device *netdev) ...@@ -394,7 +364,7 @@ static int hns3_nic_net_up(struct net_device *netdev)
return ret; return ret;
/* the device can work without cpu rmap, only aRFS needs it */ /* the device can work without cpu rmap, only aRFS needs it */
ret = hns3_set_rx_cpu_rmap(h); ret = hns3_set_rx_cpu_rmap(netdev);
if (ret) if (ret)
netdev_warn(netdev, "set rx cpu rmap fail, ret=%d!\n", ret); netdev_warn(netdev, "set rx cpu rmap fail, ret=%d!\n", ret);
...@@ -402,7 +372,7 @@ static int hns3_nic_net_up(struct net_device *netdev) ...@@ -402,7 +372,7 @@ static int hns3_nic_net_up(struct net_device *netdev)
ret = hns3_nic_init_irq(priv); ret = hns3_nic_init_irq(priv);
if (ret) { if (ret) {
netdev_err(netdev, "init irq failed! ret=%d\n", ret); netdev_err(netdev, "init irq failed! ret=%d\n", ret);
return ret; goto free_rmap;
} }
/* enable the vectors */ /* enable the vectors */
...@@ -428,7 +398,8 @@ static int hns3_nic_net_up(struct net_device *netdev) ...@@ -428,7 +398,8 @@ static int hns3_nic_net_up(struct net_device *netdev)
hns3_vector_disable(&priv->tqp_vector[j]); hns3_vector_disable(&priv->tqp_vector[j]);
hns3_nic_uninit_irq(priv); hns3_nic_uninit_irq(priv);
free_rmap:
hns3_free_rx_cpu_rmap(netdev);
return ret; return ret;
} }
...@@ -511,7 +482,7 @@ static void hns3_nic_net_down(struct net_device *netdev) ...@@ -511,7 +482,7 @@ static void hns3_nic_net_down(struct net_device *netdev)
if (ops->stop) if (ops->stop)
ops->stop(priv->ae_handle); ops->stop(priv->ae_handle);
hns3_free_rx_cpu_rmap(h); hns3_free_rx_cpu_rmap(netdev);
/* free irq resources */ /* free irq resources */
hns3_nic_uninit_irq(priv); hns3_nic_uninit_irq(priv);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册