Skip to content

Commit 3a856ab

Browse files
committed
eth: fbnic: add IRQ reuse support
Change our method of swapping NAPIs without disturbing existing config. This is primarily needed for "live reconfiguration" such as changing the channel count when interface is already up. Previously we were planning to use a trick of using shared interrupts. We would install a second IRQ handler for the new NAPI, and make it return IRQ_NONE until we were ready for it to take over. This works fine functionally but breaks IRQ naming. The IRQ subsystem uses the IRQ name to create the procfs entry, since both handlers used the same name the second handler wouldn't get a proc directory registered. When first one gets removed on success full ring count change it would remove its directory and we would be left with none. New approach uses a double pointer to the NAPI. The IRQ handler needs to know how to locate the NAPI to schedule. We register a single IRQ handler and give it a pointer to a pointer. We can then change what it points to without re-registering. This may have a tiny perf impact, but really really negligible. Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent db7159c commit 3a856ab

File tree

5 files changed

+63
-22
lines changed

5 files changed

+63
-22
lines changed

drivers/net/ethernet/meta/fbnic/fbnic.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
#include "fbnic_mac.h"
1717
#include "fbnic_rpc.h"
1818

19+
struct fbnic_napi_vector;
20+
21+
#define FBNIC_MAX_NAPI_VECTORS 128u
22+
1923
struct fbnic_dev {
2024
struct device *dev;
2125
struct net_device *netdev;
@@ -29,6 +33,11 @@ struct fbnic_dev {
2933
unsigned int pcs_msix_vector;
3034
unsigned short num_irqs;
3135

36+
struct {
37+
u8 users;
38+
char name[IFNAMSIZ + 9];
39+
} napi_irq[FBNIC_MAX_NAPI_VECTORS];
40+
3241
struct delayed_work service_task;
3342

3443
struct fbnic_fw_mbx mbx[FBNIC_IPC_MBX_INDICES];
@@ -148,6 +157,11 @@ void fbnic_hwmon_unregister(struct fbnic_dev *fbd);
148157
int fbnic_pcs_irq_enable(struct fbnic_dev *fbd);
149158
void fbnic_pcs_irq_disable(struct fbnic_dev *fbd);
150159

160+
void fbnic_napi_name_irqs(struct fbnic_dev *fbd);
161+
int fbnic_napi_request_irq(struct fbnic_dev *fbd,
162+
struct fbnic_napi_vector *nv);
163+
void fbnic_napi_free_irq(struct fbnic_dev *fbd,
164+
struct fbnic_napi_vector *nv);
151165
int fbnic_request_irq(struct fbnic_dev *dev, int nr, irq_handler_t handler,
152166
unsigned long flags, const char *name, void *data);
153167
void fbnic_free_irq(struct fbnic_dev *dev, int nr, void *data);

drivers/net/ethernet/meta/fbnic/fbnic_irq.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,48 @@ void fbnic_free_irq(struct fbnic_dev *fbd, int nr, void *data)
169169
free_irq(irq, data);
170170
}
171171

172+
void fbnic_napi_name_irqs(struct fbnic_dev *fbd)
173+
{
174+
unsigned int i;
175+
176+
for (i = 0; i < ARRAY_SIZE(fbd->napi_irq); i++)
177+
snprintf(fbd->napi_irq[i].name,
178+
sizeof(fbd->napi_irq[i].name),
179+
"%s-TxRx-%u", fbd->netdev->name, i);
180+
}
181+
182+
int fbnic_napi_request_irq(struct fbnic_dev *fbd,
183+
struct fbnic_napi_vector *nv)
184+
{
185+
struct fbnic_net *fbn = netdev_priv(fbd->netdev);
186+
int i = fbnic_napi_idx(nv);
187+
int err;
188+
189+
if (!fbd->napi_irq[i].users) {
190+
err = fbnic_request_irq(fbd, nv->v_idx,
191+
fbnic_msix_clean_rings, 0,
192+
fbd->napi_irq[i].name,
193+
&fbn->napi[i]);
194+
if (err)
195+
return err;
196+
}
197+
198+
fbd->napi_irq[i].users++;
199+
return 0;
200+
}
201+
202+
void fbnic_napi_free_irq(struct fbnic_dev *fbd,
203+
struct fbnic_napi_vector *nv)
204+
{
205+
struct fbnic_net *fbn = netdev_priv(fbd->netdev);
206+
int i = fbnic_napi_idx(nv);
207+
208+
if (--fbd->napi_irq[i].users)
209+
return;
210+
211+
fbnic_free_irq(fbd, nv->v_idx, &fbn->napi[i]);
212+
}
213+
172214
void fbnic_free_irqs(struct fbnic_dev *fbd)
173215
{
174216
struct pci_dev *pdev = to_pci_dev(fbd->dev);

drivers/net/ethernet/meta/fbnic/fbnic_netdev.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ static int fbnic_open(struct net_device *netdev)
7474
struct fbnic_net *fbn = netdev_priv(netdev);
7575
int err;
7676

77+
fbnic_napi_name_irqs(fbn->fbd);
78+
7779
err = __fbnic_open(fbn);
7880
if (!err)
7981
fbnic_up(fbn);

drivers/net/ethernet/meta/fbnic/fbnic_txrx.c

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,9 +1036,9 @@ static int fbnic_poll(struct napi_struct *napi, int budget)
10361036
return 0;
10371037
}
10381038

1039-
static irqreturn_t fbnic_msix_clean_rings(int __always_unused irq, void *data)
1039+
irqreturn_t fbnic_msix_clean_rings(int __always_unused irq, void *data)
10401040
{
1041-
struct fbnic_napi_vector *nv = data;
1041+
struct fbnic_napi_vector *nv = *(void **)data;
10421042

10431043
napi_schedule_irqoff(&nv->napi);
10441044

@@ -1099,7 +1099,6 @@ static void fbnic_free_napi_vector(struct fbnic_net *fbn,
10991099
struct fbnic_napi_vector *nv)
11001100
{
11011101
struct fbnic_dev *fbd = nv->fbd;
1102-
u32 v_idx = nv->v_idx;
11031102
int i, j;
11041103

11051104
for (i = 0; i < nv->txt_count; i++) {
@@ -1113,7 +1112,7 @@ static void fbnic_free_napi_vector(struct fbnic_net *fbn,
11131112
fbnic_remove_rx_ring(fbn, &nv->qt[i].cmpl);
11141113
}
11151114

1116-
fbnic_free_irq(fbd, v_idx, nv);
1115+
fbnic_napi_free_irq(fbd, nv);
11171116
page_pool_destroy(nv->page_pool);
11181117
netif_napi_del(&nv->napi);
11191118
fbn->napi[fbnic_napi_idx(nv)] = NULL;
@@ -1129,18 +1128,6 @@ void fbnic_free_napi_vectors(struct fbnic_net *fbn)
11291128
fbnic_free_napi_vector(fbn, fbn->napi[i]);
11301129
}
11311130

1132-
static void fbnic_name_napi_vector(struct fbnic_napi_vector *nv)
1133-
{
1134-
unsigned char *dev_name = nv->napi.dev->name;
1135-
1136-
if (!nv->rxt_count)
1137-
snprintf(nv->name, sizeof(nv->name), "%s-Tx-%u", dev_name,
1138-
nv->v_idx - FBNIC_NON_NAPI_VECTORS);
1139-
else
1140-
snprintf(nv->name, sizeof(nv->name), "%s-TxRx-%u", dev_name,
1141-
nv->v_idx - FBNIC_NON_NAPI_VECTORS);
1142-
}
1143-
11441131
#define FBNIC_PAGE_POOL_FLAGS \
11451132
(PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV)
11461133

@@ -1240,12 +1227,8 @@ static int fbnic_alloc_napi_vector(struct fbnic_dev *fbd, struct fbnic_net *fbn,
12401227
goto napi_del;
12411228
}
12421229

1243-
/* Initialize vector name */
1244-
fbnic_name_napi_vector(nv);
1245-
12461230
/* Request the IRQ for napi vector */
1247-
err = fbnic_request_irq(fbd, v_idx, &fbnic_msix_clean_rings,
1248-
IRQF_SHARED, nv->name, nv);
1231+
err = fbnic_napi_request_irq(fbd, nv);
12491232
if (err)
12501233
goto pp_destroy;
12511234

drivers/net/ethernet/meta/fbnic/fbnic_txrx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ struct fbnic_napi_vector {
104104
struct device *dev; /* Device for DMA unmapping */
105105
struct page_pool *page_pool;
106106
struct fbnic_dev *fbd;
107-
char name[IFNAMSIZ + 9];
108107

109108
u16 v_idx;
110109
u8 txt_count;
@@ -125,6 +124,7 @@ int fbnic_alloc_napi_vectors(struct fbnic_net *fbn);
125124
void fbnic_free_napi_vectors(struct fbnic_net *fbn);
126125
int fbnic_alloc_resources(struct fbnic_net *fbn);
127126
void fbnic_free_resources(struct fbnic_net *fbn);
127+
irqreturn_t fbnic_msix_clean_rings(int irq, void *data);
128128
void fbnic_napi_enable(struct fbnic_net *fbn);
129129
void fbnic_napi_disable(struct fbnic_net *fbn);
130130
void fbnic_enable(struct fbnic_net *fbn);

0 commit comments

Comments
 (0)