Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

io_uring_sendzc always report IORING_NOTIF_USAGE_ZC_COPIED #1348

Answered by isilence
dreamlike-ocean asked this question in Q&A
Discussion options

I'm attempting to use io_uring_sendzc for zero-copy TCP sending, and I've set the IORING_SEND_ZC_REPORT_USAGE zcflag.

However, I've noticed that the IORING_NOTIF_USAGE_ZC_COPIED flag is always set in cqe.res for the IORING_CQE_F_NOTIF, even though I've set SO_SNDBUF to be much larger than the size of the packet I'm trying to send.

image

Could you please guide me on how to correctly achieve zero-copy TCP sending in this scenario?
What conditions might cause a fallback to the copy-based implementation instead of the zero-copy implementation?

My Linux version:

Linux dreamlike-MS-7E01 6.11.0-14-generic #15-Ubuntu SMP PREEMPT_DYNAMIC Fri Jan 10 23:48:25 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
You must be logged in to vote

It could happen for multiple reasons, one is when the net device doesn't support necessary features, namely scatter gather tx and checksum offloading. Virtual devices like loop and veth don't support that. You can check it with ethtool -k <dev>

Replies: 1 comment 9 replies

Comment options

It could happen for multiple reasons, one is when the net device doesn't support necessary features, namely scatter gather tx and checksum offloading. Virtual devices like loop and veth don't support that. You can check it with ethtool -k <dev>

You must be logged in to vote
9 replies
Comment options

Do you get any zc notifications without IORING_NOTIF_USAGE_ZC_COPIED? It might be a reporting issue.

Comment options

Do you get any zc notifications without IORING_NOTIF_USAGE_ZC_COPIED? It might be a reporting issue.

wow, some succeeded and some failed.
image
image

Comment options

When I restrict the use of IORING_OP_SEND_ZC/IORING_OP_SENDMSG_ZC to only buffers larger than 8k, all results are sendzc success.
Could it be that small buffers also fall back to copied?"

Comment options

isilence Sep 1, 2025
Collaborator

When I restrict the use of IORING_OP_SEND_ZC/IORING_OP_SENDMSG_ZC to only buffers larger than 8k, all results are sendzc success. Could it be that small buffers also fall back to copied?"

Nah, there is no fallback for TCP, it's up to the user. Considering the script above didn't print anything, I believe it is zerocopy, but the reporting is broken. Specifically for a performance feature called notification stacking.

Let's see if this bpftrace script will give anything interesting. You can run it as the previous one, but it'll likely be more convenient to put it into a file.

kprobe:io_tx_ubuf_complete {
	$skb = arg0;
	$uarg = (struct ubuf_info *)arg1;
	$success = arg2;
	$off = offsetof(struct io_notif_data, uarg);
	$nd = (struct io_notif_data *)((int8 *)$uarg - $off);
	$token = 0;
	if ($skb) {
		$token += 1;
	}
	if ($success) {
		$token += 10;
	}
	if ($nd->zc_report) {
		if ($nd->zc_used) {
			$token += 100;
		}
		if ($nd->zc_copied) {
			$token += 1000;
		}
	}
	if ((int64)$nd->next) {
		$token += 10000;
	}
	@[$token, kstack] = count();
}
Comment options

isilence Sep 1, 2025
Collaborator

You can also profile it, it should show if there were any copies:

perf record -g -- ./program
perf report --children --call-graph=graph,0 > file.txt 
Answer selected by dreamlike-ocean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /