Skip to content

Commit 9e8f1c7

Browse files
Varun Prakashmartinkpetersen
authored andcommitted
scsi: cxgb4i: add wait_for_completion()
In case of ->set_param() and ->bind_conn() cxgb4i driver does not wait for cmd completion, this can create race conditions, to avoid this add wait_for_completion(). Signed-off-by: Varun Prakash <varun@chelsio.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 4a01ab6 commit 9e8f1c7

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
lines changed

drivers/scsi/cxgbi/cxgb3i/cxgb3i.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,7 +1144,7 @@ static void ddp_clear_map(struct cxgbi_device *cdev, struct cxgbi_ppm *ppm,
11441144
}
11451145

11461146
static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
1147-
unsigned int tid, int pg_idx, bool reply)
1147+
unsigned int tid, int pg_idx)
11481148
{
11491149
struct sk_buff *skb = alloc_wr(sizeof(struct cpl_set_tcb_field), 0,
11501150
GFP_KERNEL);
@@ -1160,7 +1160,7 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
11601160
req = (struct cpl_set_tcb_field *)skb->head;
11611161
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
11621162
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
1163-
req->reply = V_NO_REPLY(reply ? 0 : 1);
1163+
req->reply = V_NO_REPLY(1);
11641164
req->cpu_idx = 0;
11651165
req->word = htons(31);
11661166
req->mask = cpu_to_be64(0xF0000000);
@@ -1177,11 +1177,10 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk,
11771177
* @tid: connection id
11781178
* @hcrc: header digest enabled
11791179
* @dcrc: data digest enabled
1180-
* @reply: request reply from h/w
11811180
* set up the iscsi digest settings for a connection identified by tid
11821181
*/
11831182
static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
1184-
int hcrc, int dcrc, int reply)
1183+
int hcrc, int dcrc)
11851184
{
11861185
struct sk_buff *skb = alloc_wr(sizeof(struct cpl_set_tcb_field), 0,
11871186
GFP_KERNEL);
@@ -1197,7 +1196,7 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
11971196
req = (struct cpl_set_tcb_field *)skb->head;
11981197
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
11991198
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
1200-
req->reply = V_NO_REPLY(reply ? 0 : 1);
1199+
req->reply = V_NO_REPLY(1);
12011200
req->cpu_idx = 0;
12021201
req->word = htons(31);
12031202
req->mask = cpu_to_be64(0x0F000000);

drivers/scsi/cxgbi/cxgb4i/cxgb4i.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,16 +1548,22 @@ static void do_set_tcb_rpl(struct cxgbi_device *cdev, struct sk_buff *skb)
15481548
struct cxgbi_sock *csk;
15491549

15501550
csk = lookup_tid(t, tid);
1551-
if (!csk)
1551+
if (!csk) {
15521552
pr_err("can't find conn. for tid %u.\n", tid);
1553+
return;
1554+
}
15531555

15541556
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
15551557
"csk 0x%p,%u,%lx,%u, status 0x%x.\n",
15561558
csk, csk->state, csk->flags, csk->tid, rpl->status);
15571559

1558-
if (rpl->status != CPL_ERR_NONE)
1560+
if (rpl->status != CPL_ERR_NONE) {
15591561
pr_err("csk 0x%p,%u, SET_TCB_RPL status %u.\n",
15601562
csk, tid, rpl->status);
1563+
csk->err = -EINVAL;
1564+
}
1565+
1566+
complete(&csk->cmpl);
15611567

15621568
__kfree_skb(skb);
15631569
}
@@ -1983,7 +1989,7 @@ static int ddp_set_map(struct cxgbi_ppm *ppm, struct cxgbi_sock *csk,
19831989
}
19841990

19851991
static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
1986-
int pg_idx, bool reply)
1992+
int pg_idx)
19871993
{
19881994
struct sk_buff *skb;
19891995
struct cpl_set_tcb_field *req;
@@ -1999,7 +2005,7 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
19992005
req = (struct cpl_set_tcb_field *)skb->head;
20002006
INIT_TP_WR(req, csk->tid);
20012007
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, csk->tid));
2002-
req->reply_ctrl = htons(NO_REPLY_V(reply) | QUEUENO_V(csk->rss_qid));
2008+
req->reply_ctrl = htons(NO_REPLY_V(0) | QUEUENO_V(csk->rss_qid));
20032009
req->word_cookie = htons(0);
20042010
req->mask = cpu_to_be64(0x3 << 8);
20052011
req->val = cpu_to_be64(pg_idx << 8);
@@ -2008,12 +2014,15 @@ static int ddp_setup_conn_pgidx(struct cxgbi_sock *csk, unsigned int tid,
20082014
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
20092015
"csk 0x%p, tid 0x%x, pg_idx %u.\n", csk, csk->tid, pg_idx);
20102016

