diff options
Diffstat (limited to 'tools/testing/selftests/ublk/kublk.c')
| -rw-r--r-- | tools/testing/selftests/ublk/kublk.c | 70 |
1 files changed, 42 insertions, 28 deletions
diff --git a/tools/testing/selftests/ublk/kublk.c b/tools/testing/selftests/ublk/kublk.c index 6b8123c12a7a..f8fa102a627f 100644 --- a/tools/testing/selftests/ublk/kublk.c +++ b/tools/testing/selftests/ublk/kublk.c @@ -836,56 +836,70 @@ static int ublk_process_io(struct ublk_thread *t) return reapped; } -static void ublk_thread_set_sched_affinity(const struct ublk_thread *t, - cpu_set_t *cpuset) -{ - if (sched_setaffinity(0, sizeof(*cpuset), cpuset) < 0) - ublk_err("ublk dev %u thread %u set affinity failed", - t->dev->dev_info.dev_id, t->idx); -} - struct ublk_thread_info { struct ublk_dev *dev; + pthread_t thread; unsigned idx; sem_t *ready; cpu_set_t *affinity; unsigned long long extra_flags; }; -static void *ublk_io_handler_fn(void *data) +static void ublk_thread_set_sched_affinity(const struct ublk_thread_info *info) { - struct ublk_thread_info *info = data; - struct ublk_thread *t = &info->dev->threads[info->idx]; + if (pthread_setaffinity_np(pthread_self(), sizeof(*info->affinity), info->affinity) < 0) + ublk_err("ublk dev %u thread %u set affinity failed", + info->dev->dev_info.dev_id, info->idx); +} + +static __attribute__((noinline)) int __ublk_io_handler_fn(struct ublk_thread_info *info) +{ + struct ublk_thread t = { + .dev = info->dev, + .idx = info->idx, + }; int dev_id = info->dev->dev_info.dev_id; int ret; - t->dev = info->dev; - t->idx = info->idx; - - ret = ublk_thread_init(t, info->extra_flags); + ret = ublk_thread_init(&t, info->extra_flags); if (ret) { ublk_err("ublk dev %d thread %u init failed\n", - dev_id, t->idx); - return NULL; + dev_id, t.idx); + return ret; } - /* IO perf is sensitive with queue pthread affinity on NUMA machine*/ - if (info->affinity) - ublk_thread_set_sched_affinity(t, info->affinity); sem_post(info->ready); ublk_dbg(UBLK_DBG_THREAD, "tid %d: ublk dev %d thread %u started\n", - gettid(), dev_id, t->idx); + gettid(), dev_id, t.idx); /* submit all io commands to ublk driver */ - ublk_submit_fetch_commands(t); + ublk_submit_fetch_commands(&t); do { - if (ublk_process_io(t) < 0) + if (ublk_process_io(&t) < 0) break; } while (1); ublk_dbg(UBLK_DBG_THREAD, "tid %d: ublk dev %d thread %d exiting\n", - gettid(), dev_id, t->idx); - ublk_thread_deinit(t); + gettid(), dev_id, t.idx); + ublk_thread_deinit(&t); + return 0; +} + +static void *ublk_io_handler_fn(void *data) +{ + struct ublk_thread_info *info = data; + + /* + * IO perf is sensitive with queue pthread affinity on NUMA machine + * + * Set sched_affinity at beginning, so following allocated memory/pages + * could be CPU/NUMA aware. + */ + if (info->affinity) + ublk_thread_set_sched_affinity(info); + + __ublk_io_handler_fn(info); + return NULL; } @@ -983,14 +997,13 @@ static int ublk_start_daemon(const struct dev_ctx *ctx, struct ublk_dev *dev) */ if (dev->nthreads == dinfo->nr_hw_queues) tinfo[i].affinity = &affinity_buf[i]; - pthread_create(&dev->threads[i].thread, NULL, + pthread_create(&tinfo[i].thread, NULL, ublk_io_handler_fn, &tinfo[i]); } for (i = 0; i < dev->nthreads; i++) sem_wait(&ready); - free(tinfo); free(affinity_buf); /* everything is fine now, start us */ @@ -1013,7 +1026,8 @@ static int ublk_start_daemon(const struct dev_ctx *ctx, struct ublk_dev *dev) /* wait until we are terminated */ for (i = 0; i < dev->nthreads; i++) - pthread_join(dev->threads[i].thread, &thread_ret); + pthread_join(tinfo[i].thread, &thread_ret); + free(tinfo); fail: for (i = 0; i < dinfo->nr_hw_queues; i++) ublk_queue_deinit(&dev->q[i]); |
