Commit 33eb12f2 authored by Patrisious Haddad's avatar Patrisious Haddad Committed by Jason Gunthorpe

RDMA/nldev: Return an error message on failure to turn auto mode

The bounded counter can't be reconfigured to be in auto mode, in attempt
to do it, the user will get an error, but without any hint why. Update
nldev interface to return an error message through extack mechanism.

Link: https://lore.kernel.org/r/20201230130240.180737-1-leon@kernel.orgSigned-off-by: default avatarPatrisious Haddad <phaddad@nvidia.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@nvidia.com>
parent 7fbc3c37
...@@ -10,30 +10,35 @@ ...@@ -10,30 +10,35 @@
#define ALL_AUTO_MODE_MASKS (RDMA_COUNTER_MASK_QP_TYPE | RDMA_COUNTER_MASK_PID) #define ALL_AUTO_MODE_MASKS (RDMA_COUNTER_MASK_QP_TYPE | RDMA_COUNTER_MASK_PID)
static int __counter_set_mode(struct rdma_counter_mode *curr, static int __counter_set_mode(struct rdma_port_counter *port_counter,
enum rdma_nl_counter_mode new_mode, enum rdma_nl_counter_mode new_mode,
enum rdma_nl_counter_mask new_mask) enum rdma_nl_counter_mask new_mask)
{ {
if ((new_mode == RDMA_COUNTER_MODE_AUTO) && if (new_mode == RDMA_COUNTER_MODE_AUTO && port_counter->num_counters)
((new_mask & (~ALL_AUTO_MODE_MASKS)) || if (new_mask & ~ALL_AUTO_MODE_MASKS ||
(curr->mode != RDMA_COUNTER_MODE_NONE))) port_counter->mode.mode != RDMA_COUNTER_MODE_NONE)
return -EINVAL; return -EINVAL;
curr->mode = new_mode; port_counter->mode.mode = new_mode;
curr->mask = new_mask; port_counter->mode.mask = new_mask;
return 0; return 0;
} }
/** /**
* rdma_counter_set_auto_mode() - Turn on/off per-port auto mode * rdma_counter_set_auto_mode() - Turn on/off per-port auto mode
* *
* When @on is true, the @mask must be set; When @on is false, it goes * @dev: Device to operate
* into manual mode if there's any counter, so that the user is able to * @port: Port to use
* manually access them. * @mask: Mask to configure
* @extack: Message to the user
*
* Return 0 on success.
*/ */
int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port, int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port,
bool on, enum rdma_nl_counter_mask mask) enum rdma_nl_counter_mask mask,
struct netlink_ext_ack *extack)
{ {
enum rdma_nl_counter_mode mode = RDMA_COUNTER_MODE_AUTO;
struct rdma_port_counter *port_counter; struct rdma_port_counter *port_counter;
int ret; int ret;
...@@ -42,23 +47,23 @@ int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port, ...@@ -42,23 +47,23 @@ int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port,
return -EOPNOTSUPP; return -EOPNOTSUPP;
mutex_lock(&port_counter->lock); mutex_lock(&port_counter->lock);
if (on) { if (mask) {
ret = __counter_set_mode(&port_counter->mode, ret = __counter_set_mode(port_counter, mode, mask);
RDMA_COUNTER_MODE_AUTO, mask); if (ret)
} else { NL_SET_ERR_MSG(
if (port_counter->mode.mode != RDMA_COUNTER_MODE_AUTO) { extack,
ret = -EINVAL; "Turning on auto mode is not allowed when there is bound QP");
goto out; goto out;
} }
if (port_counter->num_counters) if (port_counter->mode.mode != RDMA_COUNTER_MODE_AUTO) {
ret = __counter_set_mode(&port_counter->mode, ret = -EINVAL;
RDMA_COUNTER_MODE_MANUAL, 0); goto out;
else
ret = __counter_set_mode(&port_counter->mode,
RDMA_COUNTER_MODE_NONE, 0);
} }
mode = (port_counter->num_counters) ? RDMA_COUNTER_MODE_MANUAL :
RDMA_COUNTER_MODE_NONE;
ret = __counter_set_mode(port_counter, mode, 0);
out: out:
mutex_unlock(&port_counter->lock); mutex_unlock(&port_counter->lock);
return ret; return ret;
...@@ -122,8 +127,8 @@ static struct rdma_counter *alloc_and_bind(struct ib_device *dev, u8 port, ...@@ -122,8 +127,8 @@ static struct rdma_counter *alloc_and_bind(struct ib_device *dev, u8 port,
mutex_lock(&port_counter->lock); mutex_lock(&port_counter->lock);
switch (mode) { switch (mode) {
case RDMA_COUNTER_MODE_MANUAL: case RDMA_COUNTER_MODE_MANUAL:
ret = __counter_set_mode(&port_counter->mode, ret = __counter_set_mode(port_counter, RDMA_COUNTER_MODE_MANUAL,
RDMA_COUNTER_MODE_MANUAL, 0); 0);
if (ret) { if (ret) {
mutex_unlock(&port_counter->lock); mutex_unlock(&port_counter->lock);
goto err_mode; goto err_mode;
...@@ -170,8 +175,7 @@ static void rdma_counter_free(struct rdma_counter *counter) ...@@ -170,8 +175,7 @@ static void rdma_counter_free(struct rdma_counter *counter)
port_counter->num_counters--; port_counter->num_counters--;
if (!port_counter->num_counters && if (!port_counter->num_counters &&
(port_counter->mode.mode == RDMA_COUNTER_MODE_MANUAL)) (port_counter->mode.mode == RDMA_COUNTER_MODE_MANUAL))
__counter_set_mode(&port_counter->mode, RDMA_COUNTER_MODE_NONE, __counter_set_mode(port_counter, RDMA_COUNTER_MODE_NONE, 0);
0);
mutex_unlock(&port_counter->lock); mutex_unlock(&port_counter->lock);
......
...@@ -1768,9 +1768,7 @@ static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -1768,9 +1768,7 @@ static int nldev_stat_set_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
if (tb[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK]) if (tb[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK])
mask = nla_get_u32( mask = nla_get_u32(
tb[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK]); tb[RDMA_NLDEV_ATTR_STAT_AUTO_MODE_MASK]);
ret = rdma_counter_set_auto_mode(device, port, mask, extack);
ret = rdma_counter_set_auto_mode(device, port,
mask ? true : false, mask);
if (ret) if (ret)
goto err_msg; goto err_msg;
} else { } else {
......
...@@ -46,7 +46,8 @@ struct rdma_counter { ...@@ -46,7 +46,8 @@ struct rdma_counter {
void rdma_counter_init(struct ib_device *dev); void rdma_counter_init(struct ib_device *dev);
void rdma_counter_release(struct ib_device *dev); void rdma_counter_release(struct ib_device *dev);
int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port, int rdma_counter_set_auto_mode(struct ib_device *dev, u8 port,
bool on, enum rdma_nl_counter_mask mask); enum rdma_nl_counter_mask mask,
struct netlink_ext_ack *extack);
int rdma_counter_bind_qp_auto(struct ib_qp *qp, u8 port); int rdma_counter_bind_qp_auto(struct ib_qp *qp, u8 port);
int rdma_counter_unbind_qp(struct ib_qp *qp, bool force); int rdma_counter_unbind_qp(struct ib_qp *qp, bool force);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment