From 16ba3defb8bd01a9464ba4820a487f5b196b455b Mon Sep 17 00:00:00 2001 From: Erez Shitrit Date: Sun, 31 Dec 2017 15:33:15 +0200 Subject: IB/ipoib: Fix race condition in neigh creation When using enhanced mode for IPoIB, two threads may execute xmit in parallel to two different TX queues while the target is the same. In this case, both of them will add the same neighbor to the path's neigh link list and we might see the following message: list_add double add: new=ffff88024767a348, prev=ffff88024767a348... WARNING: lib/list_debug.c:31__list_add_valid+0x4e/0x70 ipoib_start_xmit+0x477/0x680 [ib_ipoib] dev_hard_start_xmit+0xb9/0x3e0 sch_direct_xmit+0xf9/0x250 __qdisc_run+0x176/0x5d0 __dev_queue_xmit+0x1f5/0xb10 __dev_queue_xmit+0x55/0xb10 Analysis: Two SKB are scheduled to be transmitted from two cores. In ipoib_start_xmit, both gets NULL when calling ipoib_neigh_get. Two calls to neigh_add_path are made. One thread takes the spin-lock and calls ipoib_neigh_alloc which creates the neigh structure, then (after the __path_find) the neigh is added to the path's neigh link list. When the second thread enters the critical section it also calls ipoib_neigh_alloc but in this case it gets the already allocated ipoib_neigh structure, which is already linked to the path's neigh link list and adds it again to the list. Which beside of triggering the list, it creates a loop in the linked list. This loop leads to endless loop inside path_rec_completion. Solution: Check list_empty(&neigh->list) before adding to the list. Add a similar fix in "ipoib_multicast.c::ipoib_mcast_send" Fixes: b63b70d87741 ('IPoIB: Use a private hash table for path lookup in xmit path') Signed-off-by: Erez Shitrit Reviewed-by: Alex Vesker Signed-off-by: Leon Romanovsky Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/ipoib/ipoib_main.c | 25 ++++++++++++++++++------- drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 5 ++++- 2 files changed, 22 insertions(+), 8 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 12b7f911f0e5..8880351df179 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -902,8 +902,8 @@ static int path_rec_start(struct net_device *dev, return 0; } -static void neigh_add_path(struct sk_buff *skb, u8 *daddr, - struct net_device *dev) +static struct ipoib_neigh *neigh_add_path(struct sk_buff *skb, u8 *daddr, + struct net_device *dev) { struct ipoib_dev_priv *priv = ipoib_priv(dev); struct rdma_netdev *rn = netdev_priv(dev); @@ -917,7 +917,15 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, spin_unlock_irqrestore(&priv->lock, flags); ++dev->stats.tx_dropped; dev_kfree_skb_any(skb); - return; + return NULL; + } + + /* To avoid race condition, make sure that the + * neigh will be added only once. + */ + if (unlikely(!list_empty(&neigh->list))) { + spin_unlock_irqrestore(&priv->lock, flags); + return neigh; } path = __path_find(dev, daddr + 4); @@ -956,7 +964,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, path->ah->last_send = rn->send(dev, skb, path->ah->ah, IPOIB_QPN(daddr)); ipoib_neigh_put(neigh); - return; + return NULL; } } else { neigh->ah = NULL; @@ -973,7 +981,7 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, spin_unlock_irqrestore(&priv->lock, flags); ipoib_neigh_put(neigh); - return; + return NULL; err_path: ipoib_neigh_free(neigh); @@ -983,6 +991,8 @@ err_drop: spin_unlock_irqrestore(&priv->lock, flags); ipoib_neigh_put(neigh); + + return NULL; } static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, @@ -1091,8 +1101,9 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) case htons(ETH_P_TIPC): neigh = ipoib_neigh_get(dev, phdr->hwaddr); if (unlikely(!neigh)) { - neigh_add_path(skb, phdr->hwaddr, dev); - return NETDEV_TX_OK; + neigh = neigh_add_path(skb, phdr->hwaddr, dev); + if (likely(!neigh)) + return NETDEV_TX_OK; } break; case htons(ETH_P_ARP): diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 93e149efc1f5..9b3f47ae2016 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -816,7 +816,10 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb) spin_lock_irqsave(&priv->lock, flags); if (!neigh) { neigh = ipoib_neigh_alloc(daddr, dev); - if (neigh) { + /* Make sure that the neigh will be added only + * once to mcast list. + */ + if (neigh && list_empty(&neigh->list)) { kref_get(&mcast->ah->ref); neigh->ah = mcast->ah; list_add_tail(&neigh->list, &mcast->neigh_list); -- cgit v1.2.3 From bec40c26041de61162f7be9d2ce548c756ce0f65 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 3 Jan 2018 13:39:15 -0800 Subject: IB/srpt: Disable RDMA access by the initiator With the SRP protocol all RDMA operations are initiated by the target. Since no RDMA operations are initiated by the initiator, do not grant the initiator permission to submit RDMA reads or writes to the target. Signed-off-by: Bart Van Assche Cc: Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/srpt/ib_srpt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 8a1bd354b1cc..7c4249038004 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1013,8 +1013,7 @@ static int srpt_init_ch_qp(struct srpt_rdma_ch *ch, struct ib_qp *qp) return -ENOMEM; attr->qp_state = IB_QPS_INIT; - attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_READ | - IB_ACCESS_REMOTE_WRITE; + attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE; attr->port_num = ch->sport->port; attr->pkey_index = 0; -- cgit v1.2.3 From a1ffa4670cb97ae3a4b3e8535d88be5f643f7c3b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Wed, 3 Jan 2018 13:39:16 -0800 Subject: IB/srpt: Fix ACL lookup during login Make sure that the initiator port GUID is stored in ch->ini_guid. Note: when initiating a connection sgid and dgid members in struct sa_path_rec represent the source and destination GIDs. When accepting a connection however sgid represents the destination GID and dgid the source GID. Fixes: commit 2bce1a6d2209 ("IB/srpt: Accept GUIDs as port names") Signed-off-by: Bart Van Assche Cc: Signed-off-by: Jason Gunthorpe --- drivers/infiniband/ulp/srpt/ib_srpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 7c4249038004..bfa576aa9f03 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -2077,7 +2077,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, goto destroy_ib; } - guid = (__be16 *)¶m->primary_path->sgid.global.interface_id; + guid = (__be16 *)¶m->primary_path->dgid.global.interface_id; snprintf(ch->ini_guid, sizeof(ch->ini_guid), "%04x:%04x:%04x:%04x", be16_to_cpu(guid[0]), be16_to_cpu(guid[1]), be16_to_cpu(guid[2]), be16_to_cpu(guid[3])); -- cgit v1.2.3 From 1b0bb73f72d1b91c872e5c068ee5b46d943accad Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:40 -0800 Subject: IB/srpt: Remove an unused structure member Fixes: commit a42d985bd5b2 ("ib_srpt: Initial SRP Target merge for v3.3-rc1") Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 1 - drivers/infiniband/ulp/srpt/ib_srpt.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index bfa576aa9f03..81e8085bc5bb 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1123,7 +1123,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch) ioctx->state = SRPT_STATE_NEW; ioctx->n_rdma = 0; ioctx->n_rw_ctx = 0; - init_completion(&ioctx->tx_done); ioctx->queue_status_only = false; /* * transport_init_se_cmd() does not initialize all fields, so do it diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 673387d365a3..7fff73a5d1e6 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h @@ -207,7 +207,6 @@ struct srpt_send_ioctx { spinlock_t spinlock; enum srpt_command_state state; struct se_cmd cmd; - struct completion tx_done; u8 n_rdma; u8 n_rw_ctx; bool queue_status_only; -- cgit v1.2.3 From 10eac19bb272415cad6f28ebe8c055b648f334b1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:41 -0800 Subject: IB/srpt: Fix kernel-doc warnings in ib_srpt.c Avoid that warnings about missing parameter descriptions are reported when building with W=1. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 205 ++++++++++++++++++++++++---------- 1 file changed, 145 insertions(+), 60 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 81e8085bc5bb..1bcf8b3b6095 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -120,7 +120,9 @@ static bool srpt_set_ch_state(struct srpt_rdma_ch *ch, enum rdma_ch_state new) } /** - * srpt_event_handler() - Asynchronous IB event callback function. + * srpt_event_handler - asynchronous IB event callback function + * @handler: IB event handler registered by ib_register_event_handler(). + * @event: Description of the event that occurred. * * Callback function called by the InfiniBand core when an asynchronous IB * event occurs. This callback may occur in interrupt context. See also @@ -169,7 +171,9 @@ static void srpt_event_handler(struct ib_event_handler *handler, } /** - * srpt_srq_event() - SRQ event callback function. + * srpt_srq_event - SRQ event callback function + * @event: Description of the event that occurred. + * @ctx: Context pointer specified at SRQ creation time. */ static void srpt_srq_event(struct ib_event *event, void *ctx) { @@ -194,7 +198,9 @@ static const char *get_ch_state_name(enum rdma_ch_state s) } /** - * srpt_qp_event() - QP event callback function. + * srpt_qp_event - QP event callback function + * @event: Description of the event that occurred. + * @ch: SRPT RDMA channel. */ static void srpt_qp_event(struct ib_event *event, struct srpt_rdma_ch *ch) { @@ -217,8 +223,8 @@ static void srpt_qp_event(struct ib_event *event, struct srpt_rdma_ch *ch) } /** - * srpt_set_ioc() - Helper function for initializing an IOUnitInfo structure. - * + * srpt_set_ioc - initialize a IOUnitInfo structure + * @c_list: controller list. * @slot: one-based slot number. * @value: four-bit value. * @@ -241,7 +247,8 @@ static void srpt_set_ioc(u8 *c_list, u32 slot, u8 value) } /** - * srpt_get_class_port_info() - Copy ClassPortInfo to a management datagram. + * srpt_get_class_port_info - copy ClassPortInfo to a management datagram + * @mad: Datagram that will be sent as response to DM_ATTR_CLASS_PORT_INFO. * * See also section 16.3.3.1 ClassPortInfo in the InfiniBand Architecture * Specification. @@ -260,7 +267,8 @@ static void srpt_get_class_port_info(struct ib_dm_mad *mad) } /** - * srpt_get_iou() - Write IOUnitInfo to a management datagram. + * srpt_get_iou - write IOUnitInfo to a management datagram + * @mad: Datagram that will be sent as response to DM_ATTR_IOU_INFO. * * See also section 16.3.3.3 IOUnitInfo in the InfiniBand Architecture * Specification. See also section B.7, table B.6 in the SRP r16a document. @@ -284,7 +292,10 @@ static void srpt_get_iou(struct ib_dm_mad *mad) } /** - * srpt_get_ioc() - Write IOControllerprofile to a management datagram. + * srpt_get_ioc - write IOControllerprofile to a management datagram + * @sport: HCA port through which the MAD has been received. + * @slot: Slot number specified in DM_ATTR_IOC_PROFILE query. + * @mad: Datagram that will be sent as response to DM_ATTR_IOC_PROFILE. * * See also section 16.3.3.4 IOControllerProfile in the InfiniBand * Architecture Specification. See also section B.7, table B.7 in the SRP @@ -342,7 +353,12 @@ static void srpt_get_ioc(struct srpt_port *sport, u32 slot, } /** - * srpt_get_svc_entries() - Write ServiceEntries to a management datagram. + * srpt_get_svc_entries - write ServiceEntries to a management datagram + * @ioc_guid: I/O controller GUID to use in reply. + * @slot: I/O controller number. + * @hi: End of the range of service entries to be specified in the reply. + * @lo: Start of the range of service entries to be specified in the reply.. + * @mad: Datagram that will be sent as response to DM_ATTR_SVC_ENTRIES. * * See also section 16.3.3.5 ServiceEntries in the InfiniBand Architecture * Specification. See also section B.7, table B.8 in the SRP r16a document. @@ -379,8 +395,8 @@ static void srpt_get_svc_entries(u64 ioc_guid, } /** - * srpt_mgmt_method_get() - Process a received management datagram. - * @sp: source port through which the MAD has been received. + * srpt_mgmt_method_get - process a received management datagram + * @sp: HCA port through which the MAD has been received. * @rq_mad: received MAD. * @rsp_mad: response MAD. */ @@ -419,7 +435,9 @@ static void srpt_mgmt_method_get(struct srpt_port *sp, struct ib_mad *rq_mad, } /** - * srpt_mad_send_handler() - Post MAD-send callback function. + * srpt_mad_send_handler - MAD send completion callback + * @mad_agent: Return value of ib_register_mad_agent(). + * @mad_wc: Work completion reporting that the MAD has been sent. */ static void srpt_mad_send_handler(struct ib_mad_agent *mad_agent, struct ib_mad_send_wc *mad_wc) @@ -429,7 +447,10 @@ static void srpt_mad_send_handler(struct ib_mad_agent *mad_agent, } /** - * srpt_mad_recv_handler() - MAD reception callback function. + * srpt_mad_recv_handler - MAD reception callback function + * @mad_agent: Return value of ib_register_mad_agent(). + * @send_buf: Not used. + * @mad_wc: Work completion reporting that a MAD has been received. */ static void srpt_mad_recv_handler(struct ib_mad_agent *mad_agent, struct ib_mad_send_buf *send_buf, @@ -494,7 +515,8 @@ err: } /** - * srpt_refresh_port() - Configure a HCA port. + * srpt_refresh_port - configure a HCA port + * @sport: SRPT HCA port. * * Enable InfiniBand management datagram processing, update the cached sm_lid, * lid and gid values, and register a callback function for processing MADs @@ -577,7 +599,8 @@ err_mod_port: } /** - * srpt_unregister_mad_agent() - Unregister MAD callback functions. + * srpt_unregister_mad_agent - unregister MAD callback functions + * @sdev: SRPT HCA pointer. * * Note: It is safe to call this function more than once for the same device. */ @@ -602,7 +625,11 @@ static void srpt_unregister_mad_agent(struct srpt_device *sdev) } /** - * srpt_alloc_ioctx() - Allocate an SRPT I/O context structure. + * srpt_alloc_ioctx - allocate a SRPT I/O context structure + * @sdev: SRPT HCA pointer. + * @ioctx_size: I/O context size. + * @dma_size: Size of I/O context DMA buffer. + * @dir: DMA data direction. */ static struct srpt_ioctx *srpt_alloc_ioctx(struct srpt_device *sdev, int ioctx_size, int dma_size, @@ -633,7 +660,11 @@ err: } /** - * srpt_free_ioctx() - Free an SRPT I/O context structure. + * srpt_free_ioctx - free a SRPT I/O context structure + * @sdev: SRPT HCA pointer. + * @ioctx: I/O context pointer. + * @dma_size: Size of I/O context DMA buffer. + * @dir: DMA data direction. */ static void srpt_free_ioctx(struct srpt_device *sdev, struct srpt_ioctx *ioctx, int dma_size, enum dma_data_direction dir) @@ -647,7 +678,7 @@ static void srpt_free_ioctx(struct srpt_device *sdev, struct srpt_ioctx *ioctx, } /** - * srpt_alloc_ioctx_ring() - Allocate a ring of SRPT I/O context structures. + * srpt_alloc_ioctx_ring - allocate a ring of SRPT I/O context structures * @sdev: Device to allocate the I/O context ring for. * @ring_size: Number of elements in the I/O context ring. * @ioctx_size: I/O context size. @@ -685,7 +716,12 @@ out: } /** - * srpt_free_ioctx_ring() - Free the ring of SRPT I/O context structures. + * srpt_free_ioctx_ring - free the ring of SRPT I/O context structures + * @ioctx_ring: I/O context ring to be freed. + * @sdev: SRPT HCA pointer. + * @ring_size: Number of ring elements. + * @dma_size: Size of I/O context DMA buffer. + * @dir: DMA data direction. */ static void srpt_free_ioctx_ring(struct srpt_ioctx **ioctx_ring, struct srpt_device *sdev, int ring_size, @@ -702,7 +738,8 @@ static void srpt_free_ioctx_ring(struct srpt_ioctx **ioctx_ring, } /** - * srpt_get_cmd_state() - Get the state of a SCSI command. + * srpt_get_cmd_state - get the state of a SCSI command + * @ioctx: Send I/O context. */ static enum srpt_command_state srpt_get_cmd_state(struct srpt_send_ioctx *ioctx) { @@ -718,7 +755,9 @@ static enum srpt_command_state srpt_get_cmd_state(struct srpt_send_ioctx *ioctx) } /** - * srpt_set_cmd_state() - Set the state of a SCSI command. + * srpt_set_cmd_state - set the state of a SCSI command + * @ioctx: Send I/O context. + * @new: New I/O context state. * * Does not modify the state of aborted commands. Returns the previous command * state. @@ -741,7 +780,10 @@ static enum srpt_command_state srpt_set_cmd_state(struct srpt_send_ioctx *ioctx, } /** - * srpt_test_and_set_cmd_state() - Test and set the state of a command. + * srpt_test_and_set_cmd_state - test and set the state of a command + * @ioctx: Send I/O context. + * @old: Current I/O context state. + * @new: New I/O context state. * * Returns true if and only if the previous command state was equal to 'old'. */ @@ -765,7 +807,10 @@ static bool srpt_test_and_set_cmd_state(struct srpt_send_ioctx *ioctx, } /** - * srpt_post_recv() - Post an IB receive request. + * srpt_post_recv - post an IB receive request + * @sdev: SRPT HCA pointer. + * @ch: SRPT RDMA channel. + * @ioctx: Receive I/O context pointer. */ static int srpt_post_recv(struct srpt_device *sdev, struct srpt_rdma_ch *ch, struct srpt_recv_ioctx *ioctx) @@ -791,7 +836,8 @@ static int srpt_post_recv(struct srpt_device *sdev, struct srpt_rdma_ch *ch, } /** - * srpt_zerolength_write() - Perform a zero-length RDMA write. + * srpt_zerolength_write - perform a zero-length RDMA write + * @ch: SRPT RDMA channel. * * A quote from the InfiniBand specification: C9-88: For an HCA responder * using Reliable Connection service, for each zero-length RDMA READ or WRITE @@ -928,11 +974,13 @@ static inline void *srpt_get_desc_buf(struct srp_cmd *srp_cmd) } /** - * srpt_get_desc_tbl() - Parse the data descriptors of an SRP_CMD request. + * srpt_get_desc_tbl - parse the data descriptors of a SRP_CMD request * @ioctx: Pointer to the I/O context associated with the request. * @srp_cmd: Pointer to the SRP_CMD request data. * @dir: Pointer to the variable to which the transfer direction will be * written. + * @sg: [out] scatterlist allocated for the parsed SRP_CMD. + * @sg_cnt: [out] length of @sg. * @data_len: Pointer to the variable to which the total data length of all * descriptors in the SRP_CMD request will be written. * @@ -998,7 +1046,9 @@ static int srpt_get_desc_tbl(struct srpt_send_ioctx *ioctx, } /** - * srpt_init_ch_qp() - Initialize queue pair attributes. + * srpt_init_ch_qp - initialize queue pair attributes + * @ch: SRPT RDMA channel. + * @qp: Queue pair pointer. * * Initialized the attributes of queue pair 'qp' by allowing local write, * remote read and remote write. Also transitions 'qp' to state IB_QPS_INIT. @@ -1026,7 +1076,7 @@ static int srpt_init_ch_qp(struct srpt_rdma_ch *ch, struct ib_qp *qp) } /** - * srpt_ch_qp_rtr() - Change the state of a channel to 'ready to receive' (RTR). + * srpt_ch_qp_rtr - change the state of a channel to 'ready to receive' (RTR) * @ch: channel of the queue pair. * @qp: queue pair to change the state of. * @@ -1056,7 +1106,7 @@ out: } /** - * srpt_ch_qp_rts() - Change the state of a channel to 'ready to send' (RTS). + * srpt_ch_qp_rts - change the state of a channel to 'ready to send' (RTS) * @ch: channel of the queue pair. * @qp: queue pair to change the state of. * @@ -1086,7 +1136,8 @@ out: } /** - * srpt_ch_qp_err() - Set the channel queue pair state to 'error'. + * srpt_ch_qp_err - set the channel queue pair state to 'error' + * @ch: SRPT RDMA channel. */ static int srpt_ch_qp_err(struct srpt_rdma_ch *ch) { @@ -1097,7 +1148,8 @@ static int srpt_ch_qp_err(struct srpt_rdma_ch *ch) } /** - * srpt_get_send_ioctx() - Obtain an I/O context for sending to the initiator. + * srpt_get_send_ioctx - obtain an I/O context for sending to the initiator + * @ch: SRPT RDMA channel. */ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch) { @@ -1135,9 +1187,8 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch) } /** - * srpt_abort_cmd() - Abort a SCSI command. + * srpt_abort_cmd - abort a SCSI command * @ioctx: I/O context associated with the SCSI command. - * @context: Preferred execution context. */ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) { @@ -1205,6 +1256,10 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) } /** + * srpt_rdma_read_done - RDMA read completion callback + * @cq: Completion queue. + * @wc: Work completion. + * * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping * the data that has been transferred via IB RDMA had to be postponed until the * check_stop_free() callback. None of this is necessary anymore and needs to @@ -1236,7 +1291,7 @@ static void srpt_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc) } /** - * srpt_build_cmd_rsp() - Build an SRP_RSP response. + * srpt_build_cmd_rsp - build a SRP_RSP response * @ch: RDMA channel through which the request has been received. * @ioctx: I/O context associated with the SRP_CMD request. The response will * be built in the buffer ioctx->buf points at and hence this function will @@ -1296,7 +1351,7 @@ static int srpt_build_cmd_rsp(struct srpt_rdma_ch *ch, } /** - * srpt_build_tskmgmt_rsp() - Build a task management response. + * srpt_build_tskmgmt_rsp - build a task management response * @ch: RDMA channel through which the request has been received. * @ioctx: I/O context in which the SRP_RSP response will be built. * @rsp_code: RSP_CODE that will be stored in the response. @@ -1344,7 +1399,10 @@ static int srpt_check_stop_free(struct se_cmd *cmd) } /** - * srpt_handle_cmd() - Process SRP_CMD. + * srpt_handle_cmd - process a SRP_CMD information unit + * @ch: SRPT RDMA channel. + * @recv_ioctx: Receive I/O context. + * @send_ioctx: Send I/O context. */ static void srpt_handle_cmd(struct srpt_rdma_ch *ch, struct srpt_recv_ioctx *recv_ioctx, @@ -1426,7 +1484,10 @@ static int srp_tmr_to_tcm(int fn) } /** - * srpt_handle_tsk_mgmt() - Process an SRP_TSK_MGMT information unit. + * srpt_handle_tsk_mgmt - process a SRP_TSK_MGMT information unit + * @ch: SRPT RDMA channel. + * @recv_ioctx: Receive I/O context. + * @send_ioctx: Send I/O context. * * Returns 0 if and only if the request will be processed by the target core. * @@ -1469,9 +1530,10 @@ fail: } /** - * srpt_handle_new_iu() - Process a newly received information unit. + * srpt_handle_new_iu - process a newly received information unit * @ch: RDMA channel through which the information unit has been received. - * @ioctx: SRPT I/O context associated with the information unit. + * @recv_ioctx: Receive I/O context associated with the information unit. + * @send_ioctx: Send I/O context. */ static void srpt_handle_new_iu(struct srpt_rdma_ch *ch, struct srpt_recv_ioctx *recv_ioctx, @@ -1577,6 +1639,10 @@ static void srpt_process_wait_list(struct srpt_rdma_ch *ch) } /** + * srpt_send_done - send completion callback + * @cq: Completion queue. + * @wc: Work completion. + * * Note: Although this has not yet been observed during tests, at least in * theory it is possible that the srpt_get_send_ioctx() call invoked by * srpt_handle_new_iu() fails. This is possible because the req_lim_delta @@ -1618,7 +1684,8 @@ static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc) } /** - * srpt_create_ch_ib() - Create receive and send completion queues. + * srpt_create_ch_ib - create receive and send completion queues + * @ch: SRPT RDMA channel. */ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) { @@ -1717,7 +1784,8 @@ static void srpt_destroy_ch_ib(struct srpt_rdma_ch *ch) } /** - * srpt_close_ch() - Close an RDMA channel. + * srpt_close_ch - close a RDMA channel + * @ch: SRPT RDMA channel. * * Make sure all resources associated with the channel will be deallocated at * an appropriate time. @@ -1900,7 +1968,10 @@ static void srpt_release_channel_work(struct work_struct *w) } /** - * srpt_cm_req_recv() - Process the event IB_CM_REQ_RECEIVED. + * srpt_cm_req_recv - process the event IB_CM_REQ_RECEIVED + * @cm_id: IB/CM connection identifier. + * @param: IB/CM REQ parameters. + * @private_data: IB/CM REQ private data. * * Ownership of the cm_id is transferred to the target session if this * functions returns zero. Otherwise the caller remains the owner of cm_id. @@ -2205,7 +2276,8 @@ static void srpt_cm_rej_recv(struct srpt_rdma_ch *ch, } /** - * srpt_cm_rtu_recv() - Process an IB_CM_RTU_RECEIVED or USER_ESTABLISHED event. + * srpt_cm_rtu_recv - process an IB_CM_RTU_RECEIVED or USER_ESTABLISHED event + * @ch: SRPT RDMA channel. * * An IB_CM_RTU_RECEIVED message indicates that the connection is established * and that the recipient may begin transmitting (RTU = ready to use). @@ -2228,7 +2300,9 @@ static void srpt_cm_rtu_recv(struct srpt_rdma_ch *ch) } /** - * srpt_cm_handler() - IB connection manager callback function. + * srpt_cm_handler - IB connection manager callback function + * @cm_id: IB/CM connection identifier. + * @event: IB/CM event. * * A non-zero return value will cause the caller destroy the CM ID. * @@ -2297,7 +2371,7 @@ static int srpt_write_pending_status(struct se_cmd *se_cmd) } /* - * srpt_write_pending() - Start data transfer from initiator to target (write). + * srpt_write_pending - Start data transfer from initiator to target (write). */ static int srpt_write_pending(struct se_cmd *se_cmd) { @@ -2354,7 +2428,8 @@ static u8 tcm_to_srp_tsk_mgmt_status(const int tcm_mgmt_status) } /** - * srpt_queue_response() - Transmits the response to a SCSI command. + * srpt_queue_response - transmit the response to a SCSI command + * @cmd: SCSI target command. * * Callback function called by the TCM core. Must not block since it can be * invoked on the context of the IB completion handler. @@ -2494,7 +2569,8 @@ static void srpt_refresh_port_work(struct work_struct *work) } /** - * srpt_release_sdev() - Free the channel resources associated with a target. + * srpt_release_sdev - disable login and wait for associated channels + * @sdev: SRPT HCA pointer. */ static int srpt_release_sdev(struct srpt_device *sdev) { @@ -2622,7 +2698,8 @@ static int srpt_use_srq(struct srpt_device *sdev, bool use_srq) } /** - * srpt_add_one() - Infiniband device addition callback function. + * srpt_add_one - InfiniBand device addition callback function + * @device: Describes a HCA. */ static void srpt_add_one(struct ib_device *device) { @@ -2720,7 +2797,9 @@ err: } /** - * srpt_remove_one() - InfiniBand device removal callback function. + * srpt_remove_one - InfiniBand device removal callback function + * @device: Describes a HCA. + * @client_data: The value passed as the third argument to ib_set_client_data(). */ static void srpt_remove_one(struct ib_device *device, void *client_data) { @@ -2826,7 +2905,8 @@ static void srpt_release_cmd(struct se_cmd *se_cmd) } /** - * srpt_close_session() - Forcibly close a session. + * srpt_close_session - forcibly close a session + * @se_sess: SCSI target session. * * Callback function invoked by the TCM core to clean up sessions associated * with a node ACL when the user invokes @@ -2843,7 +2923,8 @@ static void srpt_close_session(struct se_session *se_sess) } /** - * srpt_sess_get_index() - Return the value of scsiAttIntrPortIndex (SCSI-MIB). + * srpt_sess_get_index - return the value of scsiAttIntrPortIndex (SCSI-MIB) + * @se_sess: SCSI target session. * * A quote from RFC 4455 (SCSI-MIB) about this MIB object: * This object represents an arbitrary integer used to uniquely identify a @@ -2882,7 +2963,7 @@ out: } /** - * srpt_parse_i_port_id() - Parse an initiator port ID. + * srpt_parse_i_port_id - parse an initiator port ID * @name: ASCII representation of a 128-bit initiator port ID. * @i_port_id: Binary 128-bit port ID. */ @@ -3133,8 +3214,10 @@ static struct configfs_attribute *srpt_tpg_attrs[] = { }; /** - * configfs callback invoked for - * mkdir /sys/kernel/config/target/$driver/$port/$tpg + * srpt_make_tpg - configfs callback invoked for mkdir /sys/kernel/config/target/$driver/$port/$tpg + * @wwn: Corresponds to $driver/$port. + * @group: Not used. + * @name: $tpg. */ static struct se_portal_group *srpt_make_tpg(struct se_wwn *wwn, struct config_group *group, @@ -3156,8 +3239,8 @@ static struct se_portal_group *srpt_make_tpg(struct se_wwn *wwn, } /** - * configfs callback invoked for - * rmdir /sys/kernel/config/target/$driver/$port/$tpg + * srpt_drop_tpg - configfs callback invoked for rmdir /sys/kernel/config/target/$driver/$port/$tpg + * @tpg: Target portal group to deregister. */ static void srpt_drop_tpg(struct se_portal_group *tpg) { @@ -3168,8 +3251,10 @@ static void srpt_drop_tpg(struct se_portal_group *tpg) } /** - * configfs callback invoked for - * mkdir /sys/kernel/config/target/$driver/$port + * srpt_make_tport - configfs callback invoked for mkdir /sys/kernel/config/target/$driver/$port + * @tf: Not used. + * @group: Not used. + * @name: $port. */ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf, struct config_group *group, @@ -3179,8 +3264,8 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf, } /** - * configfs callback invoked for - * rmdir /sys/kernel/config/target/$driver/$port + * srpt_drop_tport - configfs callback invoked for rmdir /sys/kernel/config/target/$driver/$port + * @wwn: $port. */ static void srpt_drop_tport(struct se_wwn *wwn) { @@ -3238,7 +3323,7 @@ static const struct target_core_fabric_ops srpt_template = { }; /** - * srpt_init_module() - Kernel module initialization. + * srpt_init_module - kernel module initialization * * Note: Since ib_register_client() registers callback functions, and since at * least one of these callback functions (srpt_add_one()) calls target core -- cgit v1.2.3 From f8781a53001b11ba8277da6566f352a61229b667 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:42 -0800 Subject: IB/srpt: Document all structure members in ib_srpt.h This patch avoids that the following command reports any warnings: scripts/kernel-doc -none drivers/infiniband/ulp/srpt/ib_srpt.h Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.h | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 7fff73a5d1e6..0c94cd6a7e9d 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h @@ -134,7 +134,7 @@ enum { }; /** - * enum srpt_command_state - SCSI command state managed by SRPT. + * enum srpt_command_state - SCSI command state managed by SRPT * @SRPT_STATE_NEW: New command arrived and is being processed. * @SRPT_STATE_NEED_DATA: Processing a write or bidir command and waiting * for data arrival. @@ -158,7 +158,8 @@ enum srpt_command_state { }; /** - * struct srpt_ioctx - Shared SRPT I/O context information. + * struct srpt_ioctx - shared SRPT I/O context information + * @cqe: Completion queue element. * @buf: Pointer to the buffer. * @dma: DMA address of the buffer. * @index: Index of the I/O context in its ioctx_ring array. @@ -171,7 +172,7 @@ struct srpt_ioctx { }; /** - * struct srpt_recv_ioctx - SRPT receive I/O context. + * struct srpt_recv_ioctx - SRPT receive I/O context * @ioctx: See above. * @wait_list: Node for insertion in srpt_rdma_ch.cmd_wait_list. */ @@ -187,13 +188,21 @@ struct srpt_rw_ctx { }; /** - * struct srpt_send_ioctx - SRPT send I/O context. + * struct srpt_send_ioctx - SRPT send I/O context * @ioctx: See above. * @ch: Channel pointer. + * @s_rw_ctx: @rw_ctxs points here if only a single rw_ctx is needed. + * @rw_ctxs: RDMA read/write contexts. + * @rdma_cqe: RDMA completion queue element. + * @free_list: Node in srpt_rdma_ch.free_list. * @spinlock: Protects 'state'. * @state: I/O context state. * @cmd: Target core command data structure. * @sense_data: SCSI sense data. + * @n_rdma: Number of work requests needed to transfer this ioctx. + * @n_rw_ctx: Size of rw_ctxs array. + * @queue_status_only: Send a SCSI status back to the initiator but no data. + * @sense_data: Sense data to be sent to the initiator. */ struct srpt_send_ioctx { struct srpt_ioctx ioctx; @@ -214,7 +223,7 @@ struct srpt_send_ioctx { }; /** - * enum rdma_ch_state - SRP channel state. + * enum rdma_ch_state - SRP channel state * @CH_CONNECTING: QP is in RTR state; waiting for RTU. * @CH_LIVE: QP is in RTS state. * @CH_DISCONNECTING: DREQ has been sent and waiting for DREP or DREQ has @@ -232,12 +241,14 @@ enum rdma_ch_state { }; /** - * struct srpt_rdma_ch - RDMA channel. + * struct srpt_rdma_ch - RDMA channel * @cm_id: IB CM ID associated with the channel. * @qp: IB queue pair used for communicating over this channel. * @cq: IB completion queue for this channel. + * @zw_cqe: Zero-length write CQE. + * @kref: kref for this channel. * @rq_size: IB receive queue size. - * @rsp_size IB response message size in bytes. + * @rsp_size: IB response message size 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 * channel. @@ -292,7 +303,7 @@ struct srpt_rdma_ch { }; /** - * struct srpt_port_attib - Attributes for SRPT port + * struct srpt_port_attib - attributes for SRPT port * @srp_max_rdma_size: Maximum size of SRP RDMA transfers for new connections. * @srp_max_rsp_size: Maximum size of SRP response messages in bytes. * @srp_sq_size: Shared receive queue (SRQ) size. @@ -306,7 +317,7 @@ struct srpt_port_attrib { }; /** - * struct srpt_port - Information associated by SRPT with a single IB port. + * struct srpt_port - information associated by SRPT with a single IB port * @sdev: backpointer to the HCA information. * @mad_agent: per-port management datagram processing information. * @enabled: Whether or not this target port is enabled. @@ -322,7 +333,7 @@ struct srpt_port_attrib { * @port_guid_wwn: WWN associated with target port GUID. * @port_gid_tpg: TPG associated with target port GID. * @port_gid_wwn: WWN associated with target port GID. - * @port_acl_list: Head of the list with all node ACLs for this port. + * @port_attrib: Port attributes that can be accessed through configfs. */ struct srpt_port { struct srpt_device *sdev; @@ -343,7 +354,7 @@ struct srpt_port { }; /** - * struct srpt_device - Information associated by SRPT with a single HCA. + * struct srpt_device - information associated by SRPT with a single HCA * @device: Backpointer to the struct ib_device managed by the IB core. * @pd: IB protection domain. * @lkey: L_Key (local key) with write access to all local memory. -- cgit v1.2.3 From ed262287e2b46927905a41e86100a63dc2327dac Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:43 -0800 Subject: IB/srpt: Rename a local variable, a member variable and a constant Rename rsp_size into max_rsp_size and SRPT_RQ_SIZE into MAX_SRPT_RQ_SIZE. The new names better reflect the role of this member variable and constant. Since the prefix "srp_" is superfluous in the context of the function that creates an RDMA channel, rename srp_sq_size into sq_size. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 26 +++++++++++++------------- drivers/infiniband/ulp/srpt/ib_srpt.h | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 1bcf8b3b6095..4fb884c070af 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -325,7 +325,7 @@ static void srpt_get_ioc(struct srpt_port *sport, u32 slot, if (sdev->use_srq) send_queue_depth = sdev->srq_size; else - send_queue_depth = min(SRPT_RQ_SIZE, + send_queue_depth = min(MAX_SRPT_RQ_SIZE, sdev->device->attrs.max_qp_wr); memset(iocp, 0, sizeof(*iocp)); @@ -1693,7 +1693,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) struct srpt_port *sport = ch->sport; struct srpt_device *sdev = sport->sdev; const struct ib_device_attr *attrs = &sdev->device->attrs; - u32 srp_sq_size = sport->port_attrib.srp_sq_size; + int sq_size = sport->port_attrib.srp_sq_size; int i, ret; WARN_ON(ch->rq_size < 1); @@ -1704,12 +1704,12 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) goto out; retry: - ch->cq = ib_alloc_cq(sdev->device, ch, ch->rq_size + srp_sq_size, + ch->cq = ib_alloc_cq(sdev->device, ch, ch->rq_size + sq_size, 0 /* XXX: spread CQs */, IB_POLL_WORKQUEUE); if (IS_ERR(ch->cq)) { ret = PTR_ERR(ch->cq); pr_err("failed to create CQ cqe= %d ret= %d\n", - ch->rq_size + srp_sq_size, ret); + ch->rq_size + sq_size, ret); goto out; } @@ -1727,8 +1727,8 @@ retry: * both both, as RDMA contexts will also post completions for the * RDMA READ case. */ - qp_init->cap.max_send_wr = min(srp_sq_size / 2, attrs->max_qp_wr + 0U); - qp_init->cap.max_rdma_ctxs = srp_sq_size / 2; + qp_init->cap.max_send_wr = min(sq_size / 2, attrs->max_qp_wr); + qp_init->cap.max_rdma_ctxs = sq_size / 2; qp_init->cap.max_send_sge = min(attrs->max_sge, SRPT_MAX_SG_PER_WQE); qp_init->port_num = ch->sport->port; if (sdev->use_srq) { @@ -1742,8 +1742,8 @@ retry: if (IS_ERR(ch->qp)) { ret = PTR_ERR(ch->qp); if (ret == -ENOMEM) { - srp_sq_size /= 2; - if (srp_sq_size >= MIN_SRPT_SQ_SIZE) { + sq_size /= 2; + if (sq_size >= MIN_SRPT_SQ_SIZE) { ib_destroy_cq(ch->cq); goto retry; } @@ -1950,7 +1950,7 @@ static void srpt_release_channel_work(struct work_struct *w) srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, ch->sport->sdev, ch->rq_size, - ch->rsp_size, DMA_TO_DEVICE); + ch->max_rsp_size, DMA_TO_DEVICE); srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring, sdev, ch->rq_size, @@ -2098,16 +2098,16 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, * depth to avoid that the initiator driver has to report QUEUE_FULL * to the SCSI mid-layer. */ - ch->rq_size = min(SRPT_RQ_SIZE, sdev->device->attrs.max_qp_wr); + ch->rq_size = min(MAX_SRPT_RQ_SIZE, sdev->device->attrs.max_qp_wr); spin_lock_init(&ch->spinlock); ch->state = CH_CONNECTING; INIT_LIST_HEAD(&ch->cmd_wait_list); - ch->rsp_size = ch->sport->port_attrib.srp_max_rsp_size; + ch->max_rsp_size = ch->sport->port_attrib.srp_max_rsp_size; ch->ioctx_ring = (struct srpt_send_ioctx **) srpt_alloc_ioctx_ring(ch->sport->sdev, ch->rq_size, sizeof(*ch->ioctx_ring[0]), - ch->rsp_size, DMA_TO_DEVICE); + ch->max_rsp_size, DMA_TO_DEVICE); if (!ch->ioctx_ring) goto free_ch; @@ -2235,7 +2235,7 @@ free_recv_ring: free_ring: srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, ch->sport->sdev, ch->rq_size, - ch->rsp_size, DMA_TO_DEVICE); + ch->max_rsp_size, DMA_TO_DEVICE); free_ch: kfree(ch); diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 0c94cd6a7e9d..8f90a7ca98e6 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h @@ -114,7 +114,7 @@ enum { MIN_SRPT_SQ_SIZE = 16, DEF_SRPT_SQ_SIZE = 4096, - SRPT_RQ_SIZE = 128, + MAX_SRPT_RQ_SIZE = 128, MIN_SRPT_SRQ_SIZE = 4, DEFAULT_SRPT_SRQ_SIZE = 4095, MAX_SRPT_SRQ_SIZE = 65535, @@ -248,7 +248,7 @@ enum rdma_ch_state { * @zw_cqe: Zero-length write CQE. * @kref: kref for this channel. * @rq_size: IB receive queue size. - * @rsp_size: IB response message size in bytes. + * @max_rsp_size: Maximum size of an RSP 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 * channel. @@ -280,7 +280,7 @@ struct srpt_rdma_ch { struct ib_cqe zw_cqe; struct kref kref; int rq_size; - u32 rsp_size; + u32 max_rsp_size; atomic_t sq_wr_avail; struct srpt_port *sport; u8 i_port_id[16]; -- cgit v1.2.3 From d9f45ae69ff14e672c9b1d8cb42383d4cc2a6878 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:44 -0800 Subject: IB/srpt: Reduce the severity level of a log message Since the SRQ event message is only useful for debugging purposes, reduce its severity from "informational" to "debug". Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 4fb884c070af..a71664fe939b 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -177,7 +177,7 @@ static void srpt_event_handler(struct ib_event_handler *handler, */ static void srpt_srq_event(struct ib_event *event, void *ctx) { - pr_info("SRQ event %d\n", event->event); + pr_debug("SRQ event %d\n", event->event); } static const char *get_ch_state_name(enum rdma_ch_state s) -- cgit v1.2.3 From 5f1141b165cc0c7dc1be9143461127dd856615da Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:45 -0800 Subject: IB/srpt: Verify port numbers in srpt_event_handler() Verify whether port numbers are in the expected range before using these as an array index. Complain if a port number is out of range. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index a71664fe939b..c5efe0afa2c8 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -134,6 +134,7 @@ static void srpt_event_handler(struct ib_event_handler *handler, { struct srpt_device *sdev; struct srpt_port *sport; + u8 port_num; sdev = ib_get_client_data(event->device, &srpt_client); if (!sdev || sdev->device != event->device) @@ -144,10 +145,15 @@ static void srpt_event_handler(struct ib_event_handler *handler, switch (event->event) { case IB_EVENT_PORT_ERR: - if (event->element.port_num <= sdev->device->phys_port_cnt) { - sport = &sdev->port[event->element.port_num - 1]; + port_num = event->element.port_num - 1; + if (port_num < sdev->device->phys_port_cnt) { + sport = &sdev->port[port_num]; sport->lid = 0; sport->sm_lid = 0; + } else { + WARN(true, "event %d: port_num %d out of range 1..%d\n", + event->event, port_num + 1, + sdev->device->phys_port_cnt); } break; case IB_EVENT_PORT_ACTIVE: @@ -157,15 +163,19 @@ static void srpt_event_handler(struct ib_event_handler *handler, case IB_EVENT_CLIENT_REREGISTER: case IB_EVENT_GID_CHANGE: /* Refresh port data asynchronously. */ - if (event->element.port_num <= sdev->device->phys_port_cnt) { - sport = &sdev->port[event->element.port_num - 1]; + port_num = event->element.port_num - 1; + if (port_num < sdev->device->phys_port_cnt) { + sport = &sdev->port[port_num]; if (!sport->lid && !sport->sm_lid) schedule_work(&sport->work); + } else { + WARN(true, "event %d: port_num %d out of range 1..%d\n", + event->event, port_num + 1, + sdev->device->phys_port_cnt); } break; default: - pr_err("received unrecognized IB event %d\n", - event->event); + pr_err("received unrecognized IB event %d\n", event->event); break; } } -- cgit v1.2.3 From b185d3f895632f1091513405ce80a9455cb5bf30 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:46 -0800 Subject: IB/srpt: Use the IPv6 format for GIDs in log messages Make the ib_srpt driver use the IPv6 format for GIDs in log messages to improve consistency of this driver with other RDMA kernel drivers. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index c5efe0afa2c8..25c5e188c740 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -2010,17 +2010,9 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, it_iu_len = be32_to_cpu(req->req_it_iu_len); - pr_info("Received SRP_LOGIN_REQ with i_port_id 0x%llx:0x%llx," - " t_port_id 0x%llx:0x%llx and it_iu_len %d on port %d" - " (guid=0x%llx:0x%llx)\n", - be64_to_cpu(*(__be64 *)&req->initiator_port_id[0]), - be64_to_cpu(*(__be64 *)&req->initiator_port_id[8]), - be64_to_cpu(*(__be64 *)&req->target_port_id[0]), - be64_to_cpu(*(__be64 *)&req->target_port_id[8]), - it_iu_len, - param->port, - be64_to_cpu(*(__be64 *)&sdev->port[param->port - 1].gid.raw[0]), - be64_to_cpu(*(__be64 *)&sdev->port[param->port - 1].gid.raw[8])); + pr_info("Received SRP_LOGIN_REQ with i_port_id %pI6, t_port_id %pI6 and it_iu_len %d on port %d (guid=%pI6)\n", + req->initiator_port_id, req->target_port_id, it_iu_len, + param->port, &sport->gid); rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); rej = kzalloc(sizeof(*rej), GFP_KERNEL); -- cgit v1.2.3 From ea51d2e12aac9205291b0ec88ffb7d33da7eafb5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:47 -0800 Subject: IB/srpt: Convert a warning into a debug message At least when running the ib_srpt driver on top of the rdma_rxe driver it is easy to trigger a zero-length write completion in the CH_DISCONNECTED state. Hence make the message that reports this less noisy. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 25c5e188c740..31b6f108dffb 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -875,7 +875,8 @@ static void srpt_zerolength_write_done(struct ib_cq *cq, struct ib_wc *wc) if (srpt_set_ch_state(ch, CH_DISCONNECTED)) schedule_work(&ch->release_work); else - WARN_ONCE(1, "%s-%d\n", ch->sess_name, ch->qp->qp_num); + pr_debug("%s-%d: already disconnected.\n", + ch->sess_name, ch->qp->qp_num); } } -- cgit v1.2.3 From 3fa7f0e99446f1179cbb2742e5bc4db097ad78b5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:48 -0800 Subject: IB/srpt: Reduce frequency of receive failure messages Disabling an SRP target port causes the state of all QPs associated with a port to be changed into IB_QPS_ERR. Avoid that this causes one error message per I/O context to be reported. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 31b6f108dffb..6f5a4d66eacc 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -1622,8 +1622,8 @@ static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc) pr_err("req_lim = %d < 0\n", req_lim); srpt_handle_new_iu(ch, ioctx, NULL); } else { - pr_info("receiving failed for ioctx %p with status %d\n", - ioctx, wc->status); + pr_info_ratelimited("receiving failed for ioctx %p with status %d\n", + ioctx, wc->status); } } -- cgit v1.2.3 From b14cb74479a2606b0052cc909727938953a939ac Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:49 -0800 Subject: IB/srpt: Introduce srpt_format_guid() Introduce a function for converting a GUID into an ASCII string. This patch does not change any functionality. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 6f5a4d66eacc..e4c1446699a9 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -524,6 +524,15 @@ err: ib_free_recv_mad(mad_wc); } +static int srpt_format_guid(char *buf, unsigned int size, const __be64 *guid) +{ + const __be16 *g = (const __be16 *)guid; + + return snprintf(buf, size, "%04x:%04x:%04x:%04x", + be16_to_cpu(g[0]), be16_to_cpu(g[1]), + be16_to_cpu(g[2]), be16_to_cpu(g[3])); +} + /** * srpt_refresh_port - configure a HCA port * @sport: SRPT HCA port. @@ -539,7 +548,6 @@ static int srpt_refresh_port(struct srpt_port *sport) struct ib_mad_reg_req reg_req; struct ib_port_modify port_modify; struct ib_port_attr port_attr; - __be16 *guid; int ret; memset(&port_modify, 0, sizeof(port_modify)); @@ -563,11 +571,8 @@ static int srpt_refresh_port(struct srpt_port *sport) goto err_query_port; sport->port_guid_wwn.priv = sport; - guid = (__be16 *)&sport->gid.global.interface_id; - snprintf(sport->port_guid, sizeof(sport->port_guid), - "%04x:%04x:%04x:%04x", - be16_to_cpu(guid[0]), be16_to_cpu(guid[1]), - be16_to_cpu(guid[2]), be16_to_cpu(guid[3])); + srpt_format_guid(sport->port_guid, sizeof(sport->port_guid), + &sport->gid.global.interface_id); sport->port_gid_wwn.priv = sport; snprintf(sport->port_gid, sizeof(sport->port_gid), "0x%016llx%016llx", @@ -1998,7 +2003,6 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, struct srp_login_rej *rej; struct ib_cm_rep_param *rep_param; struct srpt_rdma_ch *ch, *tmp_ch; - __be16 *guid; u32 it_iu_len; int i, ret = 0; @@ -2150,10 +2154,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id, goto destroy_ib; } - guid = (__be16 *)¶m->primary_path->dgid.global.interface_id; - snprintf(ch->ini_guid, sizeof(ch->ini_guid), "%04x:%04x:%04x:%04x", - be16_to_cpu(guid[0]), be16_to_cpu(guid[1]), - be16_to_cpu(guid[2]), be16_to_cpu(guid[3])); + srpt_format_guid(ch->ini_guid, sizeof(ch->ini_guid), + ¶m->primary_path->dgid.global.interface_id); snprintf(ch->sess_name, sizeof(ch->sess_name), "0x%016llx%016llx", be64_to_cpu(*(__be64 *)ch->i_port_id), be64_to_cpu(*(__be64 *)(ch->i_port_id + 8))); -- cgit v1.2.3 From dd3bec8655d6f760540afd2261ca7ae9b6888cb0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:50 -0800 Subject: IB/srpt: Inline srpt_get_cmd_state() It is not necessary to obtain ioctx->spinlock when reading the ioctx state. Since after removal of this locking only a single line remains, inline the srpt_get_cmd_state() function. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index e4c1446699a9..d2835b0c15e8 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -752,23 +752,6 @@ static void srpt_free_ioctx_ring(struct srpt_ioctx **ioctx_ring, kfree(ioctx_ring); } -/** - * srpt_get_cmd_state - get the state of a SCSI command - * @ioctx: Send I/O context. - */ -static enum srpt_command_state srpt_get_cmd_state(struct srpt_send_ioctx *ioctx) -{ - enum srpt_command_state state; - unsigned long flags; - - BUG_ON(!ioctx); - - spin_lock_irqsave(&ioctx->spinlock, flags); - state = ioctx->state; - spin_unlock_irqrestore(&ioctx->spinlock, flags); - return state; -} - /** * srpt_set_cmd_state - set the state of a SCSI command * @ioctx: Send I/O context. @@ -1303,7 +1286,7 @@ static void srpt_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc) target_execute_cmd(&ioctx->cmd); else pr_err("%s[%d]: wrong state = %d\n", __func__, - __LINE__, srpt_get_cmd_state(ioctx)); + __LINE__, ioctx->state); } /** @@ -2372,7 +2355,7 @@ static int srpt_write_pending_status(struct se_cmd *se_cmd) struct srpt_send_ioctx *ioctx; ioctx = container_of(se_cmd, struct srpt_send_ioctx, cmd); - return srpt_get_cmd_state(ioctx) == SRPT_STATE_NEED_DATA; + return ioctx->state == SRPT_STATE_NEED_DATA; } /* @@ -2951,7 +2934,7 @@ static int srpt_get_tcm_cmd_state(struct se_cmd *se_cmd) struct srpt_send_ioctx *ioctx; ioctx = container_of(se_cmd, struct srpt_send_ioctx, cmd); - return srpt_get_cmd_state(ioctx); + return ioctx->state; } static int srpt_parse_guid(u64 *guid, const char *name) -- cgit v1.2.3 From 2d67017cc78f1607bac5347ce0c5258734796faf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 8 Jan 2018 11:00:51 -0800 Subject: IB/srpt: Micro-optimize I/O context state manipulation Since all I/O context state changes are already serialized, it is not necessary to protect I/O context state changes with the I/O context spinlock. Hence remove that spinlock. Signed-off-by: Bart Van Assche Signed-off-by: Doug Ledford --- drivers/infiniband/ulp/srpt/ib_srpt.c | 16 +--------------- drivers/infiniband/ulp/srpt/ib_srpt.h | 2 -- 2 files changed, 1 insertion(+), 17 deletions(-) (limited to 'drivers/infiniband/ulp') diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index d2835b0c15e8..d78f60dcc2ba 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -764,15 +764,10 @@ static enum srpt_command_state srpt_set_cmd_state(struct srpt_send_ioctx *ioctx, enum srpt_command_state new) { enum srpt_command_state previous; - unsigned long flags; - - BUG_ON(!ioctx); - spin_lock_irqsave(&ioctx->spinlock, flags); previous = ioctx->state; if (previous != SRPT_STATE_DONE) ioctx->state = new; - spin_unlock_irqrestore(&ioctx->spinlock, flags); return previous; } @@ -790,17 +785,15 @@ static bool srpt_test_and_set_cmd_state(struct srpt_send_ioctx *ioctx, enum srpt_command_state new) { enum srpt_command_state previous; - unsigned long flags; WARN_ON(!ioctx); WARN_ON(old == SRPT_STATE_DONE); WARN_ON(new == SRPT_STATE_NEW); - spin_lock_irqsave(&ioctx->spinlock, flags); previous = ioctx->state; if (previous == old) ioctx->state = new; - spin_unlock_irqrestore(&ioctx->spinlock, flags); + return previous == old; } @@ -1170,7 +1163,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch) return ioctx; BUG_ON(ioctx->ch != ch); - spin_lock_init(&ioctx->spinlock); ioctx->state = SRPT_STATE_NEW; ioctx->n_rdma = 0; ioctx->n_rw_ctx = 0; @@ -1192,7 +1184,6 @@ static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch) static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) { enum srpt_command_state state; - unsigned long flags; BUG_ON(!ioctx); @@ -1201,7 +1192,6 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) * the ib_srpt driver, change the state to the next state. */ - spin_lock_irqsave(&ioctx->spinlock, flags); state = ioctx->state; switch (state) { case SRPT_STATE_NEED_DATA: @@ -1216,7 +1206,6 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx) __func__, state); break; } - spin_unlock_irqrestore(&ioctx->spinlock, flags); pr_debug("Aborting cmd with state %d -> %d and tag %lld\n", state, ioctx->state, ioctx->cmd.tag); @@ -2431,13 +2420,11 @@ static void srpt_queue_response(struct se_cmd *cmd) struct ib_send_wr send_wr, *first_wr = &send_wr, *bad_wr; struct ib_sge sge; enum srpt_command_state state; - unsigned long flags; int resp_len, ret, i; u8 srp_tm_status; BUG_ON(!ch); - spin_lock_irqsave(&ioctx->spinlock, flags); state = ioctx->state; switch (state) { case SRPT_STATE_NEW: @@ -2452,7 +2439,6 @@ static void srpt_queue_response(struct se_cmd *cmd) ch, ioctx->ioctx.index, ioctx->state); break; } - spin_unlock_irqrestore(&ioctx->spinlock, flags); if (unlikely(WARN_ON_ONCE(state == SRPT_STATE_CMD_RSP_SENT))) return; diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h index 8f90a7ca98e6..11ce8c94a051 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.h +++ b/drivers/infiniband/ulp/srpt/ib_srpt.h @@ -195,7 +195,6 @@ struct srpt_rw_ctx { * @rw_ctxs: RDMA read/write contexts. * @rdma_cqe: RDMA completion queue element. * @free_list: Node in srpt_rdma_ch.free_list. - * @spinlock: Protects 'state'. * @state: I/O context state. * @cmd: Target core command data structure. * @sense_data: SCSI sense data. @@ -213,7 +212,6 @@ struct srpt_send_ioctx { struct ib_cqe rdma_cqe; struct list_head free_list; - spinlock_t spinlock; enum srpt_command_state state; struct se_cmd cmd; u8 n_rdma; -- cgit v1.2.3