/* * rdma_counter_set_auto_mode() - Turn on/off per-port auto mode * * @dev: Device to operate * @port: Port to use * @mask: Mask to configure * @extack: Message to the user * * Return 0 on success. If counter mode wasn't changed then it is considered * as success as well. * Return -EBUSY when changing to auto mode while there are bounded counters. *
*/ int rdma_counter_set_auto_mode(struct ib_device *dev, u32 port, enum rdma_nl_counter_mask mask, bool bind_opcnt, struct netlink_ext_ack *extack)
{ struct rdma_port_counter *port_counter; enum rdma_nl_counter_mode mode; int ret;
port_counter = &dev->port_data[port].port_counter; if (!port_counter->hstats) return -EOPNOTSUPP;
if (port_counter->mode.mode == mode &&
port_counter->mode.mask == mask &&
port_counter->mode.bind_opcnt == bind_opcnt) {
ret = 0; goto out;
}
ret = __counter_set_mode(port_counter, mode, mask, bind_opcnt);
out:
mutex_unlock(&port_counter->lock); if (ret == -EBUSY)
NL_SET_ERR_MSG(
extack, "Modifying auto mode is not allowed when there is a bound QP"); return ret;
}
/* * rdma_counter_bind_qp_auto - Check and bind the QP to a counter base on * the auto-mode rule
*/ int rdma_counter_bind_qp_auto(struct ib_qp *qp, u32 port)
{ struct rdma_port_counter *port_counter; struct ib_device *dev = qp->device; struct rdma_counter *counter; int ret;
if (!rdma_restrack_is_tracked(&qp->res) || rdma_is_kernel_res(&qp->res)) return 0;
if (!rdma_is_port_valid(dev, port)) return -EINVAL;
port_counter = &dev->port_data[port].port_counter; if (port_counter->mode.mode != RDMA_COUNTER_MODE_AUTO) return 0;
counter = rdma_get_counter_auto_mode(qp, port); if (counter) {
ret = __rdma_counter_bind_qp(counter, qp, port); if (ret) {
kref_put(&counter->kref, counter_release); return ret;
}
} else {
counter = alloc_and_bind(dev, port, qp, RDMA_COUNTER_MODE_AUTO,
port_counter->mode.bind_opcnt); if (!counter) return -ENOMEM;
}
return 0;
}
/* * rdma_counter_unbind_qp - Unbind a qp from a counter * @force: * true - Decrease the counter ref-count anyway (e.g., qp destroy)
*/ int rdma_counter_unbind_qp(struct ib_qp *qp, u32 port, bool force)
{ struct rdma_counter *counter = qp->counter; int ret;
if (!counter) return -EINVAL;
ret = __rdma_counter_unbind_qp(qp, port); if (ret && !force) return ret;
/* * rdma_counter_get_hwstat_value() - Get the sum value of all counters on a * specific port, including the running ones and history data
*/
u64 rdma_counter_get_hwstat_value(struct ib_device *dev, u32 port, u32 index)
{ struct rdma_port_counter *port_counter;
u64 sum;
port_counter = &dev->port_data[port].port_counter; if (!port_counter->hstats) return 0;
sum = get_running_counters_hwstat_sum(dev, port, index);
sum += port_counter->hstats->value[index];
/* * rdma_counter_bind_qpn_alloc() - Alloc a counter and bind QP @qp_num to it * The id of new counter is returned in @counter_id
*/ int rdma_counter_bind_qpn_alloc(struct ib_device *dev, u32 port,
u32 qp_num, u32 *counter_id)
{ struct rdma_port_counter *port_counter; struct rdma_counter *counter; struct ib_qp *qp; int ret;
if (!rdma_is_port_valid(dev, port)) return -EINVAL;
port_counter = &dev->port_data[port].port_counter; if (!port_counter->hstats) return -EOPNOTSUPP;
if (port_counter->mode.mode == RDMA_COUNTER_MODE_AUTO) return -EINVAL;
qp = rdma_counter_get_qp(dev, qp_num); if (!qp) return -ENOENT;
if (rdma_is_port_valid(dev, qp->port) && (qp->port != port)) {
ret = -EINVAL; goto err;
}
counter = alloc_and_bind(dev, port, qp, RDMA_COUNTER_MODE_MANUAL, true); if (!counter) {
ret = -ENOMEM; goto err;
}
if (counter_id)
*counter_id = counter->id;
rdma_restrack_put(&qp->res); return 0;
err:
rdma_restrack_put(&qp->res); return ret;
}
/* * rdma_counter_unbind_qpn() - Unbind QP @qp_num from a counter
*/ int rdma_counter_unbind_qpn(struct ib_device *dev, u32 port,
u32 qp_num, u32 counter_id)
{ struct rdma_port_counter *port_counter; struct ib_qp *qp; int ret;
if (!rdma_is_port_valid(dev, port)) return -EINVAL;
qp = rdma_counter_get_qp(dev, qp_num); if (!qp) return -ENOENT;
if (rdma_is_port_valid(dev, qp->port) && (qp->port != port)) {
ret = -EINVAL; goto out;
}
port_counter = &dev->port_data[port].port_counter; if (!qp->counter || qp->counter->id != counter_id ||
port_counter->mode.mode != RDMA_COUNTER_MODE_MANUAL) {
ret = -EINVAL; goto out;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.