我什么时候可以修改通过 GIFT 发送到 vmsplice 的页面?

我什么时候可以修改通过 GIFT 发送到 vmsplice 的页面?

vmsplice(4)与它一起使用时SPLICE_F_GIFT,承诺我的过程不会修改我提供的底层页面。据我所知,正常的工作流程是:

/*pseudo code don't kill me*/
void* page = memmap();
vmsplice(page, SPLICE_F_GIFT);
free(page);

但这要求我每次赠送页面时都使我的 TLB 无效。这很好地抵消了我因不复制数据而获得的任何性能增益。

那么我怎么知道内核是完毕与我的页面?我可以简单地不是释放页面吧?

我假设有这样的用例:

vmsplice -> pipe -> splice -> tcpsocket

我会等待响应,此时内核将刷新其SEND缓冲区,我的页面将再次属于我的?

答案1

那么我怎么知道内核已经完成了我的页面呢?因为我根本无法释放该页面,对吗?

给内核的礼物。应用程序不得修改此内存曾经,否则页面缓存和磁盘上的数据可能会有所不同。

vmsplice -> 管道 -> 拼接 -> tcpsocket

我会等待响应,此时内核将刷新其发送缓冲区,我的页面将再次属于我的?

等到回复在您使用的协议中,确认已收到所有赠送的页面。然后你就会知道内核刷新所有有天赋页面的发送缓冲区。

(顺便说一句,我不会假设页面的内容会保留下来。我想它可以就地进行 IPSec 加密)。

显然,还可以检索“套接字发送队列中未发送的数据量”,因此这是另一种方法。 https://stackoverflow.com/questions/6421771/vmsplice-and-tcp (当然,您不必按照此链接等待它降至 0,您可以在每个页面变得安全时重新使用它)。如果您没有填充内核发送队列,则需要进行轮询。 (当你是的时候,你只需同时重新检查选择()epoll() 告诉你还有更多空间可以写入数据)。

答案2

预期用途是 vmsplice 赠送 mmaped 页面,您无法在 vmsplice 之后更改这些页面,但可以 munmap 它们。

相关内容