Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

NTB: perf: Fix race condition when run with ntb_test

When running ntb_test, the script tries to run the ntb_perf test
immediately after probing the modules. Since adding multi-port support,
this fails seeing the new initialization procedure in ntb_perf
can not complete instantly.

To fix this we add a completion which is waited on when a test is
started. In this way, run can be written any time after the module is
loaded and it will wait for the initialization to complete instead of
sending an error.

Fixes: 5648e56d03fa ("NTB: ntb_perf: Add full multi-port NTB API support")
Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Allen Hubbe <allenbh@gmail.com>
Tested-by: Alexander Fomichev <fomichev.ru@gmail.com>
Signed-off-by: Jon Mason <jdmason@kudzu.us>

authored by

Logan Gunthorpe and committed by
Jon Mason
34d8673a b54369a2

+8 -2
+8 -2
drivers/ntb/test/ntb_perf.c
··· 159 159 /* NTB connection setup service */ 160 160 struct work_struct service; 161 161 unsigned long sts; 162 + 163 + struct completion init_comp; 162 164 }; 163 165 #define to_peer_service(__work) \ 164 166 container_of(__work, struct perf_peer, service) ··· 549 547 550 548 /* Initialization is finally done */ 551 549 set_bit(PERF_STS_DONE, &peer->sts); 550 + complete_all(&peer->init_comp); 552 551 553 552 return 0; 554 553 } ··· 641 638 perf_setup_outbuf(peer); 642 639 643 640 if (test_and_clear_bit(PERF_CMD_CLEAR, &peer->sts)) { 641 + init_completion(&peer->init_comp); 644 642 clear_bit(PERF_STS_DONE, &peer->sts); 645 643 if (test_bit(0, &peer->perf->busy_flag) && 646 644 peer == peer->perf->test_peer) { ··· 1081 1077 struct perf_thread *pthr; 1082 1078 int tidx, ret; 1083 1079 1084 - if (!test_bit(PERF_STS_DONE, &peer->sts)) 1085 - return -ENOLINK; 1080 + ret = wait_for_completion_interruptible(&peer->init_comp); 1081 + if (ret < 0) 1082 + return ret; 1086 1083 1087 1084 if (test_and_set_bit_lock(0, &perf->busy_flag)) 1088 1085 return -EBUSY; ··· 1454 1449 peer->gidx = pidx; 1455 1450 } 1456 1451 INIT_WORK(&peer->service, perf_service_work); 1452 + init_completion(&peer->init_comp); 1457 1453 } 1458 1454 if (perf->gidx == -1) 1459 1455 perf->gidx = pidx;