drivers/infiniband/core/counters.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/core/counters.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/core/counters.c
Extension
.c
Size
16195 bytes
Lines
690
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

if (ret) {
			mutex_unlock(&port_counter->lock);
			goto err_mode;
		}
		break;
	case RDMA_COUNTER_MODE_AUTO:
		auto_mode_init_counter(counter, qp, port_counter->mode.mask);
		break;
	default:
		ret = -EOPNOTSUPP;
		mutex_unlock(&port_counter->lock);
		goto err_mode;
	}

	port_counter->num_counters++;
	mutex_unlock(&port_counter->lock);

	counter->mode.mode = mode;
	counter->mode.bind_opcnt = bind_opcnt;
	kref_init(&counter->kref);
	mutex_init(&counter->lock);

	ret = __rdma_counter_bind_qp(counter, qp, port);
	if (ret)
		goto err_bind;

	rdma_restrack_parent_name(&counter->res, &qp->res);
	rdma_restrack_add(&counter->res);
	return counter;

err_bind:
	mutex_lock(&port_counter->lock);
	port_counter->num_counters--;
	if (!port_counter->num_counters &&
	    port_counter->mode.mode == RDMA_COUNTER_MODE_MANUAL)
		__counter_set_mode(port_counter, RDMA_COUNTER_MODE_NONE, 0,
				   false);
	mutex_unlock(&port_counter->lock);
err_mode:
	rdma_free_hw_stats_struct(counter->stats);
err_stats:
	rdma_restrack_put(&counter->res);
	kfree(counter);
	return NULL;
}

static void rdma_counter_free(struct rdma_counter *counter)
{
	struct rdma_port_counter *port_counter;

	port_counter = &counter->device->port_data[counter->port].port_counter;
	mutex_lock(&port_counter->lock);
	port_counter->num_counters--;
	if (!port_counter->num_counters &&
	    (port_counter->mode.mode == RDMA_COUNTER_MODE_MANUAL))
		__counter_set_mode(port_counter, RDMA_COUNTER_MODE_NONE, 0,
				   false);

	mutex_unlock(&port_counter->lock);

	rdma_restrack_del(&counter->res);
	rdma_free_hw_stats_struct(counter->stats);
	kfree(counter);
}

static bool auto_mode_match(struct ib_qp *qp, struct rdma_counter *counter,
			    enum rdma_nl_counter_mask auto_mask)
{
	struct auto_mode_param *param = &counter->mode.param;
	bool match = true;

	if (auto_mask & RDMA_COUNTER_MASK_QP_TYPE)
		match &= (param->qp_type == qp->qp_type);

	if (auto_mask & RDMA_COUNTER_MASK_PID)
		match &= (task_pid_nr(counter->res.task) ==
			  task_pid_nr(qp->res.task));

	return match;
}

static int __rdma_counter_unbind_qp(struct ib_qp *qp, u32 port)
{
	struct rdma_counter *counter = qp->counter;
	int ret;

	if (!qp->device->ops.counter_unbind_qp)
		return -EOPNOTSUPP;

	mutex_lock(&counter->lock);

Annotation

Implementation Notes