diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 7846d4348..af5e81bfe 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -203,6 +203,9 @@ struct scst_vdisk_dev { struct block_device *bdev; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) struct bio_set *vdisk_bioset; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + struct bio_set vdisk_bioset_struct; +#endif #endif uint64_t format_progress_to_do, format_progress_done; @@ -7817,15 +7820,22 @@ out: #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30) static int vdisk_create_bioset(struct scst_vdisk_dev *virt_dev) { - int res; + int res = 0; EXTRACHECKS_BUG_ON(virt_dev->vdisk_bioset || !virt_dev->blockio); /* Pool size doesn't really matter */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + virt_dev->vdisk_bioset = &virt_dev->vdisk_bioset_struct; + res = bioset_init(&virt_dev->vdisk_bioset_struct, 2, 0, + BIOSET_NEED_BVECS); +#else virt_dev->vdisk_bioset = bioset_create(2, 0, BIOSET_NEED_BVECS); - if (virt_dev->vdisk_bioset == NULL) { - PRINT_ERROR("Failed to create bioset (dev %s)", virt_dev->name); + if (virt_dev->vdisk_bioset == NULL) res = -ENOMEM; +#endif + if (res < 0) { + PRINT_ERROR("Failed to create bioset (dev %s)", virt_dev->name); goto out; } @@ -7849,15 +7859,24 @@ out: return res; out_free: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + bioset_exit(virt_dev->vdisk_bioset); +#else bioset_free(virt_dev->vdisk_bioset); +#endif virt_dev->vdisk_bioset = NULL; goto out; } static void vdisk_free_bioset(struct scst_vdisk_dev *virt_dev) { - if (virt_dev->vdisk_bioset != NULL) - bioset_free(virt_dev->vdisk_bioset); + if (virt_dev->vdisk_bioset == NULL) + return; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + bioset_exit(virt_dev->vdisk_bioset); +#else + bioset_free(virt_dev->vdisk_bioset); +#endif } #endif diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 2068e2c97..0f155ce53 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -5825,17 +5825,9 @@ again: #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) if (scst_poll_ns > 0) { - struct timespec ts; ktime_t end, kt; - int rc; - rc = __getnstimeofday(&ts); - if (unlikely(rc != 0)) { - WARN_ON_ONCE(rc); - goto go; - } - - end = timespec_to_ktime(ts); + end = ktime_get(); end = ktime_add_ns(end, scst_poll_ns); do { @@ -5846,16 +5838,9 @@ again: goto again; } cpu_relax(); - rc = __getnstimeofday(&ts); - if (unlikely(rc != 0)) { - WARN_ON_ONCE(rc); - goto go; - } - kt = timespec_to_ktime(ts); + kt = ktime_get(); } while (ktime_before(kt, end)); } - -go: #endif spin_lock_irq(&p_cmd_threads->cmd_list_lock); spin_lock(&thr->thr_cmd_list_lock); diff --git a/srpt/Makefile b/srpt/Makefile index 35da325f5..31c92659a 100644 --- a/srpt/Makefile +++ b/srpt/Makefile @@ -246,6 +246,11 @@ conftest/rdma_destroy_ah/result-$(KVER).txt: \ echo "$(call run_conftest_bool,rdma_destroy_ah, \ HAVE_RDMA_DESTROY_AH)" >"$@" +conftest/rdma_query_gid/result-$(KVER).txt: \ + conftest/rdma_query_gid/rdma_query_gid.c \ + conftest/rdma_query_gid/Makefile + echo "$(call run_conftest_bool,rdma_query_gid,HAVE_RDMA_QUERY_GID)" >"$@" + conftest/register_mad_agent/result-$(KVER).txt: \ conftest/register_mad_agent/register_mad_agent.c \ conftest/register_mad_agent/Makefile diff --git a/srpt/conftest/rdma_query_gid/Makefile b/srpt/conftest/rdma_query_gid/Makefile new file mode 100644 index 000000000..cbc811e2d --- /dev/null +++ b/srpt/conftest/rdma_query_gid/Makefile @@ -0,0 +1,3 @@ +LINUXINCLUDE := $(PRE_CFLAGS) $(LINUXINCLUDE) + +obj-m += rdma_query_gid.o diff --git a/srpt/conftest/rdma_query_gid/rdma_query_gid.c b/srpt/conftest/rdma_query_gid/rdma_query_gid.c new file mode 100644 index 000000000..f7589eef2 --- /dev/null +++ b/srpt/conftest/rdma_query_gid/rdma_query_gid.c @@ -0,0 +1,9 @@ +#include +#include + +static int modinit(void) +{ + return rdma_query_gid(NULL, 0, 0, NULL, NULL); +} + +module_init(modinit); diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index a29634d6b..d2ad5f262 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -693,11 +693,15 @@ static int srpt_refresh_port(struct srpt_port *sport) sport->sm_lid = port_attr.sm_lid; sport->lid = port_attr.lid; +#if HAVE_RDMA_QUERY_GID + ret = rdma_query_gid(sport->sdev->device, sport->port, 0, &sport->gid); +#else ret = ib_query_gid(sport->sdev->device, sport->port, 0, &sport->gid #ifdef IB_QUERY_GID_HAS_ATTR_ARG , NULL #endif ); +#endif if (ret) return ret; @@ -940,7 +944,8 @@ static int srpt_post_recv(struct srpt_device *sdev, struct srpt_rdma_ch *ch, struct srpt_recv_ioctx *ioctx) { struct ib_sge list; - struct ib_recv_wr wr, *bad_wr; + struct ib_recv_wr wr; + struct ib_recv_wr *bad_wr; BUG_ON(!sdev); wr.wr_id = encode_wr_id(SRPT_RECV, ioctx->ioctx.index); @@ -973,7 +978,8 @@ static int srpt_post_send(struct srpt_rdma_ch *ch, struct srpt_send_ioctx *ioctx, int len) { struct ib_sge list; - struct ib_send_wr wr, *bad_wr; + struct ib_send_wr wr; + struct ib_send_wr *bad_wr; struct srpt_device *sdev = ch->sport->sdev; int ret; @@ -1016,7 +1022,8 @@ out: */ static int srpt_zerolength_write(struct srpt_rdma_ch *ch) { - struct ib_send_wr wr, *bad_wr; + struct ib_send_wr wr; + struct ib_send_wr *bad_wr; memset(&wr, 0, sizeof(wr)); wr.opcode = IB_WR_RDMA_WRITE; @@ -2242,17 +2249,23 @@ retry: * max_sge values < max_sge_delta, use max_sge. For intermediate * max_sge values, use max_sge_delta. */ - ch->max_sge = sdev->dev_attr.max_sge - - min(max_sge_delta, - max_t(int, 0, - sdev->dev_attr.max_sge - max_sge_delta)); - qp_init->cap.max_send_sge = ch->max_sge; - qp_init->cap.max_recv_sge = ch->max_sge; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) + ch->max_send_sge = sdev->dev_attr.max_send_sge; + ch->max_recv_sge = sdev->dev_attr.max_recv_sge; +#else + ch->max_send_sge = sdev->dev_attr.max_sge - + min_t(unsigned, max_sge_delta, + max_t(int, 0, + sdev->dev_attr.max_sge - max_sge_delta)); + ch->max_recv_sge = ch->max_send_sge; +#endif + qp_init->cap.max_send_sge = ch->max_send_sge; + qp_init->cap.max_recv_sge = ch->max_recv_sge; if (sdev->use_srq) { qp_init->srq = sdev->srq; } else { qp_init->cap.max_recv_wr = ch->rq_size; - qp_init->cap.max_recv_sge = ch->max_sge; + qp_init->cap.max_recv_sge = ch->max_recv_sge; } if (ch->using_rdma_cm) { @@ -2494,8 +2507,16 @@ static u16 srpt_next_comp_vector(struct srpt_port *sport) return comp_vector; } -/* - * srpt_cm_req_recv() - Process the IB_CM_REQ_RECEIVED event. +/** + * srpt_cm_req_recv - process the event IB_CM_REQ_RECEIVED + * @sdev: HCA through which the login request was received. + * @ib_cm_id: IB/CM connection identifier in case of IB/CM. + * @rdma_cm_id: RDMA/CM connection identifier in case of RDMA/CM. + * @port_num: Port through which the REQ message was received. + * @pkey: P_Key of the incoming connection. + * @req: SRP login request. + * @src_addr: GID (IB/CM) or IP address (RDMA/CM) of the port that submitted + * the login request. * * Ownership of the cm_id is transferred to the target session if this * function returns zero. Otherwise the caller remains the owner of cm_id. @@ -2597,8 +2618,9 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, rdma_cm_id->context = ch; } /* - * Avoid QUEUE_FULL conditions by limiting the number of buffers used - * for the SRP protocol to the SCST SCSI command queue size. + * ch->rq_size should be at least as large as the initiator queue + * depth to avoid that the initiator driver has to report QUEUE_FULL + * to the SCSI mid-layer. */ ch->rq_size = min(MAX_SRPT_RQ_SIZE, scst_get_max_lun_commands(NULL, 0)); spin_lock_init(&ch->spinlock); @@ -2765,7 +2787,8 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, goto reject; default: rej->reason = cpu_to_be32(SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); - pr_err("sending SRP_LOGIN_REQ response failed (error code = %d)\n", ret); + pr_err("sending SRP_LOGIN_REQ response failed (error code = %d)\n", + ret); goto reject; } @@ -2803,6 +2826,7 @@ reject: rej->tag = req->tag; rej->buf_fmt = cpu_to_be16(SRP_BUF_FORMAT_DIRECT | SRP_BUF_FORMAT_INDIRECT); + if (rdma_cm_id) rdma_reject(rdma_cm_id, rej, sizeof(*rej)); else @@ -3101,7 +3125,7 @@ static int srpt_map_sg_to_ib_sge(struct srpt_rdma_ch *ch, BUG_ON(!ioctx); BUG_ON(!cmd); dev = ch->sport->sdev->device; - max_sge = ch->max_sge; + max_sge = ch->max_send_sge; dir = scst_cmd_get_data_direction(cmd); BUG_ON(dir == SCST_DATA_NONE); /* diff --git a/srpt/src/ib_srpt.h b/srpt/src/ib_srpt.h index d7dc9a882..7eb7e51fe 100644 --- a/srpt/src/ib_srpt.h +++ b/srpt/src/ib_srpt.h @@ -316,7 +316,8 @@ enum rdma_ch_state { * @cq: IB completion queue for this channel. * @kref: Per-channel reference count. * @rq_size: IB receive queue size. - * @max_sge: Maximum length of RDMA scatter list. + * @max_send_sge: Maximum length of RDMA send scatter list. + * @max_recv_sge: Maximum length of RDMA receive scatter list. * @max_rsp_size: Maximum size of an SRP response message in bytes. * @sq_wr_avail: number of work requests available in the send queue. * @sport: pointer to the information of the HCA port used by this @@ -360,7 +361,8 @@ struct srpt_rdma_ch { struct kref kref; struct rcu_head rcu; int rq_size; - int max_sge; + int max_send_sge; + int max_recv_sge; int max_rsp_size; atomic_t sq_wr_avail; struct srpt_port *sport;