Skip to content

Commit 0bae02d

Browse files
grzegorz-andrejczukjgunthorpe
authored andcommitted
IB/hfi1: Add interrupt handler functions for accelerated ipoib
This patch adds the interrupt handler function, the NAPI poll function, and its associated helper functions for receiving accelerated ipoib packets. While we are here, fix the formats of two error printouts. Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Mike Marciniszyn <[email protected]> Reviewed-by: Dennis Dalessandro <[email protected]> Signed-off-by: Sadanand Warrier <[email protected]> Signed-off-by: Grzegorz Andrejczuk <[email protected]> Signed-off-by: Kaike Wan <[email protected]> Signed-off-by: Dennis Dalessandro <[email protected]> Signed-off-by: Jason Gunthorpe <[email protected]>
1 parent 6991abc commit 0bae02d

File tree

10 files changed

+206
-7
lines changed

10 files changed

+206
-7
lines changed

drivers/infiniband/hw/hfi1/affinity.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright(c) 2015 - 2018 Intel Corporation.
2+
* Copyright(c) 2015 - 2020 Intel Corporation.
33
*
44
* This file is provided under a dual BSD/GPLv2 license. When using or
55
* redistributing this file, you may do so under either license.
@@ -64,6 +64,7 @@ struct hfi1_affinity_node_list node_affinity = {
6464
static const char * const irq_type_names[] = {
6565
"SDMA",
6666
"RCVCTXT",
67+
"NETDEVCTXT",
6768
"GENERAL",
6869
"OTHER",
6970
};
@@ -915,6 +916,11 @@ static int get_irq_affinity(struct hfi1_devdata *dd,
915916
set = &entry->rcv_intr;
916917
scnprintf(extra, 64, "ctxt %u", rcd->ctxt);
917918
break;
919+
case IRQ_NETDEVCTXT:
920+
rcd = (struct hfi1_ctxtdata *)msix->arg;
921+
set = &entry->def_intr;
922+
scnprintf(extra, 64, "ctxt %u", rcd->ctxt);
923+
break;
918924
default:
919925
dd_dev_err(dd, "Invalid IRQ type %d\n", msix->type);
920926
return -EINVAL;
@@ -987,6 +993,10 @@ void hfi1_put_irq_affinity(struct hfi1_devdata *dd,
987993
if (rcd->ctxt != HFI1_CTRL_CTXT)
988994
set = &entry->rcv_intr;
989995
break;
996+
case IRQ_NETDEVCTXT:
997+
rcd = (struct hfi1_ctxtdata *)msix->arg;
998+
set = &entry->def_intr;
999+
break;
9901000
default:
9911001
mutex_unlock(&node_affinity.lock);
9921002
return;

drivers/infiniband/hw/hfi1/affinity.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright(c) 2015 - 2018 Intel Corporation.
2+
* Copyright(c) 2015 - 2020 Intel Corporation.
33
*
44
* This file is provided under a dual BSD/GPLv2 license. When using or
55
* redistributing this file, you may do so under either license.
@@ -52,6 +52,7 @@
5252
enum irq_type {
5353
IRQ_SDMA,
5454
IRQ_RCVCTXT,
55+
IRQ_NETDEVCTXT,
5556
IRQ_GENERAL,
5657
IRQ_OTHER
5758
};

drivers/infiniband/hw/hfi1/chip.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
#include "affinity.h"
6767
#include "debugfs.h"
6868
#include "fault.h"
69+
#include "netdev.h"
6970

7071
uint num_vls = HFI1_MAX_VLS_SUPPORTED;
7172
module_param(num_vls, uint, S_IRUGO);
@@ -8480,6 +8481,49 @@ static void hfi1_rcd_eoi_intr(struct hfi1_ctxtdata *rcd)
84808481
local_irq_restore(flags);
84818482
}
84828483

8484+
/**
8485+
* hfi1_netdev_rx_napi - napi poll function to move eoi inline
8486+
* @napi - pointer to napi object
8487+
* @budget - netdev budget
8488+
*/
8489+
int hfi1_netdev_rx_napi(struct napi_struct *napi, int budget)
8490+
{
8491+
struct hfi1_netdev_rxq *rxq = container_of(napi,
8492+
struct hfi1_netdev_rxq, napi);
8493+
struct hfi1_ctxtdata *rcd = rxq->rcd;
8494+
int work_done = 0;
8495+
8496+
work_done = rcd->do_interrupt(rcd, budget);
8497+
8498+
if (work_done < budget) {
8499+
napi_complete_done(napi, work_done);
8500+
hfi1_rcd_eoi_intr(rcd);
8501+
}
8502+
8503+
return work_done;
8504+
}
8505+
8506+
/* Receive packet napi handler for netdevs VNIC and AIP */
8507+
irqreturn_t receive_context_interrupt_napi(int irq, void *data)
8508+
{
8509+
struct hfi1_ctxtdata *rcd = data;
8510+
8511+
receive_interrupt_common(rcd);
8512+
8513+
if (likely(rcd->napi)) {
8514+
if (likely(napi_schedule_prep(rcd->napi)))
8515+
__napi_schedule_irqoff(rcd->napi);
8516+
else
8517+
__hfi1_rcd_eoi_intr(rcd);
8518+
} else {
8519+
WARN_ONCE(1, "Napi IRQ handler without napi set up ctxt=%d\n",
8520+
rcd->ctxt);
8521+
__hfi1_rcd_eoi_intr(rcd);
8522+
}
8523+
8524+
return IRQ_HANDLED;
8525+
}
8526+
84838527
/*
84848528
* Receive packet IRQ handler. This routine expects to be on its own IRQ.
84858529
* This routine will try to handle packets immediately (latency), but if

drivers/infiniband/hw/hfi1/chip.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,7 @@ irqreturn_t general_interrupt(int irq, void *data);
14471447
irqreturn_t sdma_interrupt(int irq, void *data);
14481448
irqreturn_t receive_context_interrupt(int irq, void *data);
14491449
irqreturn_t receive_context_thread(int irq, void *data);
1450+
irqreturn_t receive_context_interrupt_napi(int irq, void *data);
14501451

14511452
int set_intr_bits(struct hfi1_devdata *dd, u16 first, u16 last, bool set);
14521453
void init_qsfp_int(struct hfi1_devdata *dd);

drivers/infiniband/hw/hfi1/driver.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,39 @@ static noinline int skip_rcv_packet(struct hfi1_packet *packet, int thread)
752752
return ret;
753753
}
754754

755+
static void process_rcv_packet_napi(struct hfi1_packet *packet)
756+
{
757+
packet->etype = rhf_rcv_type(packet->rhf);
758+
759+
/* total length */
760+
packet->tlen = rhf_pkt_len(packet->rhf); /* in bytes */
761+
/* retrieve eager buffer details */
762+
packet->etail = rhf_egr_index(packet->rhf);
763+
packet->ebuf = get_egrbuf(packet->rcd, packet->rhf,
764+
&packet->updegr);
765+
/*
766+
* Prefetch the contents of the eager buffer. It is
767+
* OK to send a negative length to prefetch_range().
768+
* The +2 is the size of the RHF.
769+
*/
770+
prefetch_range(packet->ebuf,
771+
packet->tlen - ((packet->rcd->rcvhdrqentsize -
772+
(rhf_hdrq_offset(packet->rhf)
773+
+ 2)) * 4));
774+
775+
packet->rcd->rhf_rcv_function_map[packet->etype](packet);
776+
packet->numpkt++;
777+
778+
/* Set up for the next packet */
779+
packet->rhqoff += packet->rsize;
780+
if (packet->rhqoff >= packet->maxcnt)
781+
packet->rhqoff = 0;
782+
783+
packet->rhf_addr = (__le32 *)packet->rcd->rcvhdrq + packet->rhqoff +
784+
packet->rcd->rhf_offset;
785+
packet->rhf = rhf_to_cpu(packet->rhf_addr);
786+
}
787+
755788
static inline int process_rcv_packet(struct hfi1_packet *packet, int thread)
756789
{
757790
int ret;
@@ -830,6 +863,36 @@ static inline void finish_packet(struct hfi1_packet *packet)
830863
packet->etail, rcv_intr_dynamic, packet->numpkt);
831864
}
832865

