Skip to content

Commit 390e8d1

Browse files
committed
Merge branch 'qed-LL2-fixes'
Michal Kalderon says: ==================== qed: LL2 fixes This series fixes some issues in ll2 related to synchronization and resource freeing ==================== Signed-off-by: Ariel Elior <[email protected]> Signed-off-by: Michal Kalderon <[email protected]> Signed-off-by: David S. Miller <[email protected]>
2 parents dabe93a + 0104e57 commit 390e8d1

File tree

1 file changed

+50
-11
lines changed

1 file changed

+50
-11
lines changed

drivers/net/ethernet/qlogic/qed/qed_ll2.c

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
292292
struct qed_ll2_tx_packet *p_pkt = NULL;
293293
struct qed_ll2_info *p_ll2_conn;
294294
struct qed_ll2_tx_queue *p_tx;
295+
unsigned long flags = 0;
295296
dma_addr_t tx_frag;
296297

297298
p_ll2_conn = qed_ll2_handle_sanity_inactive(p_hwfn, connection_handle);
@@ -300,6 +301,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
300301

301302
p_tx = &p_ll2_conn->tx_queue;
302303

304+
spin_lock_irqsave(&p_tx->lock, flags);
303305
while (!list_empty(&p_tx->active_descq)) {
304306
p_pkt = list_first_entry(&p_tx->active_descq,
305307
struct qed_ll2_tx_packet, list_entry);
@@ -309,6 +311,7 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
309311
list_del(&p_pkt->list_entry);
310312
b_last_packet = list_empty(&p_tx->active_descq);
311313
list_add_tail(&p_pkt->list_entry, &p_tx->free_descq);
314+
spin_unlock_irqrestore(&p_tx->lock, flags);
312315
if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_OOO) {
313316
struct qed_ooo_buffer *p_buffer;
314317

@@ -328,7 +331,9 @@ static void qed_ll2_txq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
328331
b_last_frag,
329332
b_last_packet);
330333
}
334+
spin_lock_irqsave(&p_tx->lock, flags);
331335
}
336+
spin_unlock_irqrestore(&p_tx->lock, flags);
332337
}
333338

334339
static int qed_ll2_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
@@ -556,20 +561,22 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
556561
struct qed_ll2_info *p_ll2_conn = NULL;
557562
struct qed_ll2_rx_packet *p_pkt = NULL;
558563
struct qed_ll2_rx_queue *p_rx;
564+
unsigned long flags = 0;
559565

560566
p_ll2_conn = qed_ll2_handle_sanity_inactive(p_hwfn, connection_handle);
561567
if (!p_ll2_conn)
562568
return;
563569

564570
p_rx = &p_ll2_conn->rx_queue;
565571

572+
spin_lock_irqsave(&p_rx->lock, flags);
566573
while (!list_empty(&p_rx->active_descq)) {
567574
p_pkt = list_first_entry(&p_rx->active_descq,
568575
struct qed_ll2_rx_packet, list_entry);
569576
if (!p_pkt)
570577
break;
571-
572578
list_move_tail(&p_pkt->list_entry, &p_rx->free_descq);
579+
spin_unlock_irqrestore(&p_rx->lock, flags);
573580

574581
if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_OOO) {
575582
struct qed_ooo_buffer *p_buffer;
@@ -588,7 +595,30 @@ static void qed_ll2_rxq_flush(struct qed_hwfn *p_hwfn, u8 connection_handle)
588595
cookie,
589596
rx_buf_addr, b_last);
590597
}
598+
spin_lock_irqsave(&p_rx->lock, flags);
591599
}
600+
spin_unlock_irqrestore(&p_rx->lock, flags);
601+
}
602+
603+
static bool
604+
qed_ll2_lb_rxq_handler_slowpath(struct qed_hwfn *p_hwfn,
605+
struct core_rx_slow_path_cqe *p_cqe)
606+
{
607+
struct ooo_opaque *iscsi_ooo;
608+
u32 cid;
609+
610+
if (p_cqe->ramrod_cmd_id != CORE_RAMROD_RX_QUEUE_FLUSH)
611+
return false;
612+
613+
iscsi_ooo = (struct ooo_opaque *)&p_cqe->opaque_data;
614+
if (iscsi_ooo->ooo_opcode != TCP_EVENT_DELETE_ISLES)
615+
return false;
616+
617+
/* Need to make a flush */
618+
cid = le32_to_cpu(iscsi_ooo->cid);
619+
qed_ooo_release_connection_isles(p_hwfn, p_hwfn->p_ooo_info, cid);
620+
621+
return true;
592622
}
593623

594624
static int qed_ll2_lb_rxq_handler(struct qed_hwfn *p_hwfn,
@@ -617,6 +647,11 @@ static int qed_ll2_lb_rxq_handler(struct qed_hwfn *p_hwfn,
617647
cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain);
618648
cqe_type = cqe->rx_cqe_sp.type;
619649

650+
if (cqe_type == CORE_RX_CQE_TYPE_SLOW_PATH)
651+
if (qed_ll2_lb_rxq_handler_slowpath(p_hwfn,
652+
&cqe->rx_cqe_sp))
653+
continue;
654+
620655
if (cqe_type != CORE_RX_CQE_TYPE_REGULAR) {
621656
DP_NOTICE(p_hwfn,
622657
"Got a non-regular LB LL2 completion [type 0x%02x]\n",
@@ -794,6 +829,9 @@ static int qed_ll2_lb_rxq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
794829
struct qed_ll2_info *p_ll2_conn = (struct qed_ll2_info *)p_cookie;
795830
int rc;
796831

832+
if (!QED_LL2_RX_REGISTERED(p_ll2_conn))
833+
return 0;
834+
797835
rc = qed_ll2_lb_rxq_handler(p_hwfn, p_ll2_conn);
798836
if (rc)
799837
return rc;
@@ -814,6 +852,9 @@ static int qed_ll2_lb_txq_completion(struct qed_hwfn *p_hwfn, void *p_cookie)
814852
u16 new_idx = 0, num_bds = 0;
815853
int rc;
816854

855+
if (!QED_LL2_TX_REGISTERED(p_ll2_conn))
856+
return 0;
857+
817858
new_idx = le16_to_cpu(*p_tx->p_fw_cons);
818859
num_bds = ((s16)new_idx - (s16)p_tx->bds_idx);
819860

@@ -1867,17 +1908,25 @@ int qed_ll2_terminate_connection(void *cxt, u8 connection_handle)
18671908

18681909
/* Stop Tx & Rx of connection, if needed */
18691910
if (QED_LL2_TX_REGISTERED(p_ll2_conn)) {
1911+
p_ll2_conn->tx_queue.b_cb_registred = false;
1912+
smp_wmb(); /* Make sure this is seen by ll2_lb_rxq_completion */
18701913
rc = qed_sp_ll2_tx_queue_stop(p_hwfn, p_ll2_conn);
18711914
if (rc)
18721915
goto out;
1916+
18731917
qed_ll2_txq_flush(p_hwfn, connection_handle);
1918+
qed_int_unregister_cb(p_hwfn, p_ll2_conn->tx_queue.tx_sb_index);
18741919
}
18751920

18761921
if (QED_LL2_RX_REGISTERED(p_ll2_conn)) {
1922+
p_ll2_conn->rx_queue.b_cb_registred = false;
1923+
smp_wmb(); /* Make sure this is seen by ll2_lb_rxq_completion */
18771924
rc = qed_sp_ll2_rx_queue_stop(p_hwfn, p_ll2_conn);
18781925
if (rc)
18791926
goto out;
1927+
18801928
qed_ll2_rxq_flush(p_hwfn, connection_handle);
1929+
qed_int_unregister_cb(p_hwfn, p_ll2_conn->rx_queue.rx_sb_index);
18811930
}
18821931

18831932
if (p_ll2_conn->input.conn_type == QED_LL2_TYPE_OOO)
@@ -1925,16 +1974,6 @@ void qed_ll2_release_connection(void *cxt, u8 connection_handle)
19251974
if (!p_ll2_conn)
19261975
return;
19271976

1928-
if (QED_LL2_RX_REGISTERED(p_ll2_conn)) {
1929-
p_ll2_conn->rx_queue.b_cb_registred = false;
1930-
qed_int_unregister_cb(p_hwfn, p_ll2_conn->rx_queue.rx_sb_index);
1931-
}
1932-
1933-
if (QED_LL2_TX_REGISTERED(p_ll2_conn)) {
1934-
p_ll2_conn->tx_queue.b_cb_registred = false;
1935-
qed_int_unregister_cb(p_hwfn, p_ll2_conn->tx_queue.tx_sb_index);
1936-
}
1937-
19381977
kfree(p_ll2_conn->tx_queue.descq_mem);
19391978
qed_chain_free(p_hwfn->cdev, &p_ll2_conn->tx_queue.txq_chain);
19401979

0 commit comments

Comments
 (0)