Skip to content

Commit b4cec5f

Browse files
committed
Merge tag 'ntb-4.6' of git://github.com/jonmason/ntb
Pull NTB bug fixes from Jon Mason: "NTB bug fixes for tasklet from spinning forever, link errors, translation window setup, NULL ptr dereference, and ntb-perf errors. Also, a modification to the driver API that makes _addr functions optional" * tag 'ntb-4.6' of git://github.com/jonmason/ntb: NTB: Remove _addr functions from ntb_hw_amd NTB: Make _addr functions optional in the API NTB: Fix incorrect clean up routine in ntb_perf NTB: Fix incorrect return check in ntb_perf ntb: fix possible NULL dereference ntb: add missing setup of translation window ntb: stop link work when we do not have memory ntb: stop tasklet from spinning forever during shutdown. ntb: perf test: fix address space confusion
2 parents 895a106 + 4f1b50c commit b4cec5f

File tree

4 files changed

+79
-70
lines changed

4 files changed

+79
-70
lines changed

drivers/ntb/hw/amd/ntb_hw_amd.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -357,20 +357,6 @@ static int amd_ntb_db_clear_mask(struct ntb_dev *ntb, u64 db_bits)
357357
return 0;
358358
}
359359

360-
static int amd_ntb_peer_db_addr(struct ntb_dev *ntb,
361-
phys_addr_t *db_addr,
362-
resource_size_t *db_size)
363-
{
364-
struct amd_ntb_dev *ndev = ntb_ndev(ntb);
365-
366-
if (db_addr)
367-
*db_addr = (phys_addr_t)(ndev->peer_mmio + AMD_DBREQ_OFFSET);
368-
if (db_size)
369-
*db_size = sizeof(u32);
370-
371-
return 0;
372-
}
373-
374360
static int amd_ntb_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
375361
{
376362
struct amd_ntb_dev *ndev = ntb_ndev(ntb);
@@ -415,20 +401,6 @@ static int amd_ntb_spad_write(struct ntb_dev *ntb,
415401
return 0;
416402
}
417403

418-
static int amd_ntb_peer_spad_addr(struct ntb_dev *ntb, int idx,
419-
phys_addr_t *spad_addr)
420-
{
421-
struct amd_ntb_dev *ndev = ntb_ndev(ntb);
422-
423-
if (idx < 0 || idx >= ndev->spad_count)
424-
return -EINVAL;
425-
426-
if (spad_addr)
427-
*spad_addr = (phys_addr_t)(ndev->self_mmio + AMD_SPAD_OFFSET +
428-
ndev->peer_spad + (idx << 2));
429-
return 0;
430-
}
431-
432404
static u32 amd_ntb_peer_spad_read(struct ntb_dev *ntb, int idx)
433405
{
434406
struct amd_ntb_dev *ndev = ntb_ndev(ntb);
@@ -472,12 +444,10 @@ static const struct ntb_dev_ops amd_ntb_ops = {
472444
.db_clear = amd_ntb_db_clear,
473445
.db_set_mask = amd_ntb_db_set_mask,
474446
.db_clear_mask = amd_ntb_db_clear_mask,
475-
.peer_db_addr = amd_ntb_peer_db_addr,
476447
.peer_db_set = amd_ntb_peer_db_set,
477448
.spad_count = amd_ntb_spad_count,
478449
.spad_read = amd_ntb_spad_read,
479450
.spad_write = amd_ntb_spad_write,
480-
.peer_spad_addr = amd_ntb_peer_spad_addr,
481451
.peer_spad_read = amd_ntb_peer_spad_read,
482452
.peer_spad_write = amd_ntb_peer_spad_write,
483453
};

drivers/ntb/ntb_transport.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ struct ntb_transport_qp {
124124

125125
bool client_ready;
126126
bool link_is_up;
127+
bool active;
127128

128129
u8 qp_num; /* Only 64 QP's are allowed. 0-63 */
129130
u64 qp_bit;
@@ -719,6 +720,7 @@ static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw,
719720
static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp)
720721
{
721722
qp->link_is_up = false;
723+
qp->active = false;
722724

723725
qp->tx_index = 0;
724726
qp->rx_index = 0;
@@ -827,7 +829,7 @@ static void ntb_transport_link_work(struct work_struct *work)
827829
struct pci_dev *pdev = ndev->pdev;
828830
resource_size_t size;
829831
u32 val;
830-
int rc, i, spad;
832+
int rc = 0, i, spad;
831833

832834
/* send the local info, in the opposite order of the way we read it */
833835
for (i = 0; i < nt->mw_count; i++) {
@@ -897,6 +899,13 @@ static void ntb_transport_link_work(struct work_struct *work)
897899
out1:
898900
for (i = 0; i < nt->mw_count; i++)
899901
ntb_free_mw(nt, i);
902+
903+
/* if there's an actual failure, we should just bail */
904+
if (rc < 0) {
905+
ntb_link_disable(ndev);
906+
return;
907+
}
908+
900909
out:
901910
if (ntb_link_is_up(ndev, NULL, NULL) == 1)
902911
schedule_delayed_work(&nt->link_work,
@@ -926,11 +935,13 @@ static void ntb_qp_link_work(struct work_struct *work)
926935
if (val & BIT(qp->qp_num)) {
927936
dev_info(&pdev->dev, "qp %d: Link Up\n", qp->qp_num);
928937
qp->link_is_up = true;
938+
qp->active = true;
929939

930940
if (qp->event_handler)
931941
qp->event_handler(qp->cb_data, qp->link_is_up);
932942

933-
tasklet_schedule(&qp->rxc_db_work);
943+
if (qp->active)
944+
tasklet_schedule(&qp->rxc_db_work);
934945
} else if (nt->link_is_up)
935946
schedule_delayed_work(&qp->link_work,
936947
msecs_to_jiffies(NTB_LINK_DOWN_TIMEOUT));
@@ -1411,7 +1422,8 @@ static void ntb_transport_rxc_db(unsigned long data)
14111422

14121423
if (i == qp->rx_max_entry) {
14131424
/* there is more work to do */
1414-
tasklet_schedule(&qp->rxc_db_work);
1425+
if (qp->active)
1426+
tasklet_schedule(&qp->rxc_db_work);
14151427
} else if (ntb_db_read(qp->ndev) & BIT_ULL(qp->qp_num)) {
14161428
/* the doorbell bit is set: clear it */
14171429
ntb_db_clear(qp->ndev, BIT_ULL(qp->qp_num));
@@ -1422,7 +1434,8 @@ static void ntb_transport_rxc_db(unsigned long data)
14221434
* ntb_process_rxc and clearing the doorbell bit:
14231435
* there might be some more work to do.
14241436
*/
1425-
tasklet_schedule(&qp->rxc_db_work);
1437+
if (qp->active)
1438+
tasklet_schedule(&qp->rxc_db_work);
14261439
}
14271440
}
14281441

@@ -1760,6 +1773,8 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp)
17601773

17611774
pdev = qp->ndev->pdev;
17621775

1776+
qp->active = false;
1777+
17631778
if (qp->tx_dma_chan) {
17641779
struct dma_chan *chan = qp->tx_dma_chan;
17651780
/* Putting the dma_chan to NULL will force any new traffic to be
@@ -1793,7 +1808,7 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp)
17931808
qp_bit = BIT_ULL(qp->qp_num);
17941809

17951810
ntb_db_set_mask(qp->ndev, qp_bit);
1796-
tasklet_disable(&qp->rxc_db_work);
1811+
tasklet_kill(&qp->rxc_db_work);
17971812

17981813
cancel_delayed_work_sync(&qp->link_work);
17991814

@@ -1886,7 +1901,8 @@ int ntb_transport_rx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data,
18861901

18871902
ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry, &qp->rx_pend_q);
18881903

1889-
tasklet_schedule(&qp->rxc_db_work);
1904+
if (qp->active)
1905+
tasklet_schedule(&qp->rxc_db_work);
18901906

18911907
return 0;
18921908
}
@@ -2069,7 +2085,8 @@ static void ntb_transport_doorbell_callback(void *data, int vector)
20692085
qp_num = __ffs(db_bits);
20702086
qp = &nt->qp_vec[qp_num];
20712087

2072-
tasklet_schedule(&qp->rxc_db_work);
2088+
if (qp->active)
2089+
tasklet_schedule(&qp->rxc_db_work);
20732090

20742091
db_bits &= ~BIT_ULL(qp_num);
20752092
}

drivers/ntb/test/ntb_perf.c

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ static void perf_copy_callback(void *data)
178178
atomic_dec(&pctx->dma_sync);
179179
}
180180

181-
static ssize_t perf_copy(struct pthr_ctx *pctx, char *dst,
181+
static ssize_t perf_copy(struct pthr_ctx *pctx, char __iomem *dst,
182182
char *src, size_t size)
183183
{
184184
struct perf_ctx *perf = pctx->perf;
@@ -189,7 +189,8 @@ static ssize_t perf_copy(struct pthr_ctx *pctx, char *dst,
189189
dma_cookie_t cookie;
190190
size_t src_off, dst_off;
191191
struct perf_mw *mw = &perf->mw;
192-
u64 vbase, dst_vaddr;
192+
void __iomem *vbase;
193+
void __iomem *dst_vaddr;
193194
dma_addr_t dst_phys;
194195
int retries = 0;
195196

@@ -204,14 +205,14 @@ static ssize_t perf_copy(struct pthr_ctx *pctx, char *dst,
204205
}
205206

206207
device = chan->device;
207-
src_off = (size_t)src & ~PAGE_MASK;
208-
dst_off = (size_t)dst & ~PAGE_MASK;
208+
src_off = (uintptr_t)src & ~PAGE_MASK;
209+
dst_off = (uintptr_t __force)dst & ~PAGE_MASK;
209210

210211
if (!is_dma_copy_aligned(device, src_off, dst_off, size))
211212
return -ENODEV;
212213

213-
vbase = (u64)(u64 *)mw->vbase;
214-
dst_vaddr = (u64)(u64 *)dst;
214+
vbase = mw->vbase;
215+
dst_vaddr = dst;
215216
dst_phys = mw->phys_addr + (dst_vaddr - vbase);
216217

217218
unmap = dmaengine_get_unmap_data(device->dev, 1, GFP_NOWAIT);
@@ -261,13 +262,13 @@ static ssize_t perf_copy(struct pthr_ctx *pctx, char *dst,
261262
return 0;
262263
}
263264

264-
static int perf_move_data(struct pthr_ctx *pctx, char *dst, char *src,
265+
static int perf_move_data(struct pthr_ctx *pctx, char __iomem *dst, char *src,
265266
u64 buf_size, u64 win_size, u64 total)
266267
{
267268
int chunks, total_chunks, i;
268269
int copied_chunks = 0;
269270
u64 copied = 0, result;
270-
char *tmp = dst;
271+
char __iomem *tmp = dst;
271272
u64 perf, diff_us;
272273
ktime_t kstart, kstop, kdiff;
273274

@@ -324,7 +325,7 @@ static int ntb_perf_thread(void *data)
324325
struct perf_ctx *perf = pctx->perf;
325326
struct pci_dev *pdev = perf->ntb->pdev;
326327
struct perf_mw *mw = &perf->mw;
327-
char *dst;
328+
char __iomem *dst;
328329
u64 win_size, buf_size, total;
329330
void *src;
330331
int rc, node, i;
@@ -364,7 +365,7 @@ static int ntb_perf_thread(void *data)
364365
if (buf_size > MAX_TEST_SIZE)
365366
buf_size = MAX_TEST_SIZE;
366367

367-
dst = (char *)mw->vbase;
368+
dst = (char __iomem *)mw->vbase;
368369

369370
atomic_inc(&perf->tsync);
370371
while (atomic_read(&perf->tsync) != perf->perf_threads)
@@ -424,6 +425,7 @@ static int perf_set_mw(struct perf_ctx *perf, resource_size_t size)
424425
{
425426
struct perf_mw *mw = &perf->mw;
426427
size_t xlat_size, buf_size;
428+
int rc;
427429

428430
if (!size)
429431
return -EINVAL;
@@ -447,6 +449,13 @@ static int perf_set_mw(struct perf_ctx *perf, resource_size_t size)
447449
mw->buf_size = 0;
448450
}
449451

452+
rc = ntb_mw_set_trans(perf->ntb, 0, mw->dma_addr, mw->xlat_size);
453+
if (rc) {
454+
dev_err(&perf->ntb->dev, "Unable to set mw0 translation\n");
455+
perf_free_mw(perf);
456+
return -EIO;
457+
}
458+
450459
return 0;
451460
}
452461

@@ -541,13 +550,30 @@ static ssize_t debugfs_run_read(struct file *filp, char __user *ubuf,
541550
return 0;
542551

543552
buf = kmalloc(64, GFP_KERNEL);
553+
if (!buf)
554+
return -ENOMEM;
544555
out_offset = snprintf(buf, 64, "%d\n", perf->run);
545556
ret = simple_read_from_buffer(ubuf, count, offp, buf, out_offset);
546557
kfree(buf);
547558

548559
return ret;
549560
}
550561

562+
static void threads_cleanup(struct perf_ctx *perf)
563+
{
564+
struct pthr_ctx *pctx;
565+
int i;
566+
567+
perf->run = false;
568+
for (i = 0; i < MAX_THREADS; i++) {
569+
pctx = &perf->pthr_ctx[i];
570+
if (pctx->thread) {
571+
kthread_stop(pctx->thread);
572+
pctx->thread = NULL;
573+
}
574+
}
575+
}
576+
551577
static ssize_t debugfs_run_write(struct file *filp, const char __user *ubuf,
552578
size_t count, loff_t *offp)
553579
{
@@ -563,17 +589,9 @@ static ssize_t debugfs_run_write(struct file *filp, const char __user *ubuf,
563589
if (atomic_read(&perf->tsync) == 0)
564590
perf->run = false;
565591

566-
if (perf->run) {
567-
/* lets stop the threads */
568-
perf->run = false;
569-
for (i = 0; i < MAX_THREADS; i++) {
570-
if (perf->pthr_ctx[i].thread) {
571-
kthread_stop(perf->pthr_ctx[i].thread);
572-
perf->pthr_ctx[i].thread = NULL;
573-
} else
574-
break;
575-
}
576-
} else {
592+
if (perf->run)
593+
threads_cleanup(perf);
594+
else {
577595
perf->run = true;
578596

579597
if (perf->perf_threads > MAX_THREADS) {
@@ -604,17 +622,11 @@ static ssize_t debugfs_run_write(struct file *filp, const char __user *ubuf,
604622
kthread_create_on_node(ntb_perf_thread,
605623
(void *)pctx,
606624
node, "ntb_perf %d", i);
607-
if (pctx->thread)
625+
if (IS_ERR(pctx->thread)) {
626+
pctx->thread = NULL;
627+
goto err;
628+
} else
608629
wake_up_process(pctx->thread);
609-
else {
610-
perf->run = false;
611-
for (i = 0; i < MAX_THREADS; i++) {
612-
if (pctx->thread) {
613-
kthread_stop(pctx->thread);
614-
pctx->thread = NULL;
615-
}
616-
}
617-
}
618630

619631
if (perf->run == false)
620632
return -ENXIO;
@@ -623,6 +635,10 @@ static ssize_t debugfs_run_write(struct file *filp, const char __user *ubuf,
623635
}
624636

625637
return count;
638+
639+
err:
640+
threads_cleanup(perf);
641+
return -ENXIO;
626642
}
627643

628644
static const struct file_operations ntb_perf_debugfs_run = {

include/linux/ntb.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ static inline int ntb_dev_ops_is_valid(const struct ntb_dev_ops *ops)
284284
/* ops->db_read_mask && */
285285
ops->db_set_mask &&
286286
ops->db_clear_mask &&
287-
ops->peer_db_addr &&
287+
/* ops->peer_db_addr && */
288288
/* ops->peer_db_read && */
289289
ops->peer_db_set &&
290290
/* ops->peer_db_clear && */
@@ -295,7 +295,7 @@ static inline int ntb_dev_ops_is_valid(const struct ntb_dev_ops *ops)
295295
ops->spad_count &&
296296
ops->spad_read &&
297297
ops->spad_write &&
298-
ops->peer_spad_addr &&
298+
/* ops->peer_spad_addr && */
299299
/* ops->peer_spad_read && */
300300
ops->peer_spad_write &&
301301
1;
@@ -757,6 +757,9 @@ static inline int ntb_peer_db_addr(struct ntb_dev *ntb,
757757
phys_addr_t *db_addr,
758758
resource_size_t *db_size)
759759
{
760+
if (!ntb->ops->peer_db_addr)
761+
return -EINVAL;
762+
760763
return ntb->ops->peer_db_addr(ntb, db_addr, db_size);
761764
}
762765

@@ -948,6 +951,9 @@ static inline int ntb_spad_write(struct ntb_dev *ntb, int idx, u32 val)
948951
static inline int ntb_peer_spad_addr(struct ntb_dev *ntb, int idx,
949952
phys_addr_t *spad_addr)
950953
{
954+
if (!ntb->ops->peer_spad_addr)
955+
return -EINVAL;
956+
951957
return ntb->ops->peer_spad_addr(ntb, idx, spad_addr);
952958
}
953959

0 commit comments

Comments
 (0)