866+
/*
867+
* handle_receive_interrupt_napi_fp - receive a packet
868+
* @rcd: the context
869+
* @budget: polling budget
870+
*
871+
* Called from interrupt handler for receive interrupt.
872+
* This is the fast path interrupt handler
873+
* when executing napi soft irq environment.
874+
*/
875+
int handle_receive_interrupt_napi_fp(struct hfi1_ctxtdata *rcd, int budget)
876+
{
877+
struct hfi1_packet packet;
878+
879+
init_packet(rcd, &packet);
880+
if (last_rcv_seq(rcd, rhf_rcv_seq(packet.rhf)))
881+
goto bail;
882+
883+
while (packet.numpkt < budget) {
884+
process_rcv_packet_napi(&packet);
885+
if (hfi1_seq_incr(rcd, rhf_rcv_seq(packet.rhf)))
886+
break;
887+
888+
process_rcv_update(0, &packet);
889+
}
890+
hfi1_set_rcd_head(rcd, packet.rhqoff);
891+
bail:
892+
finish_packet(&packet);
893+
return packet.numpkt;
894+
}
895+
833896
/*
834897
* Handle receive interrupts when using the no dma rtail option.
835898
*/
@@ -1077,6 +1140,63 @@ int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread)
10771140
return last;
10781141
}
10791142

