Commit 0bae02d5 authored by Grzegorz Andrejczuk's avatar Grzegorz Andrejczuk Committed by Jason Gunthorpe
Browse files

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/20200511160637.173205.64890.stgit@awfm-01.aw.intel.com


Reviewed-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarSadanand Warrier <sadanand.warrier@intel.com>
Signed-off-by: default avatarGrzegorz Andrejczuk <grzegorz.andrejczuk@intel.com>
Signed-off-by: default avatarKaike Wan <kaike.wan@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 6991abcb
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
/*
 * Copyright(c) 2015 - 2018 Intel Corporation.
 * Copyright(c) 2015 - 2020 Intel Corporation.
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
@@ -64,6 +64,7 @@ struct hfi1_affinity_node_list node_affinity = {
static const char * const irq_type_names[] = {
	"SDMA",
	"RCVCTXT",
	"NETDEVCTXT",
	"GENERAL",
	"OTHER",
};
@@ -915,6 +916,11 @@ static int get_irq_affinity(struct hfi1_devdata *dd,
			set = &entry->rcv_intr;
		scnprintf(extra, 64, "ctxt %u", rcd->ctxt);
		break;
	case IRQ_NETDEVCTXT:
		rcd = (struct hfi1_ctxtdata *)msix->arg;
		set = &entry->def_intr;
		scnprintf(extra, 64, "ctxt %u", rcd->ctxt);
		break;
	default:
		dd_dev_err(dd, "Invalid IRQ type %d\n", msix->type);
		return -EINVAL;
@@ -987,6 +993,10 @@ void hfi1_put_irq_affinity(struct hfi1_devdata *dd,
		if (rcd->ctxt != HFI1_CTRL_CTXT)
			set = &entry->rcv_intr;
		break;
	case IRQ_NETDEVCTXT:
		rcd = (struct hfi1_ctxtdata *)msix->arg;
		set = &entry->def_intr;
		break;
	default:
		mutex_unlock(&node_affinity.lock);
		return;
+2 −1
Original line number Diff line number Diff line
/*
 * Copyright(c) 2015 - 2018 Intel Corporation.
 * Copyright(c) 2015 - 2020 Intel Corporation.
 *
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
@@ -52,6 +52,7 @@
enum irq_type {
	IRQ_SDMA,
	IRQ_RCVCTXT,
	IRQ_NETDEVCTXT,
	IRQ_GENERAL,
	IRQ_OTHER
};
+44 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@
#include "affinity.h"
#include "debugfs.h"
#include "fault.h"
#include "netdev.h"

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

/**
 * hfi1_netdev_rx_napi - napi poll function to move eoi inline
 * @napi - pointer to napi object
 * @budget - netdev budget
 */
int hfi1_netdev_rx_napi(struct napi_struct *napi, int budget)
{
	struct hfi1_netdev_rxq *rxq = container_of(napi,
			struct hfi1_netdev_rxq, napi);
	struct hfi1_ctxtdata *rcd = rxq->rcd;
	int work_done = 0;

	work_done = rcd->do_interrupt(rcd, budget);

	if (work_done < budget) {
		napi_complete_done(napi, work_done);
		hfi1_rcd_eoi_intr(rcd);
	}

	return work_done;
}

/* Receive packet napi handler for netdevs VNIC and AIP  */
irqreturn_t receive_context_interrupt_napi(int irq, void *data)
{
	struct hfi1_ctxtdata *rcd = data;

	receive_interrupt_common(rcd);

	if (likely(rcd->napi)) {
		if (likely(napi_schedule_prep(rcd->napi)))
			__napi_schedule_irqoff(rcd->napi);
		else
			__hfi1_rcd_eoi_intr(rcd);
	} else {
		WARN_ONCE(1, "Napi IRQ handler without napi set up ctxt=%d\n",
			  rcd->ctxt);
		__hfi1_rcd_eoi_intr(rcd);
	}

	return IRQ_HANDLED;
}

/*
 * Receive packet IRQ handler.  This routine expects to be on its own IRQ.
 * This routine will try to handle packets immediately (latency), but if
+1 −0
Original line number Diff line number Diff line
@@ -1447,6 +1447,7 @@ irqreturn_t general_interrupt(int irq, void *data);
irqreturn_t sdma_interrupt(int irq, void *data);
irqreturn_t receive_context_interrupt(int irq, void *data);
irqreturn_t receive_context_thread(int irq, void *data);
irqreturn_t receive_context_interrupt_napi(int irq, void *data);

int set_intr_bits(struct hfi1_devdata *dd, u16 first, u16 last, bool set);
void init_qsfp_int(struct hfi1_devdata *dd);
+120 −0
Original line number Diff line number Diff line
@@ -752,6 +752,39 @@ static noinline int skip_rcv_packet(struct hfi1_packet *packet, int thread)
	return ret;
}

static void process_rcv_packet_napi(struct hfi1_packet *packet)
{
	packet->etype = rhf_rcv_type(packet->rhf);

	/* total length */
	packet->tlen = rhf_pkt_len(packet->rhf); /* in bytes */
	/* retrieve eager buffer details */
	packet->etail = rhf_egr_index(packet->rhf);
	packet->ebuf = get_egrbuf(packet->rcd, packet->rhf,
				  &packet->updegr);
	/*
	 * Prefetch the contents of the eager buffer.  It is
	 * OK to send a negative length to prefetch_range().
	 * The +2 is the size of the RHF.
	 */
	prefetch_range(packet->ebuf,
		       packet->tlen - ((packet->rcd->rcvhdrqentsize -
				       (rhf_hdrq_offset(packet->rhf)
					+ 2)) * 4));

	packet->rcd->rhf_rcv_function_map[packet->etype](packet);
	packet->numpkt++;

	/* Set up for the next packet */
	packet->rhqoff += packet->rsize;
	if (packet->rhqoff >= packet->maxcnt)
		packet->rhqoff = 0;

	packet->rhf_addr = (__le32 *)packet->rcd->rcvhdrq + packet->rhqoff +
				      packet->rcd->rhf_offset;
	packet->rhf = rhf_to_cpu(packet->rhf_addr);
}

static inline int process_rcv_packet(struct hfi1_packet *packet, int thread)
{
	int ret;
@@ -830,6 +863,36 @@ static inline void finish_packet(struct hfi1_packet *packet)
		       packet->etail, rcv_intr_dynamic, packet->numpkt);
}

/*
 * handle_receive_interrupt_napi_fp - receive a packet
 * @rcd: the context
 * @budget: polling budget
 *
 * Called from interrupt handler for receive interrupt.
 * This is the fast path interrupt handler
 * when executing napi soft irq environment.
 */
int handle_receive_interrupt_napi_fp(struct hfi1_ctxtdata *rcd, int budget)
{
	struct hfi1_packet packet;

	init_packet(rcd, &packet);
	if (last_rcv_seq(rcd, rhf_rcv_seq(packet.rhf)))
		goto bail;

	while (packet.numpkt < budget) {
		process_rcv_packet_napi(&packet);
		if (hfi1_seq_incr(rcd, rhf_rcv_seq(packet.rhf)))
			break;

		process_rcv_update(0, &packet);
	}
	hfi1_set_rcd_head(rcd, packet.rhqoff);
bail:
	finish_packet(&packet);
	return packet.numpkt;
}

/*
 * Handle receive interrupts when using the no dma rtail option.
 */
@@ -1077,6 +1140,63 @@ bail:
	return last;
}

/*
 * handle_receive_interrupt_napi_sp - receive a packet
 * @rcd: the context
 * @budget: polling budget
 *
 * Called from interrupt handler for errors or receive interrupt.
 * This is the slow path interrupt handler
 * when executing napi soft irq environment.
 */
int handle_receive_interrupt_napi_sp(struct hfi1_ctxtdata *rcd, int budget)
{
	struct hfi1_devdata *dd = rcd->dd;
	int last = RCV_PKT_OK;
	bool needset = true;
	struct hfi1_packet packet;

	init_packet(rcd, &packet);
	if (last_rcv_seq(rcd, rhf_rcv_seq(packet.rhf)))
		goto bail;

	while (last != RCV_PKT_DONE && packet.numpkt < budget) {
		if (hfi1_need_drop(dd)) {
			/* On to the next packet */
			packet.rhqoff += packet.rsize;
			packet.rhf_addr = (__le32 *)rcd->rcvhdrq +
					  packet.rhqoff +
					  rcd->rhf_offset;
			packet.rhf = rhf_to_cpu(packet.rhf_addr);

		} else {
			if (set_armed_to_active(&packet))
				goto bail;
			process_rcv_packet_napi(&packet);
		}

		if (hfi1_seq_incr(rcd, rhf_rcv_seq(packet.rhf)))
			last = RCV_PKT_DONE;

		if (needset) {
			needset = false;
			set_all_fastpath(dd, rcd);
		}

		process_rcv_update(last, &packet);
	}

	hfi1_set_rcd_head(rcd, packet.rhqoff);

bail:
	/*
	 * Always write head at end, and setup rcv interrupt, even
	 * if no packets were processed.
	 */
	finish_packet(&packet);
	return packet.numpkt;
}

/*
 * We may discover in the interrupt that the hardware link state has
 * changed from ARMED to ACTIVE (due to the arrival of a non-SC15 packet),
Loading