Skip to content

Commit ffab969

Browse files
IronShendavem330
authored andcommitted
net: hns3: initialize CPU reverse mapping
Allocate CPU rmap and add entry for each irq. CPU rmap is used in aRFS to get the queue number of the rx completion interrupts. In additional, remove the calling of irq_set_affinity_notifier() in hns3_nic_init_irq(), because we have registered notifier in irq_cpu_rmap_add() for each vector, otherwise it may cause use-after-free issue. Signed-off-by: Jian Shen <[email protected]> Signed-off-by: Huazhong Tan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 18e8817 commit ffab969

File tree

1 file changed

+48
-29
lines changed

1 file changed

+48
-29
lines changed

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

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include <linux/dma-mapping.h>
55
#include <linux/etherdevice.h>
66
#include <linux/interrupt.h>
7+
#ifdef CONFIG_RFS_ACCEL
8+
#include <linux/cpu_rmap.h>
9+
#endif
710
#include <linux/if_vlan.h>
811
#include <linux/ip.h>
912
#include <linux/ipv6.h>
@@ -79,23 +82,6 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector)
7982
return IRQ_HANDLED;
8083
}
8184

82-
/* This callback function is used to set affinity changes to the irq affinity
83-
* masks when the irq_set_affinity_notifier function is used.
84-
*/
85-
static void hns3_nic_irq_affinity_notify(struct irq_affinity_notify *notify,
86-
const cpumask_t *mask)
87-
{
88-
struct hns3_enet_tqp_vector *tqp_vectors =
89-
container_of(notify, struct hns3_enet_tqp_vector,
90-
affinity_notify);
91-
92-
tqp_vectors->affinity_mask = *mask;
93-
}
94-
95-
static void hns3_nic_irq_affinity_release(struct kref *ref)
96-
{
97-
}
98-
9985
static void hns3_nic_uninit_irq(struct hns3_nic_priv *priv)
10086
{
10187
struct hns3_enet_tqp_vector *tqp_vectors;
@@ -107,8 +93,7 @@ static void hns3_nic_uninit_irq(struct hns3_nic_priv *priv)
10793
if (tqp_vectors->irq_init_flag != HNS3_VECTOR_INITED)
10894
continue;
10995

110-
/* clear the affinity notifier and affinity mask */
111-
irq_set_affinity_notifier(tqp_vectors->vector_irq, NULL);
96+
/* clear the affinity mask */
11297
irq_set_affinity_hint(tqp_vectors->vector_irq, NULL);
11398

11499
/* release the irq resource */
@@ -161,12 +146,6 @@ static int hns3_nic_init_irq(struct hns3_nic_priv *priv)
161146
return ret;
162147
}
163148

164-
tqp_vectors->affinity_notify.notify =
165-
hns3_nic_irq_affinity_notify;
166-
tqp_vectors->affinity_notify.release =
167-
hns3_nic_irq_affinity_release;
168-
irq_set_affinity_notifier(tqp_vectors->vector_irq,
169-
&tqp_vectors->affinity_notify);
170149
irq_set_affinity_hint(tqp_vectors->vector_irq,
171150
&tqp_vectors->affinity_mask);
172151

@@ -340,6 +319,40 @@ static void hns3_tqp_disable(struct hnae3_queue *tqp)
340319
hns3_write_dev(tqp, HNS3_RING_EN_REG, rcb_reg);
341320
}
342321

322+
static void hns3_free_rx_cpu_rmap(struct net_device *netdev)
323+
{
324+
#ifdef CONFIG_RFS_ACCEL
325+
free_irq_cpu_rmap(netdev->rx_cpu_rmap);
326+
netdev->rx_cpu_rmap = NULL;
327+
#endif
328+
}
329+
330+
static int hns3_set_rx_cpu_rmap(struct net_device *netdev)
331+
{
332+
#ifdef CONFIG_RFS_ACCEL
333+
struct hns3_nic_priv *priv = netdev_priv(netdev);
334+
struct hns3_enet_tqp_vector *tqp_vector;
335+
int i, ret;
336+
337+
if (!netdev->rx_cpu_rmap) {
338+
netdev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->vector_num);
339+
if (!netdev->rx_cpu_rmap)
340+
return -ENOMEM;
341+
}
342+
343+
for (i = 0; i < priv->vector_num; i++) {
344+
tqp_vector = &priv->tqp_vector[i];
345+
ret = irq_cpu_rmap_add(netdev->rx_cpu_rmap,
346+
tqp_vector->vector_irq);
347+
if (ret) {
348+
hns3_free_rx_cpu_rmap(netdev);
349+
return ret;
350+
}
351+
}
352+
#endif
353+
return 0;
354+
}
355+
343356
static int hns3_nic_net_up(struct net_device *netdev)
344357
{
345358
struct hns3_nic_priv *priv = netdev_priv(netdev);
@@ -351,11 +364,16 @@ static int hns3_nic_net_up(struct net_device *netdev)
351364
if (ret)
352365
return ret;
353366

367+
/* the device can work without cpu rmap, only aRFS needs it */
368+
ret = hns3_set_rx_cpu_rmap(netdev);
369+
if (ret)
370+
netdev_warn(netdev, "set rx cpu rmap fail, ret=%d!\n", ret);
371+
354372
/* get irq resource for all vectors */
355373
ret = hns3_nic_init_irq(priv);
356374
if (ret) {
357375
netdev_err(netdev, "hns init irq failed! ret=%d\n", ret);
358-
return ret;
376+
goto free_rmap;
359377
}
360378

361379
clear_bit(HNS3_NIC_STATE_DOWN, &priv->state);
@@ -384,7 +402,8 @@ static int hns3_nic_net_up(struct net_device *netdev)
384402
hns3_vector_disable(&priv->tqp_vector[j]);
385403

386404
hns3_nic_uninit_irq(priv);
387-
405+
free_rmap:
406+
hns3_free_rx_cpu_rmap(netdev);
388407
return ret;
389408
}
390409

@@ -467,6 +486,8 @@ static void hns3_nic_net_down(struct net_device *netdev)
467486
if (ops->stop)
468487
ops->stop(priv->ae_handle);
469488

489+
hns3_free_rx_cpu_rmap(netdev);
490+
470491
/* free irq resources */
471492
hns3_nic_uninit_irq(priv);
472493

@@ -3331,8 +3352,6 @@ static void hns3_nic_uninit_vector_data(struct hns3_nic_priv *priv)
33313352
hns3_free_vector_ring_chain(tqp_vector, &vector_ring_chain);
33323353

33333354
if (tqp_vector->irq_init_flag == HNS3_VECTOR_INITED) {
3334-
irq_set_affinity_notifier(tqp_vector->vector_irq,
3335-
NULL);
33363355
irq_set_affinity_hint(tqp_vector->vector_irq, NULL);
33373356
free_irq(tqp_vector->vector_irq, tqp_vector);
33383357
tqp_vector->irq_init_flag = HNS3_VECTOR_NOT_INITED;

0 commit comments

Comments
 (0)