1143+
/*
1144+
* handle_receive_interrupt_napi_sp - receive a packet
1145+
* @rcd: the context
1146+
* @budget: polling budget
1147+
*
1148+
* Called from interrupt handler for errors or receive interrupt.
1149+
* This is the slow path interrupt handler
1150+
* when executing napi soft irq environment.
1151+
*/
1152+
int handle_receive_interrupt_napi_sp(struct hfi1_ctxtdata *rcd, int budget)
1153+
{
1154+
struct hfi1_devdata *dd = rcd->dd;
1155+
int last = RCV_PKT_OK;
1156+
bool needset = true;
1157+
struct hfi1_packet packet;
1158+
1159+
init_packet(rcd, &packet);
1160+
if (last_rcv_seq(rcd, rhf_rcv_seq(packet.rhf)))
1161+
goto bail;
1162+
1163+
while (last != RCV_PKT_DONE && packet.numpkt < budget) {
1164+
if (hfi1_need_drop(dd)) {
1165+
/* On to the next packet */
1166+
packet.rhqoff += packet.rsize;
1167+
packet.rhf_addr = (__le32 *)rcd->rcvhdrq +
1168+
packet.rhqoff +
1169+
rcd->rhf_offset;
1170+
packet.rhf = rhf_to_cpu(packet.rhf_addr);
1171+
1172+
} else {
1173+
if (set_armed_to_active(&packet))
1174+
goto bail;
1175+
process_rcv_packet_napi(&packet);
1176+
}
1177+
1178+
if (hfi1_seq_incr(rcd, rhf_rcv_seq(packet.rhf)))
1179+
last = RCV_PKT_DONE;
1180+
1181+
if (needset) {
1182+
needset = false;
1183+
set_all_fastpath(dd, rcd);
1184+
}
1185+
1186+
process_rcv_update(last, &packet);
1187+
}
1188+
1189+
hfi1_set_rcd_head(rcd, packet.rhqoff);
1190+
1191+
bail:
1192+
/*
1193+
* Always write head at end, and setup rcv interrupt, even
1194+
* if no packets were processed.
1195+
*/
1196+
finish_packet(&packet);
1197+
return packet.numpkt;
1198+
}
1199+
10801200
/*
10811201
* We may discover in the interrupt that the hardware link state has
10821202
* changed from ARMED to ACTIVE (due to the arrival of a non-SC15 packet),

drivers/infiniband/hw/hfi1/hfi.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,11 @@ struct hfi1_packet {
385385
u32 rhqoff;
386386
u32 dlid;
387387
u32 slid;
388+
int numpkt;
388389
u16 tlen;
389390
s16 etail;
390391
u16 pkey;
391392
u8 hlen;
392-
u8 numpkt;
393393
u8 rsize;
394394
u8 updegr;
395395
u8 etype;
@@ -1501,6 +1501,8 @@ struct hfi1_ctxtdata *hfi1_rcd_get_by_index(struct hfi1_devdata *dd, u16 ctxt);
15011501
int handle_receive_interrupt(struct hfi1_ctxtdata *rcd, int thread);
15021502
int handle_receive_interrupt_nodma_rtail(struct hfi1_ctxtdata *rcd, int thread);
15031503
int handle_receive_interrupt_dma_rtail(struct hfi1_ctxtdata *rcd, int thread);
1504+
int handle_receive_interrupt_napi_fp(struct hfi1_ctxtdata *rcd, int budget);
1505+
int handle_receive_interrupt_napi_sp(struct hfi1_ctxtdata *rcd, int budget);
15041506
void set_all_slowpath(struct hfi1_devdata *dd);
15051507

15061508
extern const struct pci_device_id hfi1_pci_tbl[];

drivers/infiniband/hw/hfi1/init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ int hfi1_create_ctxtdata(struct hfi1_pportdata *ppd, int numa,
374374
rcd->numa_id = numa;
375375
rcd->rcv_array_groups = dd->rcv_entries.ngroups;
376376
rcd->rhf_rcv_function_map = normal_rhf_rcv_functions;
377+
rcd->msix_intr = CCE_NUM_MSIX_VECTORS;
377378

378379
mutex_init(&rcd->exp_mutex);
379380
spin_lock_init(&rcd->exp_lock);

drivers/infiniband/hw/hfi1/msix.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "hfi.h"
5050
#include "affinity.h"
5151
#include "sdma.h"
52+
#include "netdev.h"
5253

5354
/**
5455
* msix_initialize() - Calculate, request and configure MSIx IRQs
@@ -140,7 +141,7 @@ static int msix_request_irq(struct hfi1_devdata *dd, void *arg,
140141
ret = pci_request_irq(dd->pcidev, nr, handler, thread, arg, name);
141142
if (ret) {
142143
dd_dev_err(dd,
143-
"%s: request for IRQ %d failed, MSIx %lu, err %d\n",
144+
"%s: request for IRQ %d failed, MSIx %lx, err %d\n",
144145
name, irq, nr, ret);
145146
spin_lock(&dd->msix_info.msix_lock);
146147
__clear_bit(nr, dd->msix_info.in_use_msix);
@@ -160,7 +161,7 @@ static int msix_request_irq(struct hfi1_devdata *dd, void *arg,
160161
/* This is a request, so a failure is not fatal */
161162
ret = hfi1_get_irq_affinity(dd, me);
162163
if (ret)
163-
dd_dev_err(dd, "unable to pin IRQ %d\n", ret);
164+
dd_dev_err(dd, "%s: unable to pin IRQ %d\n", name, ret);
164165

