-
Notifications
You must be signed in to change notification settings - Fork 521
io_uring_sendzc always report IORING_NOTIF_USAGE_ZC_COPIED #1348
-
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.
imageCould 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/LinuxBeta Was this translation helpful? Give feedback.
All reactions
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
-
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>
Beta Was this translation helpful? Give feedback.
All reactions
-
Do you get any zc notifications without IORING_NOTIF_USAGE_ZC_COPIED? It might be a reporting issue.
Beta Was this translation helpful? Give feedback.
All reactions
-
Do you get any zc notifications without
IORING_NOTIF_USAGE_ZC_COPIED? It might be a reporting issue.
Beta Was this translation helpful? Give feedback.
All reactions
-
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?"
Beta Was this translation helpful? Give feedback.
All reactions
-
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();
}
Beta Was this translation helpful? Give feedback.
All reactions
-
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
Beta Was this translation helpful? Give feedback.