2017+
reinit_completion(&csk->cmpl);
20112018
cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
2012-
return 0;
2019+
wait_for_completion(&csk->cmpl);
2020+
2021+
return csk->err;
20132022
}
20142023

20152024
static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
2016-
int hcrc, int dcrc, int reply)
2025+
int hcrc, int dcrc)
20172026
{
20182027
struct sk_buff *skb;
20192028
struct cpl_set_tcb_field *req;
@@ -2031,7 +2040,7 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
20312040
req = (struct cpl_set_tcb_field *)skb->head;
20322041
INIT_TP_WR(req, tid);
20332042
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, tid));
2034-
req->reply_ctrl = htons(NO_REPLY_V(reply) | QUEUENO_V(csk->rss_qid));
2043+
req->reply_ctrl = htons(NO_REPLY_V(0) | QUEUENO_V(csk->rss_qid));
20352044
req->word_cookie = htons(0);
20362045
req->mask = cpu_to_be64(0x3 << 4);
20372046
req->val = cpu_to_be64(((hcrc ? ULP_CRC_HEADER : 0) |
@@ -2041,8 +2050,11 @@ static int ddp_setup_conn_digest(struct cxgbi_sock *csk, unsigned int tid,
20412050
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
20422051
"csk 0x%p, tid 0x%x, crc %d,%d.\n", csk, csk->tid, hcrc, dcrc);
20432052

2053+
reinit_completion(&csk->cmpl);
20442054
cxgb4_ofld_send(csk->cdev->ports[csk->port_id], skb);
2045-
return 0;
2055+
wait_for_completion(&csk->cmpl);
2056+
2057+
return csk->err;
20462058
}
20472059

20482060
static struct cxgbi_ppm *cdev2ppm(struct cxgbi_device *cdev)

drivers/scsi/cxgbi/libcxgbi.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,7 @@ static struct cxgbi_sock *cxgbi_sock_create(struct cxgbi_device *cdev)
573573
skb_queue_head_init(&csk->receive_queue);
574574
skb_queue_head_init(&csk->write_queue);
575575
timer_setup(&csk->retry_timer, NULL, 0);
576+
init_completion(&csk->cmpl);
576577
rwlock_init(&csk->callback_lock);
577578
csk->cdev = cdev;
578579
csk->flags = 0;
@@ -2251,14 +2252,14 @@ int cxgbi_set_conn_param(struct iscsi_cls_conn *cls_conn,
22512252
if (!err && conn->hdrdgst_en)
22522253
err = csk->cdev->csk_ddp_setup_digest(csk, csk->tid,
22532254
conn->hdrdgst_en,
2254-
conn->datadgst_en, 0);
2255+
conn->datadgst_en);
22552256
break;
22562257
case ISCSI_PARAM_DATADGST_EN:
22572258
err = iscsi_set_param(cls_conn, param, buf, buflen);
22582259
if (!err && conn->datadgst_en)
22592260
err = csk->cdev->csk_ddp_setup_digest(csk, csk->tid,
22602261
conn->hdrdgst_en,
2261-
conn->datadgst_en, 0);
2262+
conn->datadgst_en);
22622263
break;
22632264
case ISCSI_PARAM_MAX_R2T:
22642265
return iscsi_tcp_set_max_r2t(conn, buf);
@@ -2384,7 +2385,7 @@ int cxgbi_bind_conn(struct iscsi_cls_session *cls_session,
23842385

23852386
ppm = csk->cdev->cdev2ppm(csk->cdev);
23862387
err = csk->cdev->csk_ddp_setup_pgidx(csk, csk->tid,
2387-
ppm->tformat.pgsz_idx_dflt, 0);
2388+
ppm->tformat.pgsz_idx_dflt);
23882389
if (err < 0)
23892390
return err;
23902391

drivers/scsi/cxgbi/libcxgbi.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ struct cxgbi_sock {
149149
struct sk_buff_head receive_queue;
150150
struct sk_buff_head write_queue;
151151
struct timer_list retry_timer;
152+
struct completion cmpl;
152153
int err;
153154
rwlock_t callback_lock;
154155
void *user_data;
@@ -490,9 +491,9 @@ struct cxgbi_device {
490491
struct cxgbi_ppm *,
491492
struct cxgbi_task_tag_info *);
492493
int (*csk_ddp_setup_digest)(struct cxgbi_sock *,
493-
unsigned int, int, int, int);
494+
unsigned int, int, int);
494495
int (*csk_ddp_setup_pgidx)(struct cxgbi_sock *,
495-
unsigned int, int, bool);
496+
unsigned int, int);
496497

497498
void (*csk_release_offload_resources)(struct cxgbi_sock *);
498499
int (*csk_rx_pdu_ready)(struct cxgbi_sock *, struct sk_buff *);

0 commit comments

Comments
 (0)