<!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>