<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p><br>
</p>
<div class="moz-cite-prefix">On 17.04.2025 11:51, Juergen Gross
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:ed8dec2a-f507-49be-a6f3-fb8a91bfef01@suse.com">On
17.04.25 10:45, Alexey wrote:
<br>
<blockquote type="cite">
<br>
On 17.04.2025 10:12, Jürgen Groß wrote:
<br>
<blockquote type="cite">On 17.04.25 09:00, Alexey wrote:
<br>
<blockquote type="cite">
<br>
On 17.04.2025 03:58, Jakub Kicinski wrote:
<br>
<blockquote type="cite">On Mon, 14 Apr 2025 18:34:01 +0000
Alexey Nepomnyashih wrote:
<br>
<blockquote type="cite"> get_page(pdata);
<br>
</blockquote>
Please notice this get_page() here.
<br>
<br>
<blockquote type="cite"> xdpf =
xdp_convert_buff_to_frame(xdp);
<br>
+ if (unlikely(!xdpf)) {
<br>
+
trace_xdp_exception(queue->info->netdev, prog,
act);
<br>
+ break;
<br>
+ }
<br>
</blockquote>
</blockquote>
Do you mean that it would be better to move the
get_page(pdata) call lower,
<br>
after checking for NULL in xdpf, so that the reference count
is only increased
<br>
after a successful conversion?
<br>
</blockquote>
<br>
I think the error handling here is generally broken (or at
least very
<br>
questionable).
<br>
<br>
I suspect that in case of at least some errors the get_page()
is leaking
<br>
even without this new patch.
<br>
<br>
In case I'm wrong a comment reasoning why there is no leak
should be
<br>
added.
<br>
<br>
<br>
Juergen
<br>
</blockquote>
<br>
I think pdata is freed in xdp_return_frame_rx_napi() ->
__xdp_return()
<br>
</blockquote>
<br>
Agreed. But what if xennet_xdp_xmit() returns an error < 0?
<br>
<br>
In this case xdp_return_frame_rx_napi() won't be called.
<br>
<br>
<br>
Juergen
<br>
</blockquote>
<p>Agreed. There is no explicit freed pdata in the calling function<br>
xennet_get_responses(). Without this, the page referenced by pdata<br>
could be leaked.</p>
<p>I suggest:</p>
<pre><span class="token unchanged"><span
class="token prefix unchanged"> </span><span class="token line"> case XDP_TX:
</span></span><span class="token deleted-sign deleted"><span
class="token prefix deleted">-</span><span class="token line"> get_page(pdata);
</span></span><span class="token unchanged"><span
class="token prefix unchanged"> </span><span class="token line"> xdpf = xdp_convert_buff_to_frame(xdp);
</span></span><span class="token inserted-sign inserted"><span
class="token prefix inserted">+</span><span class="token line"> if (unlikely(!xdpf)) {
</span><span class="token prefix inserted">+</span><span
class="token line"> trace_xdp_exception(queue->info->netdev, prog, act);
</span><span class="token prefix inserted">+</span><span
class="token line"> break;
</span><span class="token prefix inserted">+</span><span
class="token line"> }
</span><span class="token prefix inserted">+</span><span
class="token line"> get_page(pdata);
</span></span><span class="token unchanged"><span
class="token prefix unchanged"> </span><span class="token line"> err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
</span><span class="token prefix unchanged"> </span><span
class="token line"> if (unlikely(!err))
</span><span class="token prefix unchanged"> </span><span
class="token line"> xdp_return_frame_rx_napi(xdpf);
</span></span><span class="token deleted-sign deleted"><span
class="token prefix deleted">-</span><span class="token line"> else if (unlikely(err < 0))
</span></span><span class="token inserted-sign inserted"><span
class="token prefix inserted">+</span><span class="token line"> else if (unlikely(err < 0)) {
</span></span><span class="token unchanged"><span
class="token prefix unchanged"> </span><span class="token line"> trace_xdp_exception(queue->info->netdev, prog, act);
</span></span><span class="token inserted-sign inserted"><span
class="token prefix inserted">+</span><span class="token line"> xdp_return_frame_rx_napi(xdpf);
</span><span class="token prefix inserted">+</span><span
class="token line"> }
</span></span><span class="token unchanged"><span
class="token prefix unchanged"> </span><span class="token line"> break;
</span><span class="token prefix unchanged"> </span><span
class="token line"> case XDP_REDIRECT:
</span><span class="token prefix unchanged"> </span><span
class="token line"> get_page(pdata);
</span><span class="token prefix unchanged"> </span><span
class="token line"> err = xdp_do_redirect(queue->info->netdev, xdp, prog);
</span><span class="token prefix unchanged"> </span><span
class="token line"> *need_xdp_flush = true;
</span></span><span class="token deleted-sign deleted"><span
class="token prefix deleted">-</span><span class="token line"> if (unlikely(err))
</span></span><span class="token inserted-sign inserted"><span
class="token prefix inserted">+</span><span class="token line"> if (unlikely(err)) {
</span></span><span class="token unchanged"><span
class="token prefix unchanged"> </span><span class="token line"> trace_xdp_exception(queue->info->netdev, prog, act);
</span></span><span class="token inserted-sign inserted"><span
class="token prefix inserted">+</span><span class="token line"> __xdp_return(page_address(pdata), &xdp->mem, true, xdp);
</span><span class="token prefix inserted">+</span><span
class="token line"> }
</span></span><span class="token unchanged"><span
class="token prefix unchanged"> </span><span class="token line"> break;</span></span></pre>
</body>
</html>