drivers/infiniband/hw/erdma/erdma_cm.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/erdma/erdma_cm.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/erdma/erdma_cm.c
Extension
.c
Size
31738 bytes
Lines
1432
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

ret = sock_create(AF_INET, SOCK_STREAM, IPPROTO_TCP, &s);
	if (ret < 0)
		goto error_put_qp;

	cep = erdma_cep_alloc(dev);
	if (!cep) {
		ret = -ENOMEM;
		goto error_release_sock;
	}

	erdma_cep_set_inuse(cep);

	/* Associate QP with CEP */
	erdma_cep_get(cep);
	qp->cep = cep;
	cep->qp = qp;

	/* Associate cm_id with CEP */
	id->add_ref(id);
	cep->cm_id = id;

	/*
	 * 6: Allocate a sufficient number of work elements
	 * to allow concurrent handling of local + peer close
	 * events, MPA header processing + MPA timeout, connected event
	 * and connect timeout.
	 */
	ret = erdma_cm_alloc_work(cep, 6);
	if (ret != 0) {
		ret = -ENOMEM;
		goto error_release_cep;
	}

	cep->ird = params->ird;
	cep->ord = params->ord;
	cep->state = ERDMA_EPSTATE_CONNECTING;

	erdma_cep_socket_assoc(cep, s);

	if (pd_len) {
		cep->pd_len = pd_len;
		cep->private_data = kmalloc(pd_len, GFP_KERNEL);
		if (!cep->private_data) {
			ret = -ENOMEM;
			goto error_disassoc;
		}

		memcpy(cep->private_data, params->private_data,
		       params->private_data_len);
	}

	ret = kernel_bindconnect(s, laddr, sizeof(*laddr), raddr,
				 sizeof(*raddr), O_NONBLOCK);
	if (ret != -EINPROGRESS && ret != 0) {
		goto error_disassoc;
	} else if (ret == 0) {
		ret = erdma_cm_queue_work(cep, ERDMA_CM_WORK_CONNECTED);
		if (ret)
			goto error_disassoc;
	} else {
		ret = erdma_cm_queue_work(cep, ERDMA_CM_WORK_CONNECTTIMEOUT);
		if (ret)
			goto error_disassoc;
	}

	erdma_cep_set_free(cep);
	return 0;

error_disassoc:
	kfree(cep->private_data);
	cep->private_data = NULL;
	cep->pd_len = 0;

	erdma_socket_disassoc(s);

error_release_cep:
	/* disassoc with cm_id */
	cep->cm_id = NULL;
	id->rem_ref(id);

	/* disassoc with qp */
	qp->cep = NULL;
	erdma_cep_put(cep);
	cep->qp = NULL;

	cep->state = ERDMA_EPSTATE_CLOSED;

	erdma_cep_set_free(cep);

	/* release the cep. */

Annotation

Implementation Notes