* [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM
@ 2026-09-24 16:23 Alan Borzeszkowski
2026-09-24 16:23 ` [PATCH 1/3] thunderbolt: stream: Add tbstream_dev_from_file() Alan Borzeszkowski
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Alan Borzeszkowski @ 2026-09-24 16:23 UTC (permalink / raw)
To: ericvh, lucho, asmadeus, mika.westerberg, andreas.noever,
YehezkelShB, corbet
Cc: linux-usb, v9fs, linux-doc, linux_oss, alan.borzeszkowski
This series adds trans=thunderbolt, a 9P transport over the
Thunderbolt/USB4 DMA tunnels exposed by the tbstream character devices
(USB4STREAM). It's designed for simple host-to-host file sharing over
single Thunderbolt/USB4 cable.
Today the only practical way to use 9P over a USB4 link is trans=fd
which, due to its design, cannot fully utilize USB4STREAM capabilities.
Thunderbolt transport offers a simpler mount (no fd redirection required),
busy-poll support and substantial throughput increase compared to FD
transport.
User may mount 9P export with following command:
mount -t 9p -o trans=thunderbolt,aname=<exported_remote> /dev/tbstreamX /mnt
Thunderbolt transport achieves a median 1.21x more throughput compared
to FD transport under same conditions, and the advantage grows with
concurrency: 1.03-1.09x at 1-2 threads, 1.14-1.27x at 4, and 1.34-2.28x
at 8-16.
As an example, 4K random reads, 4 worker threads. FD transport achieves
~53k IOPS, Thunderbolt transport ~66k (+24.7%). 4K random writes follow:
FD ~28k IOPS, Thunderbolt ~33k (+19.4%).
With busy-poll enabled, throughput drastically increases for
single-threaded workloads. 4K random read, 1 thread: FD transport 12,345
IOPS, Thunderbolt 12,843 IOPS (+4%), Thunderbolt + busy-poll 22,262 IOPS
(+80.3% vs fd). Normally, busy-polling trades lower latency for increase
in CPU usage but measured system CPU usage was lower (23.1% -> 15.2%).
Above is replicated in more practical example: simulated file-manager
style copy (drag&drop in GUI) of extracted Chromium release repo. Copy
from 9P client to 9P server took 22m29s for FD transport, 21m52s for
Thunderbolt transport (-3%), 14m50s for Thunderbolt + busy-poll (-34%).
__Technical details__
'fio' based benchmarks: random read, random write
ioengine=psync, direct I/O, bs=512-128k, numjobs=1-16, rsize=128M,
runtime=60, ramp=5
'GUI' copy simulation: one extracted chromium-156.0.8066.9 release, 4126
MiB, cp -a --no-preserve=ownership.
Testing was done between two hosts over a single Thunderbolt 5 cable,
with diod as the server (version: 1.1.0-24-gde51d1e), fio (version:
3.36) on modified v7.3 kernel, Ubuntu 24.04 LTS.
Every transport ran on default settings: "msize=131096, cache=none,
version=9p2000.L". Each scenario result is 3-run median. Between each
run, 9P FS was remounted and page cache was dropped on both server and
client.
Alan Borzeszkowski (3):
thunderbolt: stream: Add tbstream_dev_from_file()
net/9p/thunderbolt: Add native 9P Thunderbolt transport support
Documentation/fs/9p: Add Thunderbolt transport documentation
Documentation/filesystems/9p.rst | 39 +++-
MAINTAINERS | 1 +
drivers/thunderbolt/stream.c | 16 ++
include/linux/thunderbolt_stream.h | 14 ++
net/9p/Kconfig | 7 +
net/9p/Makefile | 4 +
net/9p/trans_thunderbolt.c | 348 +++++++++++++++++++++++++++++
7 files changed, 419 insertions(+), 10 deletions(-)
create mode 100644 include/linux/thunderbolt_stream.h
create mode 100644 net/9p/trans_thunderbolt.c
base-commit: 93f51579e7df248780214094418f205253383cc5
--
2.53.0
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH 1/3] thunderbolt: stream: Add tbstream_dev_from_file() 2026-09-24 16:23 [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Alan Borzeszkowski @ 2026-09-24 16:23 ` Alan Borzeszkowski 2026-09-29 6:42 ` Mika Westerberg 2026-09-24 16:23 ` [PATCH 2/3] net/9p/thunderbolt: Add native 9P Thunderbolt transport support Alan Borzeszkowski ` (2 subsequent siblings) 3 siblings, 1 reply; 9+ messages in thread From: Alan Borzeszkowski @ 2026-09-24 16:23 UTC (permalink / raw) To: ericvh, lucho, asmadeus, mika.westerberg, andreas.noever, YehezkelShB, corbet Cc: linux-usb, v9fs, linux-doc, linux_oss, alan.borzeszkowski Add tbstream_dev_from_file() which returns USB4STREAM device behind a file. Expose it to in-kernel users via separate header. Required by the 9P Thunderbolt transport driver to validate mount source. Signed-off-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> --- MAINTAINERS | 1 + drivers/thunderbolt/stream.c | 16 ++++++++++++++++ include/linux/thunderbolt_stream.h | 14 ++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 include/linux/thunderbolt_stream.h diff --git a/MAINTAINERS b/MAINTAINERS index cc3cae2e378b..a626e81d1724 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -27211,6 +27211,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt.git F: Documentation/admin-guide/thunderbolt.rst F: drivers/thunderbolt/ F: include/linux/thunderbolt.h +F: include/linux/thunderbolt_stream.h THUNDERBOLT NETWORK DRIVER M: Mika Westerberg <westeri@kernel.org> diff --git a/drivers/thunderbolt/stream.c b/drivers/thunderbolt/stream.c index 25c259dd0760..d6d0aafd5984 100644 --- a/drivers/thunderbolt/stream.c +++ b/drivers/thunderbolt/stream.c @@ -21,6 +21,7 @@ #include <linux/poll.h> #include <linux/sizes.h> #include <linux/thunderbolt.h> +#include <linux/thunderbolt_stream.h> #include <linux/uaccess.h> #include <linux/uio.h> #include <linux/uuid.h> @@ -1024,6 +1025,21 @@ tbstream_dev_from_group(struct config_group *group) return container_of(group, struct tbstream_dev, group); } +/** + * tbstream_dev_from_file() - Return USB4STREAM device behind a file + * @file: File to check + * + * Return: Pointer to &struct tbstream_dev, %NULL if file is not + * USB4STREAM device. + */ +struct tbstream_dev *tbstream_dev_from_file(struct file *file) +{ + if (file->f_op != &tbstream_dev_fops) + return NULL; + return to_tbstream_dev(file->private_data); +} +EXPORT_SYMBOL_GPL(tbstream_dev_from_file); + static ssize_t tbstream_dev_busy_poll_show(struct config_item *item, char *buf) { struct config_group *group = to_config_group(item); diff --git a/include/linux/thunderbolt_stream.h b/include/linux/thunderbolt_stream.h new file mode 100644 index 000000000000..ed4fdba7c7e9 --- /dev/null +++ b/include/linux/thunderbolt_stream.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Thunderbolt Stream API + * + * Copyright (C) 2026, Intel Corporation + * Author: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> + */ + +#ifndef THUNDERBOLT_STREAM_H_ +#define THUNDERBOLT_STREAM_H_ + +struct tbstream_dev *tbstream_dev_from_file(struct file *file); + +#endif /* THUNDERBOLT_STREAM_H_ */ -- 2.53.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 1/3] thunderbolt: stream: Add tbstream_dev_from_file() 2026-09-24 16:23 ` [PATCH 1/3] thunderbolt: stream: Add tbstream_dev_from_file() Alan Borzeszkowski @ 2026-09-29 6:42 ` Mika Westerberg 0 siblings, 0 replies; 9+ messages in thread From: Mika Westerberg @ 2026-09-29 6:42 UTC (permalink / raw) To: Alan Borzeszkowski Cc: ericvh, lucho, asmadeus, andreas.noever, YehezkelShB, corbet, linux-usb, v9fs, linux-doc, linux_oss On Thu, Sep 24, 2026 at 06:23:31PM +0200, Alan Borzeszkowski wrote: > Add tbstream_dev_from_file() which returns USB4STREAM device behind a > file. Expose it to in-kernel users via separate header. > > Required by the 9P Thunderbolt transport driver to validate mount > source. > > Signed-off-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com> ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] net/9p/thunderbolt: Add native 9P Thunderbolt transport support 2026-09-24 16:23 [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Alan Borzeszkowski 2026-09-24 16:23 ` [PATCH 1/3] thunderbolt: stream: Add tbstream_dev_from_file() Alan Borzeszkowski @ 2026-09-24 16:23 ` Alan Borzeszkowski 2026-09-24 16:23 ` [PATCH 3/3] Documentation/fs/9p: Add Thunderbolt transport documentation Alan Borzeszkowski 2026-10-29 2:45 ` [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Dominique Martinet 3 siblings, 0 replies; 9+ messages in thread From: Alan Borzeszkowski @ 2026-09-24 16:23 UTC (permalink / raw) To: ericvh, lucho, asmadeus, mika.westerberg, andreas.noever, YehezkelShB, corbet Cc: linux-usb, v9fs, linux-doc, linux_oss, alan.borzeszkowski Add native Thunderbolt 9P transport driver which allows user to setup simple host-to-host file sharing over a Thunderbolt/USB4 cable. Compared to FD transport, it offers greater data throughput while being simpler to use. Driver uses blocking write to send data over Thunderbolt fabric and dedicated kthread to read from it. User may mount it like so: mount -t 9p -o trans=thunderbolt,aname=<exported_dir> /dev/tbstream0 /mnt Signed-off-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> --- net/9p/Kconfig | 7 + net/9p/Makefile | 4 + net/9p/trans_thunderbolt.c | 348 +++++++++++++++++++++++++++++++++++++ 3 files changed, 359 insertions(+) create mode 100644 net/9p/trans_thunderbolt.c diff --git a/net/9p/Kconfig b/net/9p/Kconfig index 22f8c167845d..6bbab10c0bea 100644 --- a/net/9p/Kconfig +++ b/net/9p/Kconfig @@ -49,6 +49,13 @@ config NET_9P_USBG This builds support for a transport for 9pfs over usb gadget. +config NET_9P_USB4 + tristate "9P Thunderbolt/USB4 Transport" + depends on USB4_STREAM + help + This builds support for a transport for 9pfs over + Thunderbolt/USB4 cable. + config NET_9P_RDMA depends on INET && INFINIBAND && INFINIBAND_ADDR_TRANS tristate "9P RDMA Transport (Experimental)" diff --git a/net/9p/Makefile b/net/9p/Makefile index 22794a451c3f..417ea999008a 100644 --- a/net/9p/Makefile +++ b/net/9p/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_NET_9P_XEN) += 9pnet_xen.o obj-$(CONFIG_NET_9P_VIRTIO) += 9pnet_virtio.o obj-$(CONFIG_NET_9P_RDMA) += 9pnet_rdma.o obj-$(CONFIG_NET_9P_USBG) += 9pnet_usbg.o +obj-$(CONFIG_NET_9P_USB4) += 9pnet_thunderbolt.o 9pnet-objs := \ mod.o \ @@ -27,3 +28,6 @@ obj-$(CONFIG_NET_9P_USBG) += 9pnet_usbg.o 9pnet_usbg-objs := \ trans_usbg.o \ + +9pnet_thunderbolt-objs := \ + trans_thunderbolt.o \ diff --git a/net/9p/trans_thunderbolt.c b/net/9p/trans_thunderbolt.c new file mode 100644 index 000000000000..95780ac24919 --- /dev/null +++ b/net/9p/trans_thunderbolt.c @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * 9P transport over Thunderbolt/USB4 cable using USB4STREAM. + * + * Copyright (C) 2026, Intel Corporation + * Author: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> + */ + +#include <linux/file.h> +#include <linux/fs_context.h> +#include <linux/kthread.h> +#include <linux/module.h> +#include <linux/sched/signal.h> +#include <linux/sizes.h> +#include <linux/thunderbolt_stream.h> +#include <linux/wait.h> +#include <net/9p/9p.h> +#include <net/9p/client.h> +#include <net/9p/transport.h> + +/** + * struct p9_tb_conn - 9P Thunderbolt connection state + * @client: 9P client instance. + * @stream: USB4STREAM device. + * @req_list_lock: Lock protecting active request list. + * @write_lock: Makes sure only one write happens at a time. + * @req_list: Sent request list. + * @reader: Dedicated read thread. + * @reader_wait: Wake @reader when request is queued. + */ +struct p9_tb_conn { + struct p9_client *client; + struct file *stream; + struct mutex req_list_lock; + struct mutex write_lock; + struct list_head req_list; + struct task_struct *reader; + wait_queue_head_t reader_wait; +}; + +static void p9_tb_conn_cancel(struct p9_tb_conn *p9_tb, int err) +{ + struct p9_req_t *req, *temp; + LIST_HEAD(cancel_list); + + scoped_guard(mutex, &p9_tb->req_list_lock) { + list_for_each_entry_safe(req, temp, &p9_tb->req_list, req_list) { + list_move(&req->req_list, &cancel_list); + WRITE_ONCE(req->status, REQ_STATUS_ERROR); + } + } + + list_for_each_entry_safe(req, temp, &cancel_list, req_list) { + list_del(&req->req_list); + if (!req->t_err) + req->t_err = err; + p9_client_cb(p9_tb->client, req, REQ_STATUS_ERROR); + } +} + +static int p9_tb_read(struct p9_tb_conn *p9_tb, u8 *buf, size_t len) +{ + while (len) { + int ret; + + ret = kernel_read(p9_tb->stream, buf, len, NULL); + if (ret <= 0) + return ret ?: -ESHUTDOWN; + + buf += ret; + len -= ret; + } + + return 0; +} + +static int p9_tb_recv(struct p9_tb_conn *p9_tb) +{ + u8 header[P9_HDRSZ]; + /* rc.size needs to be set for header parse */ + struct p9_fcall rc = { .sdata = header, .size = P9_HDRSZ }; + struct p9_req_t *p9_req; + int ret; + + ret = p9_tb_read(p9_tb, header, P9_HDRSZ); + if (ret) + return ret; + + ret = p9_parse_header(&rc, &rc.size, NULL, NULL, 0); + if (ret) { + p9_debug(P9_DEBUG_ERROR, "error parsing header: %d\n", ret); + return ret; + } + + p9_req = p9_tag_lookup(p9_tb->client, rc.tag); + if (!p9_req) { + p9_debug(P9_DEBUG_ERROR, "request with tag %d not found\n", rc.tag); + return -EIO; + } + if (rc.size > p9_req->rc.capacity) { + p9_debug(P9_DEBUG_ERROR, + "requested packet size too big: %d for tag %d with capacity %zd\n", + rc.size, rc.tag, p9_req->rc.capacity); + ret = -E2BIG; + goto out_put; + } + memcpy(p9_req->rc.sdata, header, P9_HDRSZ); + ret = p9_tb_read(p9_tb, p9_req->rc.sdata + P9_HDRSZ, rc.size - P9_HDRSZ); + if (ret) + goto out_put; + + p9_req->rc.size = rc.size; + p9_debug(P9_DEBUG_TRANS, "got packet tag %d size %d\n", rc.tag, rc.size); + + mutex_lock(&p9_tb->req_list_lock); + if (p9_req->status == REQ_STATUS_SENT) { + list_del(&p9_req->req_list); + p9_client_cb(p9_tb->client, p9_req, REQ_STATUS_RCVD); + } else if (p9_req->status != REQ_STATUS_FLSHD) { + /* Invalid request - neither sent nor flushed */ + ret = -EIO; + } + /* Ignore response for cancelled (flushed) request */ + mutex_unlock(&p9_tb->req_list_lock); + +out_put: + p9_req_put(p9_tb->client, p9_req); + return ret; +} + +static int p9_tb_read_thread(void *data) +{ + struct p9_tb_conn *p9_tb = data; + int ret; + + while (!kthread_should_stop()) { + wait_event_interruptible(p9_tb->reader_wait, + !list_empty_careful(&p9_tb->req_list) || + kthread_should_stop()); + if (kthread_should_stop()) + break; + + ret = p9_tb_recv(p9_tb); + if (ret < 0) { + /* Woken to stop, not real error */ + if (kthread_should_stop()) + break; + + /* Prevent subsequent writes */ + p9_tb->client->status = Disconnected; + + p9_tb_conn_cancel(p9_tb, ret); + } + } + + return 0; +} + +static void p9_tb_close(struct p9_client *client) +{ + struct p9_tb_conn *p9_tb = client->trans; + + client->status = Disconnected; + + if (p9_tb->reader) { + /* Break a blocked read */ + kthread_stop(p9_tb->reader); + } + + p9_tb_conn_cancel(p9_tb, -ECONNRESET); + filp_close(p9_tb->stream, NULL); + kfree(p9_tb); +} + +static int p9_tb_write(struct p9_tb_conn *p9_tb, struct p9_req_t *req) +{ + const char *p = req->tc.sdata; + size_t nbytes = req->tc.size; + int ret; + + scoped_guard(mutex, &p9_tb->req_list_lock) { + WRITE_ONCE(req->status, REQ_STATUS_SENT); + list_move_tail(&req->req_list, &p9_tb->req_list); + } + + if (mutex_lock_interruptible(&p9_tb->write_lock)) { + ret = -ERESTARTSYS; + goto err; + } + + do { + ret = kernel_write(p9_tb->stream, p, nbytes, NULL); + if (ret <= 0) { + mutex_unlock(&p9_tb->write_lock); + if (ret == 0) + ret = -EIO; + + if (nbytes != req->tc.size) { + p9_tb->client->status = Disconnected; + p9_tb_conn_cancel(p9_tb, ret); + } + goto err; + } + nbytes -= ret; + if (nbytes > 0) + p += ret; + } while (nbytes != 0); + mutex_unlock(&p9_tb->write_lock); + + wake_up_interruptible(&p9_tb->reader_wait); + + return 0; + +err: + guard(mutex)(&p9_tb->req_list_lock); + /* + * If request has status other than sent, we know p9_tb_conn_cancel() + * already handled it. + */ + if (READ_ONCE(req->status) == REQ_STATUS_SENT) { + list_del(&req->req_list); + return ret; + } + return 0; +} + +static int p9_tb_request(struct p9_client *client, struct p9_req_t *req) +{ + struct p9_tb_conn *p9_tb = client->trans; + + if (client->status != Connected) + return -EIO; + + return p9_tb_write(p9_tb, req); +} + +static int p9_tb_create(struct p9_client *client, struct fs_context *fc) +{ + const char *devname = fc->source; + struct p9_tb_conn *p9_tb; + struct file *file; + int ret; + + if (!devname) + return -EINVAL; + + p9_tb = kzalloc_obj(*p9_tb); + if (!p9_tb) + return -ENOMEM; + + file = filp_open(devname, O_RDWR, 0); + if (IS_ERR(file)) { + ret = PTR_ERR(file); + goto err_free; + } + + if (!tbstream_dev_from_file(file)) { + ret = -ENODEV; + goto err_close; + } + + p9_tb->stream = file; + p9_tb->client = client; + + init_waitqueue_head(&p9_tb->reader_wait); + INIT_LIST_HEAD(&p9_tb->req_list); + mutex_init(&p9_tb->req_list_lock); + mutex_init(&p9_tb->write_lock); + + p9_tb->reader = kthread_run(p9_tb_read_thread, p9_tb, "9p/%s", + kbasename(devname)); + if (IS_ERR(p9_tb->reader)) { + ret = PTR_ERR(p9_tb->reader); + goto err_close; + } + + client->trans = p9_tb; + client->status = Connected; + + return 0; + +err_close: + filp_close(file, NULL); +err_free: + kfree(p9_tb); + + return ret; +} + +static int p9_tb_cancel(struct p9_client *client, struct p9_req_t *req) +{ + /* + * Once p9_tb_request() returns, 9P request is queued on Thunderbolt + * TX ring and is marked as sent. Return '1' to let 9P client continue + * request flushing. + */ + return 1; +} + +static int p9_tb_cancelled(struct p9_client *client, struct p9_req_t *req) +{ + struct p9_tb_conn *p9_tb = client->trans; + + p9_debug(P9_DEBUG_TRANS, "cancelling sent req %p, tag %d\n", req, req->tc.tag); + + /* + * If request got flushed and we didn't receive response by now, remove + * it from the list. + */ + guard(mutex)(&p9_tb->req_list_lock); + if (READ_ONCE(req->status) != REQ_STATUS_SENT) + return 0; + + list_del(&req->req_list); + WRITE_ONCE(req->status, REQ_STATUS_FLSHD); + p9_req_put(client, req); + return 0; +} + +static struct p9_trans_module p9_tb_trans = { + .name = "thunderbolt", + .owner = THIS_MODULE, + .maxsize = SZ_1M, + .supports_vmalloc = true, + .create = p9_tb_create, + .close = p9_tb_close, + .request = p9_tb_request, + .cancel = p9_tb_cancel, + .cancelled = p9_tb_cancelled, +}; + +static int __init p9_trans_tb_init(void) +{ + v9fs_register_trans(&p9_tb_trans); + return 0; +} +module_init(p9_trans_tb_init); + +static void __exit p9_trans_tb_exit(void) +{ + v9fs_unregister_trans(&p9_tb_trans); +} +module_exit(p9_trans_tb_exit); + +MODULE_ALIAS_9P("thunderbolt"); +MODULE_AUTHOR("Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com>"); +MODULE_DESCRIPTION("9P transport over Thunderbolt/USB4 cable using USB4STREAM"); +MODULE_LICENSE("GPL"); -- 2.53.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/3] Documentation/fs/9p: Add Thunderbolt transport documentation 2026-09-24 16:23 [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Alan Borzeszkowski 2026-09-24 16:23 ` [PATCH 1/3] thunderbolt: stream: Add tbstream_dev_from_file() Alan Borzeszkowski 2026-09-24 16:23 ` [PATCH 2/3] net/9p/thunderbolt: Add native 9P Thunderbolt transport support Alan Borzeszkowski @ 2026-09-24 16:23 ` Alan Borzeszkowski 2026-10-29 2:45 ` [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Dominique Martinet 3 siblings, 0 replies; 9+ messages in thread From: Alan Borzeszkowski @ 2026-09-24 16:23 UTC (permalink / raw) To: ericvh, lucho, asmadeus, mika.westerberg, andreas.noever, YehezkelShB, corbet Cc: linux-usb, v9fs, linux-doc, linux_oss, alan.borzeszkowski With new 9P Thunderbolt transport added, update documentation with simple usage guide. Signed-off-by: Alan Borzeszkowski <alan.borzeszkowski@linux.intel.com> --- Documentation/filesystems/9p.rst | 39 ++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/Documentation/filesystems/9p.rst b/Documentation/filesystems/9p.rst index 3f65db648db0..d79082b320ba 100644 --- a/Documentation/filesystems/9p.rst +++ b/Documentation/filesystems/9p.rst @@ -50,6 +50,24 @@ mount points. Each 9P export is seen by the client as a virtio device with an associated "mount_tag" property. Available mount tags can be seen by reading /sys/bus/virtio/drivers/9pnet_virtio/virtio<n>/mount_tag files. +Thunderbolt/USB4 Usage +====================== + +Establish USB4STREAM between two machines (see Documentation/admin-guide/thunderbolt.rst). +Export filesystem on server machine (e.g., using diod). Example:: + + diod -f -n -S -e /srv/shared -r 3 -w 4 3</dev/tbstream0 4>/dev/tbstream0 + +Mount remote filesystem on client machine using:: + + mount -t 9p -o trans=thunderbolt,aname=<exported_remote_dir > /dev/<USB4STREAM_device> /mnt/9 + +where USB4STREAM device is 'tbstreamX'. + +Example:: + + mount -t 9p -o trans=thunderbolt,aname=/srv/shared /dev/tbstream0 /mnt + USBG Usage ========== @@ -112,16 +130,17 @@ Options trans=name select an alternative transport. Valid options are currently: - ======== ============================================ - unix specifying a named pipe mount point - tcp specifying a normal TCP/IP connection - fd used passed file descriptors for connection - (see rfdno and wfdno) - virtio connect to the next virtio channel available - (from QEMU with trans_virtio module) - rdma connect to a specified RDMA channel - usbg connect to a specified usb gadget channel - ======== ============================================ + =========== ========================================= + unix specifying a named pipe mount point + tcp specifying a normal TCP/IP connection + fd used passed file descriptors for connection + (see rfdno and wfdno) + virtio connect to the next virtio channel available + (from QEMU with trans_virtio module) + rdma connect to a specified RDMA channel + usbg connect to a specified usb gadget channel + thunderbolt connect using USB4STREAM + =========== ========================================= uname=name user name to attempt mount as on the remote server. The server may override or ignore this value. Certain user -- 2.53.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM 2026-09-24 16:23 [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Alan Borzeszkowski ` (2 preceding siblings ...) 2026-09-24 16:23 ` [PATCH 3/3] Documentation/fs/9p: Add Thunderbolt transport documentation Alan Borzeszkowski @ 2026-10-29 2:45 ` Dominique Martinet 2026-11-02 15:39 ` Alan Borzeszkowski 3 siblings, 1 reply; 9+ messages in thread From: Dominique Martinet @ 2026-10-29 2:45 UTC (permalink / raw) To: Alan Borzeszkowski Cc: ericvh, lucho, mika.westerberg, andreas.noever, YehezkelShB, corbet, linux-usb, v9fs, linux-doc, linux_oss Alan Borzeszkowski wrote on Thu, Sep 24, 2026 at 06:23:30PM +0200: > This series adds trans=thunderbolt, a 9P transport over the > Thunderbolt/USB4 DMA tunnels exposed by the tbstream character devices > (USB4STREAM). It's designed for simple host-to-host file sharing over > single Thunderbolt/USB4 cable. > > Today the only practical way to use 9P over a USB4 link is trans=fd > which, due to its design, cannot fully utilize USB4STREAM capabilities. > Thunderbolt transport offers a simpler mount (no fd redirection required), > busy-poll support and substantial throughput increase compared to FD > transport. > > User may mount 9P export with following command: > > mount -t 9p -o trans=thunderbolt,aname=<exported_remote> /dev/tbstreamX /mnt > > Thunderbolt transport achieves a median 1.21x more throughput compared > to FD transport under same conditions, and the advantage grows with > concurrency: 1.03-1.09x at 1-2 threads, 1.14-1.27x at 4, and 1.34-2.28x > at 8-16. > > As an example, 4K random reads, 4 worker threads. FD transport achieves > ~53k IOPS, Thunderbolt transport ~66k (+24.7%). 4K random writes follow: > FD ~28k IOPS, Thunderbolt ~33k (+19.4%). Thanks for the patches We've kept adding new transports for 9p lately but maintenance is becoming a burden so let me push back a bit: is the increased performance really worth it over trans=fd ? If this could be used to bringup a system with a root filesystem like it was done for trans=usbg I'd see the point, but otherwise the simpler usage could be addressed with a simple mount.9p helper, and at this point I'd consider usb4stream to be used for perhaps one-shot copy and not care too much about 4k random IOs (so less affected by latency if msize is large enough, and for a one-shot backup it doesn't matter too much if it takes 6 instead of 5 minutes) If you can convince me this is worth it and can take care of the transport for the forseable future I'm not dead set to refuse this, but I can't say I'm convinced right now, especially as I can't even test this (I don't own two computers with working usb-c...) Thanks, -- Dominique Martinet | Asmadeus ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM 2026-10-29 2:45 ` [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Dominique Martinet @ 2026-11-02 15:39 ` Alan Borzeszkowski 2026-11-09 16:52 ` Mika Westerberg 0 siblings, 1 reply; 9+ messages in thread From: Alan Borzeszkowski @ 2026-11-02 15:39 UTC (permalink / raw) To: Dominique Martinet Cc: ericvh, lucho, mika.westerberg, andreas.noever, YehezkelShB, corbet, linux-usb, v9fs, linux-doc, linux_oss Hi, On Thu, 2026-10-29 at 11:45 +0900, Dominique Martinet wrote: > Alan Borzeszkowski wrote on Thu, Sep 24, 2026 at 06:23:30PM +0200: > > This series adds trans=thunderbolt, a 9P transport over the > > Thunderbolt/USB4 DMA tunnels exposed by the tbstream character > > devices > > (USB4STREAM). It's designed for simple host-to-host file sharing > > over > > single Thunderbolt/USB4 cable. > > > > Today the only practical way to use 9P over a USB4 link is trans=fd > > which, due to its design, cannot fully utilize USB4STREAM > > capabilities. > > Thunderbolt transport offers a simpler mount (no fd redirection > > required), > > busy-poll support and substantial throughput increase compared to > > FD > > transport. > > > > User may mount 9P export with following command: > > > > mount -t 9p -o trans=thunderbolt,aname=<exported_remote> > > /dev/tbstreamX /mnt > > > > Thunderbolt transport achieves a median 1.21x more throughput > > compared > > to FD transport under same conditions, and the advantage grows with > > concurrency: 1.03-1.09x at 1-2 threads, 1.14-1.27x at 4, and 1.34- > > 2.28x > > at 8-16. > > > > As an example, 4K random reads, 4 worker threads. FD transport > > achieves > > ~53k IOPS, Thunderbolt transport ~66k (+24.7%). 4K random writes > > follow: > > FD ~28k IOPS, Thunderbolt ~33k (+19.4%). > > Thanks for the patches > > We've kept adding new transports for 9p lately but maintenance is > becoming a burden so let me push back a bit: is the increased > performance really worth it over trans=fd ? From the data I've collected, yes. trans=thunderbolt is at worst on par with trans=fd and with increasing amount of threads, trans=fd lags behind. Thunderbolt transport also offers busy-poll support, which boosts performance significantly at low thread counts. It cannot be used by trans=fd due to its design around polling. And regarding maintenance, this transport is simple and much smaller than existing ones. > > If this could be used to bringup a system with a root filesystem like > it > was done for trans=usbg I'd see the point, but otherwise the simpler > usage could be addressed with a simple mount.9p helper, and at this > point I'd consider usb4stream to be used for perhaps one-shot copy > and > not care too much about 4k random IOs (so less affected by latency > if msize is large enough, and for a one-shot backup it doesn't matter > too much if it takes 6 instead of 5 minutes) In case of one-shot backup, I think my drag&drop scenario from cover- letter fits it well. Assuming single thread copy, both transports achieve similar results, but with busy-poll enabled, trans=thunderbolt cuts about 1/3rd of copy time: Copy from 9P client to a server, using trans=fd, takes 22m29s while trans=thunderbolt + busy-poll takes 14m50s (~1.5x faster). Reverse direction, same improvement: reducing copy time from 41m07s to 26m56s. All done on default msize. > > If you can convince me this is worth it and can take care of the > transport for the forseable future I'm not dead set to refuse this, > but > I can't say I'm convinced right now, especially as I can't even test > this (I don't own two computers with working usb-c...) I would be happy to maintain Thunderbolt transport. > > Thanks, ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM 2026-11-02 15:39 ` Alan Borzeszkowski @ 2026-11-09 16:52 ` Mika Westerberg 2026-11-10 13:38 ` Dominique Martinet 0 siblings, 1 reply; 9+ messages in thread From: Mika Westerberg @ 2026-11-09 16:52 UTC (permalink / raw) To: Alan Borzeszkowski Cc: Dominique Martinet, ericvh, lucho, andreas.noever, YehezkelShB, corbet, linux-usb, v9fs, linux-doc, linux_oss Hi, On Mon, Nov 02, 2026 at 04:39:15PM +0100, Alan Borzeszkowski wrote: > Hi, > > On Thu, 2026-10-29 at 11:45 +0900, Dominique Martinet wrote: > > Alan Borzeszkowski wrote on Thu, Sep 24, 2026 at 06:23:30PM +0200: > > > This series adds trans=thunderbolt, a 9P transport over the > > > Thunderbolt/USB4 DMA tunnels exposed by the tbstream character > > > devices > > > (USB4STREAM). It's designed for simple host-to-host file sharing > > > over > > > single Thunderbolt/USB4 cable. > > > > > > Today the only practical way to use 9P over a USB4 link is trans=fd > > > which, due to its design, cannot fully utilize USB4STREAM > > > capabilities. > > > Thunderbolt transport offers a simpler mount (no fd redirection > > > required), > > > busy-poll support and substantial throughput increase compared to > > > FD > > > transport. > > > > > > User may mount 9P export with following command: > > > > > > mount -t 9p -o trans=thunderbolt,aname=<exported_remote> > > > /dev/tbstreamX /mnt > > > > > > Thunderbolt transport achieves a median 1.21x more throughput > > > compared > > > to FD transport under same conditions, and the advantage grows with > > > concurrency: 1.03-1.09x at 1-2 threads, 1.14-1.27x at 4, and 1.34- > > > 2.28x > > > at 8-16. > > > > > > As an example, 4K random reads, 4 worker threads. FD transport > > > achieves > > > ~53k IOPS, Thunderbolt transport ~66k (+24.7%). 4K random writes > > > follow: > > > FD ~28k IOPS, Thunderbolt ~33k (+19.4%). > > > > Thanks for the patches > > > > We've kept adding new transports for 9p lately but maintenance is > > becoming a burden so let me push back a bit: is the increased > > performance really worth it over trans=fd ? > > >From the data I've collected, yes. trans=thunderbolt is at worst on par > with trans=fd and with increasing amount of threads, trans=fd lags > behind. > > Thunderbolt transport also offers busy-poll support, which boosts > performance significantly at low thread counts. It cannot be used by > trans=fd due to its design around polling. > > And regarding maintenance, this transport is simple and much smaller > than existing ones. > > > > > If this could be used to bringup a system with a root filesystem like > > it > > was done for trans=usbg I'd see the point, but otherwise the simpler > > usage could be addressed with a simple mount.9p helper, and at this > > point I'd consider usb4stream to be used for perhaps one-shot copy > > and > > not care too much about 4k random IOs (so less affected by latency > > if msize is large enough, and for a one-shot backup it doesn't matter > > too much if it takes 6 instead of 5 minutes) > > In case of one-shot backup, I think my drag&drop scenario from cover- > letter fits it well. Assuming single thread copy, both transports > achieve similar results, but with busy-poll enabled, trans=thunderbolt > cuts about 1/3rd of copy time: > Copy from 9P client to a server, using trans=fd, takes 22m29s while > trans=thunderbolt + busy-poll takes 14m50s (~1.5x faster). > Reverse direction, same improvement: reducing copy time from 41m07s to > 26m56s. All done on default msize. That sounds like a good reason to include it IMHO. Also I like the simplicity - no need to run a separate descriptor feeding process :) > > If you can convince me this is worth it and can take care of the > > transport for the forseable future I'm not dead set to refuse this, > > but > > I can't say I'm convinced right now, especially as I can't even test > > this (I don't own two computers with working usb-c...) > > I would be happy to maintain Thunderbolt transport. If Dominique is okay with this, I suggest to send v2 with a MAINTAINERS update as well. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM 2026-11-09 16:52 ` Mika Westerberg @ 2026-11-10 13:38 ` Dominique Martinet 0 siblings, 0 replies; 9+ messages in thread From: Dominique Martinet @ 2026-11-10 13:38 UTC (permalink / raw) To: Mika Westerberg Cc: Alan Borzeszkowski, ericvh, lucho, andreas.noever, YehezkelShB, corbet, linux-usb, v9fs, linux-doc, linux_oss Mika Westerberg wrote on Mon, Nov 09, 2026 at 05:52:36PM +0100: > > In case of one-shot backup, I think my drag&drop scenario from cover- > > letter fits it well. Assuming single thread copy, both transports > > achieve similar results, but with busy-poll enabled, trans=thunderbolt > > cuts about 1/3rd of copy time: > > Copy from 9P client to a server, using trans=fd, takes 22m29s while > > trans=thunderbolt + busy-poll takes 14m50s (~1.5x faster). > > Reverse direction, same improvement: reducing copy time from 41m07s to > > 26m56s. All done on default msize. > > That sounds like a good reason to include it IMHO. Also I like the > simplicity - no need to run a separate descriptor feeding process :) I'm sorry but I'm just not convinced it's useful enough to warrant the effort to review this from my point of view given my lack of time for linux work: - most of the speed benefit comes from busy-poll, can't this be made to work for all fd consumers somehow? (it could be an ioctl before passing the fd to the mount call, or it could reuse e.g. the existing NAPI config with network over usb4stream if that's more practical; in particular I recall some drivers supporting a hybrid mode that'd busy-poll for x ns/ms then fall back to waiting for the irq, that'd get you the best of both worlds as a sane default) - for simplicity it looks like mounting from boot without initrd isn't a goal, so this can all be hidden in a userspace wrapper. 9p has historically always been pretty bare, we're not even doing dns resolution that has been a basic feature available for nfs since forever. You can look at this mount.9P helper for inspiration: https://github.com/nfs-ganesha/nfs-ganesha/blob/V15.2/src/tools/mount.9P > > I would be happy to maintain Thunderbolt transport. > > If Dominique is okay with this, I suggest to send v2 with a MAINTAINERS > update as well. OTOH if you're going to maintain this I have no reason to block, I can just say I'm not reviewing in depth and pass the ball to Linus or someone else higher up the stack to decide... -- Dominique Martinet | Asmadeus ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-11-10 13:38 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-24 16:23 [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Alan Borzeszkowski 2026-09-24 16:23 ` [PATCH 1/3] thunderbolt: stream: Add tbstream_dev_from_file() Alan Borzeszkowski 2026-09-29 6:42 ` Mika Westerberg 2026-09-24 16:23 ` [PATCH 2/3] net/9p/thunderbolt: Add native 9P Thunderbolt transport support Alan Borzeszkowski 2026-09-24 16:23 ` [PATCH 3/3] Documentation/fs/9p: Add Thunderbolt transport documentation Alan Borzeszkowski 2026-10-29 2:45 ` [PATCH 0/3] net/9p: Add 9P transport over USB4STREAM Dominique Martinet 2026-11-02 15:39 ` Alan Borzeszkowski 2026-11-09 16:52 ` Mika Westerberg 2026-11-10 13:38 ` Dominique Martinet
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox