|
39 | 39 | #include <linux/prefetch.h> |
40 | 40 | #include <net/ip6_checksum.h> |
41 | 41 | #include <linux/ktime.h> |
| 42 | +#include <linux/numa.h> |
42 | 43 | #ifdef CONFIG_RFS_ACCEL |
43 | 44 | #include <linux/cpu_rmap.h> |
44 | 45 | #endif |
@@ -112,6 +113,71 @@ static struct enic_intr_mod_range mod_range[ENIC_MAX_LINK_SPEEDS] = { |
112 | 113 | {3, 6}, /* 10 - 40 Gbps */ |
113 | 114 | }; |
114 | 115 |
|
| 116 | +static void enic_init_affinity_hint(struct enic *enic) |
| 117 | +{ |
| 118 | + int numa_node = dev_to_node(&enic->pdev->dev); |
| 119 | + int i; |
| 120 | + |
| 121 | + for (i = 0; i < enic->intr_count; i++) { |
| 122 | + if (enic_is_err_intr(enic, i) || enic_is_notify_intr(enic, i) || |
| 123 | + (enic->msix[i].affinity_mask && |
| 124 | + !cpumask_empty(enic->msix[i].affinity_mask))) |
| 125 | + continue; |
| 126 | + if (zalloc_cpumask_var(&enic->msix[i].affinity_mask, |
| 127 | + GFP_KERNEL)) |
| 128 | + cpumask_set_cpu(cpumask_local_spread(i, numa_node), |
| 129 | + enic->msix[i].affinity_mask); |
| 130 | + } |
| 131 | +} |
| 132 | + |
| 133 | +static void enic_free_affinity_hint(struct enic *enic) |
| 134 | +{ |
| 135 | + int i; |
| 136 | + |
| 137 | + for (i = 0; i < enic->intr_count; i++) { |
| 138 | + if (enic_is_err_intr(enic, i) || enic_is_notify_intr(enic, i)) |
| 139 | + continue; |
| 140 | + free_cpumask_var(enic->msix[i].affinity_mask); |
| 141 | + } |
| 142 | +} |
| 143 | + |
| 144 | +static void enic_set_affinity_hint(struct enic *enic) |
| 145 | +{ |
| 146 | + int i; |
| 147 | + int err; |
| 148 | + |
| 149 | + for (i = 0; i < enic->intr_count; i++) { |
| 150 | + if (enic_is_err_intr(enic, i) || |
| 151 | + enic_is_notify_intr(enic, i) || |
| 152 | + !enic->msix[i].affinity_mask || |
| 153 | + cpumask_empty(enic->msix[i].affinity_mask)) |
| 154 | + continue; |
| 155 | + err = irq_set_affinity_hint(enic->msix_entry[i].vector, |
| 156 | + enic->msix[i].affinity_mask); |
| 157 | + if (err) |
| 158 | + netdev_warn(enic->netdev, "irq_set_affinity_hint failed, err %d\n", |
| 159 | + err); |
| 160 | + } |
| 161 | + |
| 162 | + for (i = 0; i < enic->wq_count; i++) { |
| 163 | + int wq_intr = enic_msix_wq_intr(enic, i); |
| 164 | + |
| 165 | + if (enic->msix[wq_intr].affinity_mask && |
| 166 | + !cpumask_empty(enic->msix[wq_intr].affinity_mask)) |
| 167 | + netif_set_xps_queue(enic->netdev, |
| 168 | + enic->msix[wq_intr].affinity_mask, |
| 169 | + i); |
| 170 | + } |
| 171 | +} |
| 172 | + |
| 173 | +static void enic_unset_affinity_hint(struct enic *enic) |
| 174 | +{ |
| 175 | + int i; |
| 176 | + |
| 177 | + for (i = 0; i < enic->intr_count; i++) |
| 178 | + irq_set_affinity_hint(enic->msix_entry[i].vector, NULL); |
| 179 | +} |
| 180 | + |
115 | 181 | int enic_is_dynamic(struct enic *enic) |
116 | 182 | { |
117 | 183 | return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_DYN; |
@@ -1649,6 +1715,8 @@ static int enic_open(struct net_device *netdev) |
1649 | 1715 | netdev_err(netdev, "Unable to request irq.\n"); |
1650 | 1716 | return err; |
1651 | 1717 | } |
| 1718 | + enic_init_affinity_hint(enic); |
| 1719 | + enic_set_affinity_hint(enic); |
1652 | 1720 |
|
1653 | 1721 | err = enic_dev_notify_set(enic); |
1654 | 1722 | if (err) { |
@@ -1701,6 +1769,7 @@ static int enic_open(struct net_device *netdev) |
1701 | 1769 | vnic_rq_clean(&enic->rq[i], enic_free_rq_buf); |
1702 | 1770 | enic_dev_notify_unset(enic); |
1703 | 1771 | err_out_free_intr: |
| 1772 | + enic_unset_affinity_hint(enic); |
1704 | 1773 | enic_free_intr(enic); |
1705 | 1774 |
|
1706 | 1775 | return err; |
@@ -1754,6 +1823,7 @@ static int enic_stop(struct net_device *netdev) |
1754 | 1823 | } |
1755 | 1824 |
|
1756 | 1825 | enic_dev_notify_unset(enic); |
| 1826 | + enic_unset_affinity_hint(enic); |
1757 | 1827 | enic_free_intr(enic); |
1758 | 1828 |
|
1759 | 1829 | for (i = 0; i < enic->wq_count; i++) |
@@ -2309,6 +2379,7 @@ static void enic_dev_deinit(struct enic *enic) |
2309 | 2379 |
|
2310 | 2380 | enic_free_vnic_resources(enic); |
2311 | 2381 | enic_clear_intr_mode(enic); |
| 2382 | + enic_free_affinity_hint(enic); |
2312 | 2383 | } |
2313 | 2384 |
|
2314 | 2385 | static void enic_kdump_kernel_config(struct enic *enic) |
@@ -2404,6 +2475,7 @@ static int enic_dev_init(struct enic *enic) |
2404 | 2475 | return 0; |
2405 | 2476 |
|
2406 | 2477 | err_out_free_vnic_resources: |
| 2478 | + enic_free_affinity_hint(enic); |
2407 | 2479 | enic_clear_intr_mode(enic); |
2408 | 2480 | enic_free_vnic_resources(enic); |
2409 | 2481 |
|
|
0 commit comments