165166
return nr;
166167
}
@@ -203,6 +204,21 @@ int msix_request_rcd_irq(struct hfi1_ctxtdata *rcd)
203204
receive_context_thread, name);
204205
}
205206

207+
/**
208+
* msix_request_rcd_irq() - Helper function for RCVAVAIL IRQs
209+
* for netdev context
210+
* @rcd: valid netdev contexti
211+
*/
212+
int msix_netdev_request_rcd_irq(struct hfi1_ctxtdata *rcd)
213+
{
214+
char name[MAX_NAME_SIZE];
215+
216+
snprintf(name, sizeof(name), DRIVER_NAME "_%d nd kctxt%d",
217+
rcd->dd->unit, rcd->ctxt);
218+
return msix_request_rcd_irq_common(rcd, receive_context_interrupt_napi,
219+
NULL, name);
220+
}
221+
206222
/**
207223
* msix_request_smda_ira() - Helper for getting SDMA IRQ resources
208224
* @sde: valid sdma engine

drivers/infiniband/hw/hfi1/msix.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
22
/*
3-
* Copyright(c) 2018 Intel Corporation.
3+
* Copyright(c) 2018 - 2020 Intel Corporation.
44
*
55
* This file is provided under a dual BSD/GPLv2 license. When using or
66
* redistributing this file, you may do so under either license.
@@ -59,7 +59,8 @@ int msix_request_rcd_irq(struct hfi1_ctxtdata *rcd);
5959
int msix_request_sdma_irq(struct sdma_engine *sde);
6060
void msix_free_irq(struct hfi1_devdata *dd, u8 msix_intr);
6161

62-
/* VNIC interface */
62+
/* Netdev interface */
6363
void msix_vnic_synchronize_irq(struct hfi1_devdata *dd);
64+
int msix_netdev_request_rcd_irq(struct hfi1_ctxtdata *rcd);
6465

6566
#endif

drivers/infiniband/hw/hfi1/netdev.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,7 @@ void *hfi1_netdev_remove_data(struct hfi1_devdata *dd, int id);
8787
void *hfi1_netdev_get_data(struct hfi1_devdata *dd, int id);
8888
void *hfi1_netdev_get_first_data(struct hfi1_devdata *dd, int *start_id);
8989

90+
/* chip.c */
91+
int hfi1_netdev_rx_napi(struct napi_struct *napi, int budget);
92+
9093
#endif /* HFI1_NETDEV_H */

0 commit comments

Comments
 (0)