Skip to content

Commit ba60c84

Browse files
KAGA-KOKOdledford
authored andcommitted
IB/srpt: One target per port
In multipathing setups where a target system is equipped with dual-port HCAs it is useful to have one connection per target port instead of one connection per target HCA. Hence move the connection list (rch_list) from struct srpt_device into struct srpt_port. Signed-off-by: Bart Van Assche <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent c5efb62 commit ba60c84

File tree

2 files changed

+61
-53
lines changed

2 files changed

+61
-53
lines changed

drivers/infiniband/ulp/srpt/ib_srpt.c

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,13 +1847,13 @@ static int srpt_disconnect_ch(struct srpt_rdma_ch *ch)
18471847
return ret;
18481848
}
18491849

1850-
static bool srpt_ch_closed(struct srpt_device *sdev, struct srpt_rdma_ch *ch)
1850+
static bool srpt_ch_closed(struct srpt_port *sport, struct srpt_rdma_ch *ch)
18511851
{
18521852
struct srpt_rdma_ch *ch2;
18531853
bool res = true;
18541854

18551855
rcu_read_lock();
1856-
list_for_each_entry(ch2, &sdev->rch_list, list) {
1856+
list_for_each_entry(ch2, &sport->rch_list, list) {
18571857
if (ch2 == ch) {
18581858
res = false;
18591859
break;
@@ -1871,33 +1871,32 @@ static bool srpt_ch_closed(struct srpt_device *sdev, struct srpt_rdma_ch *ch)
18711871
static bool srpt_disconnect_ch_sync(struct srpt_rdma_ch *ch)
18721872
__must_hold(&sdev->mutex)
18731873
{
1874-
struct srpt_device *sdev = ch->sport->sdev;
1874+
struct srpt_port *sport = ch->sport;
18751875
int ret;
18761876

1877-
lockdep_assert_held(&sdev->mutex);
1877+
lockdep_assert_held(&sport->mutex);
18781878

18791879
pr_debug("ch %s-%d state %d\n", ch->sess_name, ch->qp->qp_num,
18801880
ch->state);
18811881

18821882
ret = srpt_disconnect_ch(ch);
1883-
mutex_unlock(&sdev->mutex);
1883+
mutex_unlock(&sport->mutex);
18841884

1885-
while (wait_event_timeout(sdev->ch_releaseQ, srpt_ch_closed(sdev, ch),
1885+
while (wait_event_timeout(sport->ch_releaseQ, srpt_ch_closed(sport, ch),
18861886
5 * HZ) == 0)
18871887
pr_info("%s(%s-%d state %d): still waiting ...\n", __func__,
18881888
ch->sess_name, ch->qp->qp_num, ch->state);
18891889

1890-
mutex_lock(&sdev->mutex);
1890+
mutex_lock(&sport->mutex);
18911891
return ret == 0;
18921892
}
18931893

18941894
static void srpt_set_enabled(struct srpt_port *sport, bool enabled)
1895-
__must_hold(&sdev->mutex)
1895+
__must_hold(&sport->mutex)
18961896
{
1897-
struct srpt_device *sdev = sport->sdev;
18981897
struct srpt_rdma_ch *ch;
18991898

1900-
lockdep_assert_held(&sdev->mutex);
1899+
lockdep_assert_held(&sport->mutex);
19011900

19021901
if (sport->enabled == enabled)
19031902
return;
@@ -1906,10 +1905,10 @@ static void srpt_set_enabled(struct srpt_port *sport, bool enabled)
19061905
return;
19071906

19081907
again:
1909-
list_for_each_entry(ch, &sdev->rch_list, list) {
1908+
list_for_each_entry(ch, &sport->rch_list, list) {
19101909
if (ch->sport == sport) {
19111910
pr_info("%s: closing channel %s-%d\n",
1912-
sdev->device->name, ch->sess_name,
1911+
sport->sdev->device->name, ch->sess_name,
19131912
ch->qp->qp_num);
19141913
if (srpt_disconnect_ch_sync(ch))
19151914
goto again;
@@ -1929,6 +1928,7 @@ static void srpt_release_channel_work(struct work_struct *w)
19291928
{
19301929
struct srpt_rdma_ch *ch;
19311930
struct srpt_device *sdev;
1931+
struct srpt_port *sport;
19321932
struct se_session *se_sess;
19331933

19341934
ch = container_of(w, struct srpt_rdma_ch, release_work);
@@ -1959,11 +1959,12 @@ static void srpt_release_channel_work(struct work_struct *w)
19591959
sdev, ch->rq_size,
19601960
srp_max_req_size, DMA_FROM_DEVICE);
19611961

1962-
mutex_lock(&sdev->mutex);
1962+
sport = ch->sport;
1963+
mutex_lock(&sport->mutex);
19631964
list_del_rcu(&ch->list);
1964-
mutex_unlock(&sdev->mutex);
1965+
mutex_unlock(&sport->mutex);
19651966

1966-
wake_up(&sdev->ch_releaseQ);
1967+
wake_up(&sport->ch_releaseQ);
19671968

19681969
kref_put(&ch->kref, srpt_free_ch);
19691970
}
@@ -2036,9 +2037,9 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
20362037
if ((req->req_flags & SRP_MTCH_ACTION) == SRP_MULTICHAN_SINGLE) {
20372038
rsp->rsp_flags = SRP_LOGIN_RSP_MULTICHAN_NO_CHAN;
20382039

2039-
mutex_lock(&sdev->mutex);
2040+
mutex_lock(&sport->mutex);
20402041

2041-
list_for_each_entry_safe(ch, tmp_ch, &sdev->rch_list, list) {
2042+
list_for_each_entry_safe(ch, tmp_ch, &sport->rch_list, list) {
20422043
if (!memcmp(ch->i_port_id, req->initiator_port_id, 16)
20432044
&& !memcmp(ch->t_port_id, req->target_port_id, 16)
20442045
&& param->port == ch->sport->port
@@ -2053,7 +2054,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
20532054
}
20542055
}
20552056

2056-
mutex_unlock(&sdev->mutex);
2057+
mutex_unlock(&sport->mutex);
20572058

20582059
} else
20592060
rsp->rsp_flags = SRP_LOGIN_RSP_MULTICHAN_MAINTAINED;
@@ -2205,9 +2206,9 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
22052206
goto release_channel;
22062207
}
22072208

2208-
mutex_lock(&sdev->mutex);
2209-
list_add_tail_rcu(&ch->list, &sdev->rch_list);
2210-
mutex_unlock(&sdev->mutex);
2209+
mutex_lock(&sport->mutex);
2210+
list_add_tail_rcu(&ch->list, &sport->rch_list);
2211+
mutex_unlock(&sport->mutex);
22112212

22122213
goto out;
22132214

@@ -2559,24 +2560,21 @@ static void srpt_refresh_port_work(struct work_struct *work)
25592560
}
25602561

25612562
/**
2562-
* srpt_release_sdev - disable login and wait for associated channels
2563-
* @sdev: SRPT HCA pointer.
2563+
* srpt_release_sport - disable login and wait for associated channels
2564+
* @sport: SRPT HCA port.
25642565
*/
2565-
static int srpt_release_sdev(struct srpt_device *sdev)
2566+
static int srpt_release_sport(struct srpt_port *sport)
25662567
{
2567-
int i, res;
2568+
int res;
25682569

25692570
WARN_ON_ONCE(irqs_disabled());
25702571

2571-
BUG_ON(!sdev);
2572-
2573-
mutex_lock(&sdev->mutex);
2574-
for (i = 0; i < ARRAY_SIZE(sdev->port); i++)
2575-
srpt_set_enabled(&sdev->port[i], false);
2576-
mutex_unlock(&sdev->mutex);
2572+
mutex_lock(&sport->mutex);
2573+
srpt_set_enabled(sport, false);
2574+
mutex_unlock(&sport->mutex);
25772575

2578-
res = wait_event_interruptible(sdev->ch_releaseQ,
2579-
list_empty_careful(&sdev->rch_list));
2576+
res = wait_event_interruptible(sport->ch_releaseQ,
2577+
list_empty_careful(&sport->rch_list));
25802578
if (res)
25812579
pr_err("%s: interrupted.\n", __func__);
25822580

@@ -2704,9 +2702,7 @@ static void srpt_add_one(struct ib_device *device)
27042702
goto err;
27052703

27062704
sdev->device = device;
2707-
INIT_LIST_HEAD(&sdev->rch_list);
2708-
init_waitqueue_head(&sdev->ch_releaseQ);
2709-
mutex_init(&sdev->mutex);
2705+
mutex_init(&sdev->sdev_mutex);
27102706

27112707
sdev->pd = ib_alloc_pd(device, 0);
27122708
if (IS_ERR(sdev->pd))
@@ -2747,6 +2743,9 @@ static void srpt_add_one(struct ib_device *device)
27472743

27482744
for (i = 1; i <= sdev->device->phys_port_cnt; i++) {
27492745
sport = &sdev->port[i - 1];
2746+
INIT_LIST_HEAD(&sport->rch_list);
2747+
init_waitqueue_head(&sport->ch_releaseQ);
2748+
mutex_init(&sport->mutex);
27502749
sport->sdev = sdev;
27512750
sport->port = i;
27522751
sport->port_attrib.srp_max_rdma_size = DEFAULT_MAX_RDMA_SIZE;
@@ -2819,7 +2818,9 @@ static void srpt_remove_one(struct ib_device *device, void *client_data)
28192818
spin_lock(&srpt_dev_lock);
28202819
list_del(&sdev->list);
28212820
spin_unlock(&srpt_dev_lock);
2822-
srpt_release_sdev(sdev);
2821+
2822+
for (i = 0; i < sdev->device->phys_port_cnt; i++)
2823+
srpt_release_sport(&sdev->port[i]);
28232824

28242825
srpt_free_srq(sdev);
28252826

@@ -2905,11 +2906,11 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
29052906
static void srpt_close_session(struct se_session *se_sess)
29062907
{
29072908
struct srpt_rdma_ch *ch = se_sess->fabric_sess_ptr;
2908-
struct srpt_device *sdev = ch->sport->sdev;
2909+
struct srpt_port *sport = ch->sport;
29092910

2910-
mutex_lock(&sdev->mutex);
2911+
mutex_lock(&sport->mutex);
29112912
srpt_disconnect_ch_sync(ch);
2912-
mutex_unlock(&sdev->mutex);
2913+
mutex_unlock(&sport->mutex);
29132914
}
29142915

29152916
/**
@@ -3134,18 +3135,24 @@ static ssize_t srpt_tpg_attrib_use_srq_store(struct config_item *item,
31343135
if (val != !!val)
31353136
return -EINVAL;
31363137

3137-
ret = mutex_lock_interruptible(&sdev->mutex);
3138+
ret = mutex_lock_interruptible(&sdev->sdev_mutex);
31383139
if (ret < 0)
31393140
return ret;
3141+
ret = mutex_lock_interruptible(&sport->mutex);
3142+
if (ret < 0)
3143+
goto unlock_sdev;
31403144
enabled = sport->enabled;
31413145
/* Log out all initiator systems before changing 'use_srq'. */
31423146
srpt_set_enabled(sport, false);
31433147
sport->port_attrib.use_srq = val;
31443148
srpt_use_srq(sdev, sport->port_attrib.use_srq);
31453149
srpt_set_enabled(sport, enabled);
3146-
mutex_unlock(&sdev->mutex);
3150+
ret = count;
3151+
mutex_unlock(&sport->mutex);
3152+
unlock_sdev:
3153+
mutex_unlock(&sdev->sdev_mutex);
31473154

3148-
return count;
3155+
return ret;
31493156
}
31503157

31513158
CONFIGFS_ATTR(srpt_tpg_attrib_, srp_max_rdma_size);
@@ -3174,7 +3181,6 @@ static ssize_t srpt_tpg_enable_store(struct config_item *item,
31743181
{
31753182
struct se_portal_group *se_tpg = to_tpg(item);
31763183
struct srpt_port *sport = srpt_tpg_to_sport(se_tpg);
3177-
struct srpt_device *sdev = sport->sdev;
31783184
unsigned long tmp;
31793185
int ret;
31803186

@@ -3189,9 +3195,9 @@ static ssize_t srpt_tpg_enable_store(struct config_item *item,
31893195
return -EINVAL;
31903196
}
31913197

3192-
mutex_lock(&sdev->mutex);
3198+
mutex_lock(&sport->mutex);
31933199
srpt_set_enabled(sport, tmp);
3194-
mutex_unlock(&sdev->mutex);
3200+
mutex_unlock(&sport->mutex);
31953201

31963202
return count;
31973203
}

drivers/infiniband/ulp/srpt/ib_srpt.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ enum rdma_ch_state {
262262
* @state: channel state. See also enum rdma_ch_state.
263263
* @ioctx_ring: Send ring.
264264
* @ioctx_recv_ring: Receive I/O context ring.
265-
* @list: Node for insertion in the srpt_device.rch_list list.
265+
* @list: Node in srpt_port.rch_list.
266266
* @cmd_wait_list: List of SCSI commands that arrived before the RTU event. This
267267
* list contains struct srpt_ioctx elements and is protected
268268
* against concurrent modification by the cm_id spinlock.
@@ -334,6 +334,9 @@ struct srpt_port_attrib {
334334
* @port_gid_tpg: TPG associated with target port GID.
335335
* @port_gid_wwn: WWN associated with target port GID.
336336
* @port_attrib: Port attributes that can be accessed through configfs.
337+
* @ch_releaseQ: Enables waiting for removal from rch_list.
338+
* @mutex: Protects rch_list.
339+
* @rch_list: Channel list. See also srpt_rdma_ch.list.
337340
*/
338341
struct srpt_port {
339342
struct srpt_device *sdev;
@@ -351,6 +354,9 @@ struct srpt_port {
351354
struct se_portal_group port_gid_tpg;
352355
struct se_wwn port_gid_wwn;
353356
struct srpt_port_attrib port_attrib;
357+
wait_queue_head_t ch_releaseQ;
358+
struct mutex mutex;
359+
struct list_head rch_list;
354360
};
355361

356362
/**
@@ -361,11 +367,9 @@ struct srpt_port {
361367
* @srq: Per-HCA SRQ (shared receive queue).
362368
* @cm_id: Connection identifier.
363369
* @srq_size: SRQ size.
370+
* @sdev_mutex: Serializes use_srq changes.
364371
* @use_srq: Whether or not to use SRQ.
365372
* @ioctx_ring: Per-HCA SRQ.
366-
* @rch_list: Per-device channel list -- see also srpt_rdma_ch.list.
367-
* @ch_releaseQ: Enables waiting for removal from rch_list.
368-
* @mutex: Protects rch_list.
369373
* @port: Information about the ports owned by this HCA.
370374
* @event_handler: Per-HCA asynchronous IB event handler.
371375
* @list: Node in srpt_dev_list.
@@ -377,11 +381,9 @@ struct srpt_device {
377381
struct ib_srq *srq;
378382
struct ib_cm_id *cm_id;
379383
int srq_size;
384+
struct mutex sdev_mutex;
380385
bool use_srq;
381386
struct srpt_recv_ioctx **ioctx_ring;
382-
struct list_head rch_list;
383-
wait_queue_head_t ch_releaseQ;
384-
struct mutex mutex;
385387
struct srpt_port port[2];
386388
struct ib_event_handler event_handler;
387389
struct list_head list;

0 commit comments

Comments
 (0)