summaryrefslogtreecommitdiff
path: root/drivers/infiniband/ulp
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-12-14 09:27:13 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2022-12-14 09:27:13 -0800
commitab425febda94c7d287ea3433cbd0971771d6aeb4 (patch)
tree66240fae1e9720214afda604635c3f0da0b9ebfa /drivers/infiniband/ulp
parent08cdc2157966c07d3f986a097ddaa74cee312751 (diff)
parentdbc94a0fb81771a38733c0e8f2ea8c4fa6934dc1 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull rdma updates from Jason Gunthorpe: "Usual size of updates, a new driver, and most of the bulk focusing on rxe: - Usual typos, style, and language updates - Driver updates for mlx5, irdma, siw, rts, srp, hfi1, hns, erdma, mlx4, srp - Lots of RXE updates: * Improve reply error handling for bad MR operations * Code tidying * Debug printing uses common loggers * Remove half implemented RD related stuff * Support IBA's recently defined Atomic Write and Flush operations - erdma support for atomic operations - New driver 'mana' for Ethernet HW available in Azure VMs. This driver only supports DPDK" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (122 commits) IB/IPoIB: Fix queue count inconsistency for PKEY child interfaces RDMA: Add missed netdev_put() for the netdevice_tracker RDMA/rxe: Enable RDMA FLUSH capability for rxe device RDMA/cm: Make QP FLUSHABLE for supported device RDMA/rxe: Implement flush completion RDMA/rxe: Implement flush execution in responder side RDMA/rxe: Implement RC RDMA FLUSH service in requester side RDMA/rxe: Extend rxe packet format to support flush RDMA/rxe: Allow registering persistent flag for pmem MR only RDMA/rxe: Extend rxe user ABI to support flush RDMA: Extend RDMA kernel verbs ABI to support flush RDMA: Extend RDMA user ABI to support flush RDMA/rxe: Fix incorrect responder length checking RDMA/rxe: Fix oops with zero length reads RDMA/mlx5: Remove not-used IB_FLOW_SPEC_IB define RDMA/hns: Fix XRC caps on HIP08 RDMA/hns: Fix error code of CMD RDMA/hns: Fix page size cap from firmware RDMA/hns: Fix PBL page MTR find RDMA/hns: Fix AH attr queried by query_qp ...
Diffstat (limited to 'drivers/infiniband/ulp')
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_netlink.c7
-rw-r--r--drivers/infiniband/ulp/iser/iser_verbs.c67
-rw-r--r--drivers/infiniband/ulp/isert/ib_isert.c5
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs-clt.c6
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs-pri.h3
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c13
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs-srv.c72
-rw-r--r--drivers/infiniband/ulp/rtrs/rtrs.c22
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c96
9 files changed, 164 insertions, 127 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
index ea16ba5d8da6..9ad8d9856275 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_netlink.c
@@ -41,6 +41,11 @@ static const struct nla_policy ipoib_policy[IFLA_IPOIB_MAX + 1] = {
[IFLA_IPOIB_UMCAST] = { .type = NLA_U16 },
};
+static unsigned int ipoib_get_max_num_queues(void)
+{
+ return min_t(unsigned int, num_possible_cpus(), 128);
+}
+
static int ipoib_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
struct ipoib_dev_priv *priv = ipoib_priv(dev);
@@ -172,6 +177,8 @@ static struct rtnl_link_ops ipoib_link_ops __read_mostly = {
.changelink = ipoib_changelink,
.get_size = ipoib_get_size,
.fill_info = ipoib_fill_info,
+ .get_num_rx_queues = ipoib_get_max_num_queues,
+ .get_num_tx_queues = ipoib_get_max_num_queues,
};
struct rtnl_link_ops *ipoib_get_link_ops(void)
diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c
index a00ca117303a..1b8eda0dae4e 100644
--- a/drivers/infiniband/ulp/iser/iser_verbs.c
+++ b/drivers/infiniband/ulp/iser/iser_verbs.c
@@ -347,22 +347,6 @@ static void iser_device_try_release(struct iser_device *device)
mutex_unlock(&ig.device_list_mutex);
}
-/*
- * Called with state mutex held
- */
-static int iser_conn_state_comp_exch(struct iser_conn *iser_conn,
- enum iser_conn_state comp,
- enum iser_conn_state exch)
-{
- int ret;
-
- ret = (iser_conn->state == comp);
- if (ret)
- iser_conn->state = exch;
-
- return ret;
-}
-
void iser_release_work(struct work_struct *work)
{
struct iser_conn *iser_conn;
@@ -464,11 +448,13 @@ int iser_conn_terminate(struct iser_conn *iser_conn)
struct ib_conn *ib_conn = &iser_conn->ib_conn;
int err = 0;
+ lockdep_assert_held(&iser_conn->state_mutex);
+
/* terminate the iser conn only if the conn state is UP */
- if (!iser_conn_state_comp_exch(iser_conn, ISER_CONN_UP,
- ISER_CONN_TERMINATING))
+ if (iser_conn->state != ISER_CONN_UP)
return 0;
+ iser_conn->state = ISER_CONN_TERMINATING;
iser_info("iser_conn %p state %d\n", iser_conn, iser_conn->state);
/* suspend queuing of new iscsi commands */
@@ -498,9 +484,10 @@ int iser_conn_terminate(struct iser_conn *iser_conn)
*/
static void iser_connect_error(struct rdma_cm_id *cma_id)
{
- struct iser_conn *iser_conn;
+ struct iser_conn *iser_conn = cma_id->context;
+
+ lockdep_assert_held(&iser_conn->state_mutex);
- iser_conn = cma_id->context;
iser_conn->state = ISER_CONN_TERMINATING;
}
@@ -542,12 +529,13 @@ static void iser_calc_scsi_params(struct iser_conn *iser_conn,
*/
static void iser_addr_handler(struct rdma_cm_id *cma_id)
{
+ struct iser_conn *iser_conn = cma_id->context;
struct iser_device *device;
- struct iser_conn *iser_conn;
struct ib_conn *ib_conn;
int ret;
- iser_conn = cma_id->context;
+ lockdep_assert_held(&iser_conn->state_mutex);
+
if (iser_conn->state != ISER_CONN_PENDING)
/* bailout */
return;
@@ -597,6 +585,8 @@ static void iser_route_handler(struct rdma_cm_id *cma_id)
struct ib_conn *ib_conn = &iser_conn->ib_conn;
struct ib_device *ib_dev = ib_conn->device->ib_device;
+ lockdep_assert_held(&iser_conn->state_mutex);
+
if (iser_conn->state != ISER_CONN_PENDING)
/* bailout */
return;
@@ -629,14 +619,18 @@ failure:
iser_connect_error(cma_id);
}
+/*
+ * Called with state mutex held
+ */
static void iser_connected_handler(struct rdma_cm_id *cma_id,
const void *private_data)
{
- struct iser_conn *iser_conn;
+ struct iser_conn *iser_conn = cma_id->context;
struct ib_qp_attr attr;
struct ib_qp_init_attr init_attr;
- iser_conn = cma_id->context;
+ lockdep_assert_held(&iser_conn->state_mutex);
+
if (iser_conn->state != ISER_CONN_PENDING)
/* bailout */
return;
@@ -657,30 +651,27 @@ static void iser_connected_handler(struct rdma_cm_id *cma_id,
complete(&iser_conn->up_completion);
}
-static void iser_disconnected_handler(struct rdma_cm_id *cma_id)
-{
- struct iser_conn *iser_conn = cma_id->context;
-
- if (iser_conn_terminate(iser_conn)) {
- if (iser_conn->iscsi_conn)
- iscsi_conn_failure(iser_conn->iscsi_conn,
- ISCSI_ERR_CONN_FAILED);
- else
- iser_err("iscsi_iser connection isn't bound\n");
- }
-}
-
+/*
+ * Called with state mutex held
+ */
static void iser_cleanup_handler(struct rdma_cm_id *cma_id,
bool destroy)
{
struct iser_conn *iser_conn = cma_id->context;
+ lockdep_assert_held(&iser_conn->state_mutex);
/*
* We are not guaranteed that we visited disconnected_handler
* by now, call it here to be safe that we handle CM drep
* and flush errors.
*/
- iser_disconnected_handler(cma_id);
+ if (iser_conn_terminate(iser_conn)) {
+ if (iser_conn->iscsi_conn)
+ iscsi_conn_failure(iser_conn->iscsi_conn,
+ ISCSI_ERR_CONN_FAILED);
+ else
+ iser_err("iscsi_iser connection isn't bound\n");
+ }
iser_free_ib_conn_res(iser_conn, destroy);
complete(&iser_conn->ib_completion);
}
diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index b360a1527cd1..75404885cf98 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -993,9 +993,8 @@ isert_rx_login_req(struct isert_conn *isert_conn)
* login request PDU.
*/
login->leading_connection = (!login_req->tsih) ? 1 : 0;
- login->current_stage =
- (login_req->flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK)
- >> 2;
+ login->current_stage = ISCSI_LOGIN_CURRENT_STAGE(
+ login_req->flags);
login->version_min = login_req->min_version;
login->version_max = login_req->max_version;
memcpy(login->isid, login_req->isid, 6);
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
index 205fd44a4727..80abf45a197a 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c
@@ -1064,10 +1064,8 @@ static int rtrs_map_sg_fr(struct rtrs_clt_io_req *req, size_t count)
/* Align the MR to a 4K page size to match the block virt boundary */
nr = ib_map_mr_sg(req->mr, req->sglist, count, NULL, SZ_4K);
- if (nr < 0)
- return nr;
- if (nr < req->sg_cnt)
- return -EINVAL;
+ if (nr != count)
+ return nr < 0 ? nr : -EINVAL;
ib_update_fast_reg_key(req->mr, ib_inc_rkey(req->mr->rkey));
return nr;
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-pri.h b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
index a2420eecaf5a..ab25619261d2 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-pri.h
+++ b/drivers/infiniband/ulp/rtrs/rtrs-pri.h
@@ -68,10 +68,7 @@ enum {
struct rtrs_ib_dev;
struct rtrs_rdma_dev_pd_ops {
- struct rtrs_ib_dev *(*alloc)(void);
- void (*free)(struct rtrs_ib_dev *dev);
int (*init)(struct rtrs_ib_dev *dev);
- void (*deinit)(struct rtrs_ib_dev *dev);
};
struct rtrs_rdma_dev_pd {
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
index 2a3c9ac64a42..c76ba29da1e2 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-srv-sysfs.c
@@ -203,7 +203,6 @@ rtrs_srv_destroy_once_sysfs_root_folders(struct rtrs_srv_path *srv_path)
mutex_lock(&srv->paths_mutex);
if (!--srv->dev_ref) {
- kobject_del(srv->kobj_paths);
kobject_put(srv->kobj_paths);
mutex_unlock(&srv->paths_mutex);
device_del(&srv->dev);
@@ -304,12 +303,18 @@ destroy_root:
void rtrs_srv_destroy_path_files(struct rtrs_srv_path *srv_path)
{
- if (srv_path->kobj.state_in_sysfs) {
+ if (srv_path->stats->kobj_stats.state_in_sysfs) {
+ sysfs_remove_group(&srv_path->stats->kobj_stats,
+ &rtrs_srv_stats_attr_group);
kobject_del(&srv_path->stats->kobj_stats);
kobject_put(&srv_path->stats->kobj_stats);
+ }
+
+ if (srv_path->kobj.state_in_sysfs) {
sysfs_remove_group(&srv_path->kobj, &rtrs_srv_path_attr_group);
+ kobject_del(&srv_path->kobj);
kobject_put(&srv_path->kobj);
-
- rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
}
+
+ rtrs_srv_destroy_once_sysfs_root_folders(srv_path);
}
diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
index 22d7ba05e9fe..d1703e2c0b82 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c
@@ -561,9 +561,11 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path)
{
struct rtrs_srv_sess *srv = srv_path->srv;
struct rtrs_path *ss = &srv_path->s;
- int i, mri, err, mrs_num;
+ int i, err, mrs_num;
unsigned int chunk_bits;
int chunks_per_mr = 1;
+ struct ib_mr *mr;
+ struct sg_table *sgt;
/*
* Here we map queue_depth chunks to MR. Firstly we have to
@@ -586,16 +588,14 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path)
if (!srv_path->mrs)
return -ENOMEM;
- srv_path->mrs_num = mrs_num;
-
- for (mri = 0; mri < mrs_num; mri++) {
- struct rtrs_srv_mr *srv_mr = &srv_path->mrs[mri];
- struct sg_table *sgt = &srv_mr->sgt;
+ for (srv_path->mrs_num = 0; srv_path->mrs_num < mrs_num;
+ srv_path->mrs_num++) {
+ struct rtrs_srv_mr *srv_mr = &srv_path->mrs[srv_path->mrs_num];
struct scatterlist *s;
- struct ib_mr *mr;
int nr, nr_sgt, chunks;
- chunks = chunks_per_mr * mri;
+ sgt = &srv_mr->sgt;
+ chunks = chunks_per_mr * srv_path->mrs_num;
if (!always_invalidate)
chunks_per_mr = min_t(int, chunks_per_mr,
srv->queue_depth - chunks);
@@ -622,7 +622,7 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path)
}
nr = ib_map_mr_sg(mr, sgt->sgl, nr_sgt,
NULL, max_chunk_size);
- if (nr < 0 || nr < sgt->nents) {
+ if (nr != nr_sgt) {
err = nr < 0 ? nr : -EINVAL;
goto dereg_mr;
}
@@ -644,31 +644,24 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path)
ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey));
srv_mr->mr = mr;
-
- continue;
-err:
- while (mri--) {
- srv_mr = &srv_path->mrs[mri];
- sgt = &srv_mr->sgt;
- mr = srv_mr->mr;
- rtrs_iu_free(srv_mr->iu, srv_path->s.dev->ib_dev, 1);
-dereg_mr:
- ib_dereg_mr(mr);
-unmap_sg:
- ib_dma_unmap_sg(srv_path->s.dev->ib_dev, sgt->sgl,
- sgt->nents, DMA_BIDIRECTIONAL);
-free_sg:
- sg_free_table(sgt);
- }
- kfree(srv_path->mrs);
-
- return err;
}
chunk_bits = ilog2(srv->queue_depth - 1) + 1;
srv_path->mem_bits = (MAX_IMM_PAYL_BITS - chunk_bits);
return 0;
+
+dereg_mr:
+ ib_dereg_mr(mr);
+unmap_sg:
+ ib_dma_unmap_sg(srv_path->s.dev->ib_dev, sgt->sgl,
+ sgt->nents, DMA_BIDIRECTIONAL);
+free_sg:
+ sg_free_table(sgt);
+err:
+ unmap_cont_bufs(srv_path);
+
+ return err;
}
static void rtrs_srv_hb_err_handler(struct rtrs_con *c)
@@ -1678,12 +1671,6 @@ static int create_con(struct rtrs_srv_path *srv_path,
srv->queue_depth * (1 + 2) + 1);
max_recv_wr = srv->queue_depth + 1;
- /*
- * If we have all receive requests posted and
- * all write requests posted and each read request
- * requires an invalidate request + drain
- * and qp gets into error state.
- */
}
cq_num = max_send_wr + max_recv_wr;
atomic_set(&con->c.sq_wr_avail, max_send_wr);
@@ -1950,22 +1937,21 @@ static int rtrs_srv_rdma_cm_handler(struct rdma_cm_id *cm_id,
{
struct rtrs_srv_path *srv_path = NULL;
struct rtrs_path *s = NULL;
+ struct rtrs_con *c = NULL;
- if (ev->event != RDMA_CM_EVENT_CONNECT_REQUEST) {
- struct rtrs_con *c = cm_id->context;
-
- s = c->path;
- srv_path = to_srv_path(s);
- }
-
- switch (ev->event) {
- case RDMA_CM_EVENT_CONNECT_REQUEST:
+ if (ev->event == RDMA_CM_EVENT_CONNECT_REQUEST)
/*
* In case of error cma.c will destroy cm_id,
* see cma_process_remove()
*/
return rtrs_rdma_connect(cm_id, ev->param.conn.private_data,
ev->param.conn.private_data_len);
+
+ c = cm_id->context;
+ s = c->path;
+ srv_path = to_srv_path(s);
+
+ switch (ev->event) {
case RDMA_CM_EVENT_ESTABLISHED:
/* Nothing here */
break;
diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c
index ed324b47d93a..4bf9d868cc52 100644
--- a/drivers/infiniband/ulp/rtrs/rtrs.c
+++ b/drivers/infiniband/ulp/rtrs/rtrs.c
@@ -557,7 +557,6 @@ EXPORT_SYMBOL(rtrs_addr_to_sockaddr);
void rtrs_rdma_dev_pd_init(enum ib_pd_flags pd_flags,
struct rtrs_rdma_dev_pd *pool)
{
- WARN_ON(pool->ops && (!pool->ops->alloc ^ !pool->ops->free));
INIT_LIST_HEAD(&pool->list);
mutex_init(&pool->mutex);
pool->pd_flags = pd_flags;
@@ -583,15 +582,8 @@ static void dev_free(struct kref *ref)
list_del(&dev->entry);
mutex_unlock(&pool->mutex);
- if (pool->ops && pool->ops->deinit)
- pool->ops->deinit(dev);
-
ib_dealloc_pd(dev->ib_pd);
-
- if (pool->ops && pool->ops->free)
- pool->ops->free(dev);
- else
- kfree(dev);
+ kfree(dev);
}
int rtrs_ib_dev_put(struct rtrs_ib_dev *dev)
@@ -618,11 +610,8 @@ rtrs_ib_dev_find_or_add(struct ib_device *ib_dev,
goto out_unlock;
}
mutex_unlock(&pool->mutex);
- if (pool->ops && pool->ops->alloc)
- dev = pool->ops->alloc();
- else
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (IS_ERR_OR_NULL(dev))
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
goto out_err;
kref_init(&dev->ref);
@@ -644,10 +633,7 @@ out_unlock:
out_free_pd:
ib_dealloc_pd(dev->ib_pd);
out_free_dev:
- if (pool->ops && pool->ops->free)
- pool->ops->free(dev);
- else
- kfree(dev);
+ kfree(dev);
out_err:
return NULL;
}
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 1075c2ac8fe2..b4d6a4a5ae81 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -3410,7 +3410,8 @@ static int srp_parse_options(struct net *net, const char *buf,
break;
case SRP_OPT_PKEY:
- if (match_hex(args, &token)) {
+ ret = match_hex(args, &token);
+ if (ret) {
pr_warn("bad P_Key parameter '%s'\n", p);
goto out;
}
@@ -3470,7 +3471,8 @@ static int srp_parse_options(struct net *net, const char *buf,
break;
case SRP_OPT_MAX_SECT:
- if (match_int(args, &token)) {
+ ret = match_int(args, &token);
+ if (ret) {
pr_warn("bad max sect parameter '%s'\n", p);
goto out;
}
@@ -3478,8 +3480,15 @@ static int srp_parse_options(struct net *net, const char *buf,
break;
case SRP_OPT_QUEUE_SIZE:
- if (match_int(args, &token) || token < 1) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for queue_size parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 1) {
pr_warn("bad queue_size parameter '%s'\n", p);
+ ret = -EINVAL;
goto out;
}
target->scsi_host->can_queue = token;
@@ -3490,25 +3499,40 @@ static int srp_parse_options(struct net *net, const char *buf,
break;
case SRP_OPT_MAX_CMD_PER_LUN:
- if (match_int(args, &token) || token < 1) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for max cmd_per_lun parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 1) {
pr_warn("bad max cmd_per_lun parameter '%s'\n",
p);
+ ret = -EINVAL;
goto out;
}
target->scsi_host->cmd_per_lun = token;
break;
case SRP_OPT_TARGET_CAN_QUEUE:
- if (match_int(args, &token) || token < 1) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for max target_can_queue parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 1) {
pr_warn("bad max target_can_queue parameter '%s'\n",
p);
+ ret = -EINVAL;
goto out;
}
target->target_can_queue = token;
break;
case SRP_OPT_IO_CLASS:
- if (match_hex(args, &token)) {
+ ret = match_hex(args, &token);
+ if (ret) {
pr_warn("bad IO class parameter '%s'\n", p);
goto out;
}
@@ -3517,6 +3541,7 @@ static int srp_parse_options(struct net *net, const char *buf,
pr_warn("unknown IO class parameter value %x specified (use %x or %x).\n",
token, SRP_REV10_IB_IO_CLASS,
SRP_REV16A_IB_IO_CLASS);
+ ret = -EINVAL;
goto out;
}
target->io_class = token;
@@ -3539,16 +3564,24 @@ static int srp_parse_options(struct net *net, const char *buf,
break;
case SRP_OPT_CMD_SG_ENTRIES:
- if (match_int(args, &token) || token < 1 || token > 255) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for max cmd_sg_entries parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 1 || token > 255) {
pr_warn("bad max cmd_sg_entries parameter '%s'\n",
p);
+ ret = -EINVAL;
goto out;
}
target->cmd_sg_cnt = token;
break;
case SRP_OPT_ALLOW_EXT_SG:
- if (match_int(args, &token)) {
+ ret = match_int(args, &token);
+ if (ret) {
pr_warn("bad allow_ext_sg parameter '%s'\n", p);
goto out;
}
@@ -3556,43 +3589,77 @@ static int srp_parse_options(struct net *net, const char *buf,
break;
case SRP_OPT_SG_TABLESIZE:
- if (match_int(args, &token) || token < 1 ||
- token > SG_MAX_SEGMENTS) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for max sg_tablesize parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 1 || token > SG_MAX_SEGMENTS) {
pr_warn("bad max sg_tablesize parameter '%s'\n",
p);
+ ret = -EINVAL;
goto out;
}
target->sg_tablesize = token;
break;
case SRP_OPT_COMP_VECTOR:
- if (match_int(args, &token) || token < 0) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for comp_vector parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 0) {
pr_warn("bad comp_vector parameter '%s'\n", p);
+ ret = -EINVAL;
goto out;
}
target->comp_vector = token;
break;
case SRP_OPT_TL_RETRY_COUNT:
- if (match_int(args, &token) || token < 2 || token > 7) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for tl_retry_count parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 2 || token > 7) {
pr_warn("bad tl_retry_count parameter '%s' (must be a number between 2 and 7)\n",
p);
+ ret = -EINVAL;
goto out;
}
target->tl_retry_count = token;
break;
case SRP_OPT_MAX_IT_IU_SIZE:
- if (match_int(args, &token) || token < 0) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for max it_iu_size parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 0) {
pr_warn("bad maximum initiator to target IU size '%s'\n", p);
+ ret = -EINVAL;
goto out;
}
target->max_it_iu_size = token;
break;
case SRP_OPT_CH_COUNT:
- if (match_int(args, &token) || token < 1) {
+ ret = match_int(args, &token);
+ if (ret) {
+ pr_warn("match_int() failed for channel count parameter '%s', Error %d\n",
+ p, ret);
+ goto out;
+ }
+ if (token < 1) {
pr_warn("bad channel count %s\n", p);
+ ret = -EINVAL;
goto out;
}
target->ch_count = token;
@@ -3601,6 +3668,7 @@ static int srp_parse_options(struct net *net, const char *buf,
default:
pr_warn("unknown parameter or missing value '%s' in target creation request\n",
p);
+ ret = -EINVAL;
goto out;
}
}