drivers/infiniband/hw/hfi1/verbs.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/hfi1/verbs.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/hfi1/verbs.c
Extension
.c
Size
57234 bytes
Lines
1947
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

list_for_each_entry_rcu(p, &mcast->qp_list, list) {
			packet->qp = p->qp;
			if (hfi1_do_pkey_check(packet))
				goto unlock_drop;
			spin_lock_irqsave(&packet->qp->r_lock, flags);
			packet_handler = qp_ok(packet);
			if (likely(packet_handler))
				packet_handler(packet);
			else
				ibp->rvp.n_pkt_drops++;
			spin_unlock_irqrestore(&packet->qp->r_lock, flags);
		}
		rcu_read_unlock();
		/*
		 * Notify rvt_multicast_detach() if it is waiting for us
		 * to finish.
		 */
		if (atomic_dec_return(&mcast->refcount) <= 1)
			wake_up(&mcast->wait);
	} else {
		/* Get the destination QP number. */
		if (packet->etype == RHF_RCV_TYPE_BYPASS &&
		    hfi1_16B_get_l4(packet->hdr) == OPA_16B_L4_FM)
			qp_num = hfi1_16B_get_dest_qpn(packet->mgmt);
		else
			qp_num = ib_bth_get_qpn(packet->ohdr);

		rcu_read_lock();
		packet->qp = rvt_lookup_qpn(rdi, &ibp->rvp, qp_num);
		if (!packet->qp)
			goto unlock_drop;

		if (hfi1_do_pkey_check(packet))
			goto unlock_drop;

		spin_lock_irqsave(&packet->qp->r_lock, flags);
		packet_handler = qp_ok(packet);
		if (likely(packet_handler))
			packet_handler(packet);
		else
			ibp->rvp.n_pkt_drops++;
		spin_unlock_irqrestore(&packet->qp->r_lock, flags);
		rcu_read_unlock();
	}
	return;
unlock_drop:
	rcu_read_unlock();
drop:
	ibp->rvp.n_pkt_drops++;
}

/**
 * hfi1_ib_rcv - process an incoming packet
 * @packet: data packet information
 *
 * This is called to process an incoming packet at interrupt level.
 */
void hfi1_ib_rcv(struct hfi1_packet *packet)
{
	struct hfi1_ctxtdata *rcd = packet->rcd;

	trace_input_ibhdr(rcd->dd, packet, !!(rhf_dc_info(packet->rhf)));
	hfi1_handle_packet(packet, hfi1_check_mcast(packet->dlid));
}

void hfi1_16B_rcv(struct hfi1_packet *packet)
{
	struct hfi1_ctxtdata *rcd = packet->rcd;

	trace_input_ibhdr(rcd->dd, packet, false);
	hfi1_handle_packet(packet, hfi1_check_mcast(packet->dlid));
}

/*
 * This is called from a timer to check for QPs
 * which need kernel memory in order to send a packet.
 */
static void mem_timer(struct timer_list *t)
{
	struct hfi1_ibdev *dev = timer_container_of(dev, t, mem_timer);
	struct list_head *list = &dev->memwait;
	struct rvt_qp *qp = NULL;
	struct iowait *wait;
	unsigned long flags;
	struct hfi1_qp_priv *priv;

	write_seqlock_irqsave(&dev->iowait_lock, flags);
	if (!list_empty(list)) {
		wait = list_first_entry(list, struct iowait, list);
		qp = iowait_to_qp(wait);

Annotation

Implementation Notes