From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <stable-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id EB043A0C45
	for <public@inbox.dpdk.org>; Wed, 17 Nov 2021 17:42:53 +0100 (CET)
Received: from [217.70.189.124] (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id D8F4C41142;
	Wed, 17 Nov 2021 17:42:53 +0100 (CET)
Received: from mail-ed1-f46.google.com (mail-ed1-f46.google.com
 [209.85.208.46]) by mails.dpdk.org (Postfix) with ESMTP id 9188140687
 for <stable@dpdk.org>; Wed, 17 Nov 2021 17:42:51 +0100 (CET)
Received: by mail-ed1-f46.google.com with SMTP id w1so13802110edd.10
 for <stable@dpdk.org>; Wed, 17 Nov 2021 08:42:51 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nfware.com; s=google;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to
 :cc; bh=h6oZnf5A5LWZahhANzhmR3sajMgzhhltWNMBmGNiBS0=;
 b=W49EYGTtjdjAT414gmdG80DpL5MBv1OjxYJe8rMA9JMQDKsTaE/C8vNw9W8V9xP9Yd
 yzTisgVlyGOHfGo+f8zxHQKDJwxS9vOHAxeKo5x8dxEkGvh5N42X7LXQgU3cOCShnDNP
 zHi/VruM6WFuyeYirrR/5+TeJXr7OcFpNDSbMZEFKaVaiD3hdkASgwLkTGY5N4+0Om9f
 nw3F92XMDUEr/T8p4iW+N2UM06i66vOkvAlE1HxzZN1n6Q8dCJAurdg1d9gOn3FYhC9r
 IodUa6Av+zl4lBWzLQ7Srue911cqMteGSQP7K2w/Xaz9uzB0ha+v6qigyiK2H5PisNKl
 Mo8g==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to:cc;
 bh=h6oZnf5A5LWZahhANzhmR3sajMgzhhltWNMBmGNiBS0=;
 b=SEZuPzPZY88WDEMwBUKtW4urybfAvkl9I0aq16HMLpxyHobUmi1+xfeVTJvrm12ulL
 fEOAcaLkBNGUv51niC+a3CfIiMMXWP2miHXuJRyirWrsFIaL5QkDGrV/b2IB46r1z5Xm
 fb1AR2xf8v5j6Lp2piQROnKzxah/jvvpVZPSpfH/ghx9utw00F4KLZOkYzHT6wdxA5T9
 5vdzdcgk4u/tgmji8Ui1CVPKYIERfFAfhiYAIQWItWGtVL2iR7xmlYiG/HBrTMEu3Wei
 z1BkKZs+50KU2xLvxt3R9YKV4VVvRqmOB3A+8G3gtsW7P7Ad4Y0wHigQQroIs2Yt0nS5
 sdMQ==
X-Gm-Message-State: AOAM530YIDWAJc7i28XuumD2vaO7/rG8I0jwZY0h7GxKQBVu3VoZ+cHJ
 S4kYGZf6Dg0cxOJ9n6dJ+/+tcQyl6gYkh4+qATOgGA==
X-Google-Smtp-Source: ABdhPJzQGShf3oR6EZnMwDfC/dJUXfxFtoS9bg4tBdTF2gaepiQobnVzi9U4DCkp4H+kY6EG9h2XwiGtcMb/6Jxx+c8=
X-Received: by 2002:aa7:cc82:: with SMTP id p2mr23754478edt.201.1637167371093; 
 Wed, 17 Nov 2021 08:42:51 -0800 (PST)
MIME-Version: 1.0
References: <20211008235830.127167-1-ferruh.yigit@intel.com>
In-Reply-To: <20211008235830.127167-1-ferruh.yigit@intel.com>
From: Igor Ryzhov <iryzhov@nfware.com>
Date: Wed, 17 Nov 2021 19:42:40 +0300
Message-ID: <CAF+s_Fx7U8njih7+WW=8AVG+riuyLggQHy0V93bg3HK+x_9ZCw@mail.gmail.com>
Subject: Re: [PATCH] kni: restrict bifurcated device support
To: Ferruh Yigit <ferruh.yigit@intel.com>
Cc: Elad Nachman <eladv6@gmail.com>, dev@dpdk.org, stable@dpdk.org, 
 Eric Christian <erclists@gmail.com>,
 Stephen Hemminger <stephen@networkplumber.org>
Content-Type: multipart/alternative; boundary="00000000000097a04d05d0febbb0"
X-BeenThere: stable@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: patches for DPDK stable branches <stable.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/stable>,
 <mailto:stable-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/stable/>
List-Post: <mailto:stable@dpdk.org>
List-Help: <mailto:stable-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/stable>,
 <mailto:stable-request@dpdk.org?subject=subscribe>
Errors-To: stable-bounces@dpdk.org

--00000000000097a04d05d0febbb0
Content-Type: text/plain; charset="UTF-8"

Acked-by: Igor Ryzhov <iryzhov@nfware.com>

On Sat, Oct 9, 2021 at 2:58 AM Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> To enable bifurcated device support, rtnl_lock is released before calling
> userspace callbacks and asynchronous requests are enabled.
>
> But these changes caused more issues, like bug #809, #816. To reduce the
> scope of the problems, the bifurcated device support related changes are
> only enabled when it is requested explicitly with new 'enable_bifurcated'
> module parameter.
> And bifurcated device support is disabled by default.
>
> So the bifurcated device related problems are isolated and they can be
> fixed without impacting all use cases.
>
> Bugzilla ID: 816
> Fixes: 631217c76135 ("kni: fix kernel deadlock with bifurcated device")
> Cc: stable@dpdk.org
>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
> Cc: Igor Ryzhov <iryzhov@nfware.com>
> Cc: Elad Nachman <eladv6@gmail.com>
> Cc: Eric Christian <erclists@gmail.com>
> Cc: Stephen Hemminger <stephen@networkplumber.org>
> ---
>  .../prog_guide/kernel_nic_interface.rst       | 28 +++++++++++++
>  kernel/linux/kni/kni_dev.h                    |  3 ++
>  kernel/linux/kni/kni_misc.c                   | 36 ++++++++++++++++
>  kernel/linux/kni/kni_net.c                    | 42 +++++++++++--------
>  4 files changed, 92 insertions(+), 17 deletions(-)
>
> diff --git a/doc/guides/prog_guide/kernel_nic_interface.rst
> b/doc/guides/prog_guide/kernel_nic_interface.rst
> index 1ce03ec1a374..771c7d7fdac4 100644
> --- a/doc/guides/prog_guide/kernel_nic_interface.rst
> +++ b/doc/guides/prog_guide/kernel_nic_interface.rst
> @@ -56,6 +56,12 @@ can be specified when the module is loaded to control
> its behavior:
>                      off   Interfaces will be created with carrier state
> set to off.
>                      on    Interfaces will be created with carrier state
> set to on.
>                       (charp)
> +    parm:           enable_bifurcated: Enable request processing support
> for
> +                    bifurcated drivers, which means releasing rtnl_lock
> before calling
> +                    userspace callback and supporting async requests
> (default=off):
> +                    on    Enable request processing support for
> bifurcated drivers.
> +                     (charp)
> +
>
>  Loading the ``rte_kni`` kernel module without any optional parameters is
>  the typical way a DPDK application gets packets into and out of the kernel
> @@ -174,6 +180,28 @@ To set the default carrier state to *off*:
>  If the ``carrier`` parameter is not specified, the default carrier state
>  of KNI interfaces will be set to *off*.
>
> +.. _kni_bifurcated_device_support:
> +
> +Bifurcated Device Support
> +~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +User callbacks are executed while kernel module holds the ``rtnl`` lock,
> this
> +causes a deadlock when callbacks run control commands on another Linux
> kernel
> +network interface.
> +
> +Bifurcated devices has kernel network driver part and to prevent deadlock
> for
> +them ``enable_bifurcated`` is used.
> +
> +To enable bifurcated device support:
> +
> +.. code-block:: console
> +
> +    # insmod <build_dir>/kernel/linux/kni/rte_kni.ko enable_bifurcated=on
> +
> +Enabling bifurcated device support releases ``rtnl`` lock before calling
> +callback and locks it back after callback. Also enables asynchronous
> request to
> +support callbacks that requires rtnl lock to work (interface down).
> +
>  KNI Creation and Deletion
>  -------------------------
>
> diff --git a/kernel/linux/kni/kni_dev.h b/kernel/linux/kni/kni_dev.h
> index c15da311ba25..e8633486eeb8 100644
> --- a/kernel/linux/kni/kni_dev.h
> +++ b/kernel/linux/kni/kni_dev.h
> @@ -34,6 +34,9 @@
>  /* Default carrier state for created KNI network interfaces */
>  extern uint32_t kni_dflt_carrier;
>
> +/* Request processing support for bifurcated drivers. */
> +extern uint32_t bifurcated_support;
> +
>  /**
>   * A structure describing the private information for a kni device.
>   */
> diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c
> index 2b464c438113..aae977c187a9 100644
> --- a/kernel/linux/kni/kni_misc.c
> +++ b/kernel/linux/kni/kni_misc.c
> @@ -41,6 +41,10 @@ static uint32_t multiple_kthread_on;
>  static char *carrier;
>  uint32_t kni_dflt_carrier;
>
> +/* Request processing support for bifurcated drivers. */
> +static char *enable_bifurcated;
> +uint32_t bifurcated_support;
> +
>  #define KNI_DEV_IN_USE_BIT_NUM 0 /* Bit number for device in use */
>
>  static int kni_net_id;
> @@ -568,6 +572,22 @@ kni_parse_carrier_state(void)
>         return 0;
>  }
>
> +static int __init
> +kni_parse_bifurcated_support(void)
> +{
> +       if (!enable_bifurcated) {
> +               bifurcated_support = 0;
> +               return 0;
> +       }
> +
> +       if (strcmp(enable_bifurcated, "on") == 0)
> +               bifurcated_support = 1;
> +       else
> +               return -1;
> +
> +       return 0;
> +}
> +
>  static int __init
>  kni_init(void)
>  {
> @@ -593,6 +613,13 @@ kni_init(void)
>         else
>                 pr_debug("Default carrier state set to on.\n");
>
> +       if (kni_parse_bifurcated_support() < 0) {
> +               pr_err("Invalid parameter for bifurcated support\n");
> +               return -EINVAL;
> +       }
> +       if (bifurcated_support == 1)
> +               pr_debug("bifurcated support is enabled.\n");
> +
>  #ifdef HAVE_SIMPLIFIED_PERNET_OPERATIONS
>         rc = register_pernet_subsys(&kni_net_ops);
>  #else
> @@ -659,3 +686,12 @@ MODULE_PARM_DESC(carrier,
>  "\t\ton    Interfaces will be created with carrier state set to on.\n"
>  "\t\t"
>  );
> +
> +module_param(enable_bifurcated, charp, 0644);
> +MODULE_PARM_DESC(enable_bifurcated,
> +"Enable request processing support for bifurcated drivers, "
> +"which means releasing rtnl_lock before calling userspace callback and "
> +"supporting async requests (default=off):\n"
> +"\t\ton    Enable request processing support for bifurcated drivers.\n"
> +"\t\t"
> +);
> diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c
> index 611719b5ee27..29e5b9e21f9e 100644
> --- a/kernel/linux/kni/kni_net.c
> +++ b/kernel/linux/kni/kni_net.c
> @@ -113,12 +113,14 @@ kni_net_process_request(struct net_device *dev,
> struct rte_kni_request *req)
>
>         ASSERT_RTNL();
>
> -       /* If we need to wait and RTNL mutex is held
> -        * drop the mutex and hold reference to keep device
> -        */
> -       if (req->async == 0) {
> -               dev_hold(dev);
> -               rtnl_unlock();
> +       if (bifurcated_support) {
> +               /* If we need to wait and RTNL mutex is held
> +                * drop the mutex and hold reference to keep device
> +                */
> +               if (req->async == 0) {
> +                       dev_hold(dev);
> +                       rtnl_unlock();
> +               }
>         }
>
>         mutex_lock(&kni->sync_lock);
> @@ -132,12 +134,14 @@ kni_net_process_request(struct net_device *dev,
> struct rte_kni_request *req)
>                 goto fail;
>         }
>
> -       /* No result available since request is handled
> -        * asynchronously. set response to success.
> -        */
> -       if (req->async != 0) {
> -               req->result = 0;
> -               goto async;
> +       if (bifurcated_support) {
> +               /* No result available since request is handled
> +                * asynchronously. set response to success.
> +                */
> +               if (req->async != 0) {
> +                       req->result = 0;
> +                       goto async;
> +               }
>         }
>
>         ret_val = wait_event_interruptible_timeout(kni->wq,
> @@ -160,9 +164,11 @@ kni_net_process_request(struct net_device *dev,
> struct rte_kni_request *req)
>
>  fail:
>         mutex_unlock(&kni->sync_lock);
> -       if (req->async == 0) {
> -               rtnl_lock();
> -               dev_put(dev);
> +       if (bifurcated_support) {
> +               if (req->async == 0) {
> +                       rtnl_lock();
> +                       dev_put(dev);
> +               }
>         }
>         return ret;
>  }
> @@ -207,8 +213,10 @@ kni_net_release(struct net_device *dev)
>         /* Setting if_up to 0 means down */
>         req.if_up = 0;
>
> -       /* request async because of the deadlock problem */
> -       req.async = 1;
> +       if (bifurcated_support) {
> +               /* request async because of the deadlock problem */
> +               req.async = 1;
> +       }
>
>         ret = kni_net_process_request(dev, &req);
>
> --
> 2.31.1
>
>

--00000000000097a04d05d0febbb0
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Acked-by: Igor Ryzhov &lt;<a href=3D"mailto:iryzhov@nfware=
.com">iryzhov@nfware.com</a>&gt;</div><br><div class=3D"gmail_quote"><div d=
ir=3D"ltr" class=3D"gmail_attr">On Sat, Oct 9, 2021 at 2:58 AM Ferruh Yigit=
 &lt;<a href=3D"mailto:ferruh.yigit@intel.com">ferruh.yigit@intel.com</a>&g=
t; wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0p=
x 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color=
:rgb(204,204,204);padding-left:1ex">To enable bifurcated device support, rt=
nl_lock is released before calling<br>
userspace callbacks and asynchronous requests are enabled.<br>
<br>
But these changes caused more issues, like bug #809, #816. To reduce the<br=
>
scope of the problems, the bifurcated device support related changes are<br=
>
only enabled when it is requested explicitly with new &#39;enable_bifurcate=
d&#39;<br>
module parameter.<br>
And bifurcated device support is disabled by default.<br>
<br>
So the bifurcated device related problems are isolated and they can be<br>
fixed without impacting all use cases.<br>
<br>
Bugzilla ID: 816<br>
Fixes: 631217c76135 (&quot;kni: fix kernel deadlock with bifurcated device&=
quot;)<br>
Cc: <a href=3D"mailto:stable@dpdk.org" target=3D"_blank">stable@dpdk.org</a=
><br>
<br>
Signed-off-by: Ferruh Yigit &lt;<a href=3D"mailto:ferruh.yigit@intel.com" t=
arget=3D"_blank">ferruh.yigit@intel.com</a>&gt;<br>
---<br>
Cc: Igor Ryzhov &lt;<a href=3D"mailto:iryzhov@nfware.com" target=3D"_blank"=
>iryzhov@nfware.com</a>&gt;<br>
Cc: Elad Nachman &lt;<a href=3D"mailto:eladv6@gmail.com" target=3D"_blank">=
eladv6@gmail.com</a>&gt;<br>
Cc: Eric Christian &lt;<a href=3D"mailto:erclists@gmail.com" target=3D"_bla=
nk">erclists@gmail.com</a>&gt;<br>
Cc: Stephen Hemminger &lt;<a href=3D"mailto:stephen@networkplumber.org" tar=
get=3D"_blank">stephen@networkplumber.org</a>&gt;<br>
---<br>
=C2=A0.../prog_guide/kernel_nic_interface.rst=C2=A0 =C2=A0 =C2=A0 =C2=A0| 2=
8 +++++++++++++<br>
=C2=A0kernel/linux/kni/kni_dev.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 3 ++<br>
=C2=A0kernel/linux/kni/kni_misc.c=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0| 36 ++++++++++++++++<br>
=C2=A0kernel/linux/kni/kni_net.c=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 | 42 +++++++++++--------<br>
=C2=A04 files changed, 92 insertions(+), 17 deletions(-)<br>
<br>
diff --git a/doc/guides/prog_guide/kernel_nic_interface.rst b/doc/guides/pr=
og_guide/kernel_nic_interface.rst<br>
index 1ce03ec1a374..771c7d7fdac4 100644<br>
--- a/doc/guides/prog_guide/kernel_nic_interface.rst<br>
+++ b/doc/guides/prog_guide/kernel_nic_interface.rst<br>
@@ -56,6 +56,12 @@ can be specified when the module is loaded to control it=
s behavior:<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0off=C2=A0 =C2=A0Interfaces will be created with carrier state set to off=
.<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0on=C2=A0 =C2=A0 Interfaces will be created with carrier state set to on.=
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (charp)<br>
+=C2=A0 =C2=A0 parm:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0enable_bifurca=
ted: Enable request processing support for<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bifu=
rcated drivers, which means releasing rtnl_lock before calling<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 user=
space callback and supporting async requests (default=3Doff):<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 on=
=C2=A0 =C2=A0 Enable request processing support for bifurcated drivers.<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0(charp)<br>
+<br>
<br>
=C2=A0Loading the ``rte_kni`` kernel module without any optional parameters=
 is<br>
=C2=A0the typical way a DPDK application gets packets into and out of the k=
ernel<br>
@@ -174,6 +180,28 @@ To set the default carrier state to *off*:<br>
=C2=A0If the ``carrier`` parameter is not specified, the default carrier st=
ate<br>
=C2=A0of KNI interfaces will be set to *off*.<br>
<br>
+.. _kni_bifurcated_device_support:<br>
+<br>
+Bifurcated Device Support<br>
+~~~~~~~~~~~~~~~~~~~~~~~~~<br>
+<br>
+User callbacks are executed while kernel module holds the ``rtnl`` lock, t=
his<br>
+causes a deadlock when callbacks run control commands on another Linux ker=
nel<br>
+network interface.<br>
+<br>
+Bifurcated devices has kernel network driver part and to prevent deadlock =
for<br>
+them ``enable_bifurcated`` is used.<br>
+<br>
+To enable bifurcated device support:<br>
+<br>
+.. code-block:: console<br>
+<br>
+=C2=A0 =C2=A0 # insmod &lt;build_dir&gt;/kernel/linux/kni/rte_kni.ko enabl=
e_bifurcated=3Don<br>
+<br>
+Enabling bifurcated device support releases ``rtnl`` lock before calling<b=
r>
+callback and locks it back after callback. Also enables asynchronous reque=
st to<br>
+support callbacks that requires rtnl lock to work (interface down).<br>
+<br>
=C2=A0KNI Creation and Deletion<br>
=C2=A0-------------------------<br>
<br>
diff --git a/kernel/linux/kni/kni_dev.h b/kernel/linux/kni/kni_dev.h<br>
index c15da311ba25..e8633486eeb8 100644<br>
--- a/kernel/linux/kni/kni_dev.h<br>
+++ b/kernel/linux/kni/kni_dev.h<br>
@@ -34,6 +34,9 @@<br>
=C2=A0/* Default carrier state for created KNI network interfaces */<br>
=C2=A0extern uint32_t kni_dflt_carrier;<br>
<br>
+/* Request processing support for bifurcated drivers. */<br>
+extern uint32_t bifurcated_support;<br>
+<br>
=C2=A0/**<br>
=C2=A0 * A structure describing the private information for a kni device.<b=
r>
=C2=A0 */<br>
diff --git a/kernel/linux/kni/kni_misc.c b/kernel/linux/kni/kni_misc.c<br>
index 2b464c438113..aae977c187a9 100644<br>
--- a/kernel/linux/kni/kni_misc.c<br>
+++ b/kernel/linux/kni/kni_misc.c<br>
@@ -41,6 +41,10 @@ static uint32_t multiple_kthread_on;<br>
=C2=A0static char *carrier;<br>
=C2=A0uint32_t kni_dflt_carrier;<br>
<br>
+/* Request processing support for bifurcated drivers. */<br>
+static char *enable_bifurcated;<br>
+uint32_t bifurcated_support;<br>
+<br>
=C2=A0#define KNI_DEV_IN_USE_BIT_NUM 0 /* Bit number for device in use */<b=
r>
<br>
=C2=A0static int kni_net_id;<br>
@@ -568,6 +572,22 @@ kni_parse_carrier_state(void)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return 0;<br>
=C2=A0}<br>
<br>
+static int __init<br>
+kni_parse_bifurcated_support(void)<br>
+{<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (!enable_bifurcated) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bifurcated_support =
=3D 0;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (strcmp(enable_bifurcated, &quot;on&quot;) =
=3D=3D 0)<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bifurcated_support =
=3D 1;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0else<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;<br>
+<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;<br>
+}<br>
+<br>
=C2=A0static int __init<br>
=C2=A0kni_init(void)<br>
=C2=A0{<br>
@@ -593,6 +613,13 @@ kni_init(void)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 else<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pr_debug(&quot;Defa=
ult carrier state set to on.\n&quot;);<br>
<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (kni_parse_bifurcated_support() &lt; 0) {<br=
>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pr_err(&quot;Invali=
d parameter for bifurcated support\n&quot;);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (bifurcated_support =3D=3D 1)<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pr_debug(&quot;bifu=
rcated support is enabled.\n&quot;);<br>
+<br>
=C2=A0#ifdef HAVE_SIMPLIFIED_PERNET_OPERATIONS<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 rc =3D register_pernet_subsys(&amp;kni_net_ops)=
;<br>
=C2=A0#else<br>
@@ -659,3 +686,12 @@ MODULE_PARM_DESC(carrier,<br>
=C2=A0&quot;\t\ton=C2=A0 =C2=A0 Interfaces will be created with carrier sta=
te set to on.\n&quot;<br>
=C2=A0&quot;\t\t&quot;<br>
=C2=A0);<br>
+<br>
+module_param(enable_bifurcated, charp, 0644);<br>
+MODULE_PARM_DESC(enable_bifurcated,<br>
+&quot;Enable request processing support for bifurcated drivers, &quot;<br>
+&quot;which means releasing rtnl_lock before calling userspace callback an=
d &quot;<br>
+&quot;supporting async requests (default=3Doff):\n&quot;<br>
+&quot;\t\ton=C2=A0 =C2=A0 Enable request processing support for bifurcated=
 drivers.\n&quot;<br>
+&quot;\t\t&quot;<br>
+);<br>
diff --git a/kernel/linux/kni/kni_net.c b/kernel/linux/kni/kni_net.c<br>
index 611719b5ee27..29e5b9e21f9e 100644<br>
--- a/kernel/linux/kni/kni_net.c<br>
+++ b/kernel/linux/kni/kni_net.c<br>
@@ -113,12 +113,14 @@ kni_net_process_request(struct net_device *dev, struc=
t rte_kni_request *req)<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ASSERT_RTNL();<br>
<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0/* If we need to wait and RTNL mutex is held<br=
>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 * drop the mutex and hold reference to keep de=
vice<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 */<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0if (req-&gt;async =3D=3D 0) {<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_hold(dev);<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rtnl_unlock();<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (bifurcated_support) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* If we need to wa=
it and RTNL mutex is held<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * drop the mutex a=
nd hold reference to keep device<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (req-&gt;async =
=3D=3D 0) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0dev_hold(dev);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0rtnl_unlock();<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 mutex_lock(&amp;kni-&gt;sync_lock);<br>
@@ -132,12 +134,14 @@ kni_net_process_request(struct net_device *dev, struc=
t rte_kni_request *req)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 goto fail;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0/* No result available since request is handled=
<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 * asynchronously. set response to success.<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 */<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0if (req-&gt;async !=3D 0) {<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0req-&gt;result =3D =
0;<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0goto async;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (bifurcated_support) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* No result availa=
ble since request is handled<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 * asynchronously. =
set response to success.<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 */<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (req-&gt;async !=
=3D 0) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0req-&gt;result =3D 0;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0goto async;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret_val =3D wait_event_interruptible_timeout(kn=
i-&gt;wq,<br>
@@ -160,9 +164,11 @@ kni_net_process_request(struct net_device *dev, struct=
 rte_kni_request *req)<br>
<br>
=C2=A0fail:<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 mutex_unlock(&amp;kni-&gt;sync_lock);<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0if (req-&gt;async =3D=3D 0) {<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0rtnl_lock();<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0dev_put(dev);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (bifurcated_support) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (req-&gt;async =
=3D=3D 0) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0rtnl_lock();<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0dev_put(dev);<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return ret;<br>
=C2=A0}<br>
@@ -207,8 +213,10 @@ kni_net_release(struct net_device *dev)<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Setting if_up to 0 means down */<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 req.if_up =3D 0;<br>
<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0/* request async because of the deadlock proble=
m */<br>
-=C2=A0 =C2=A0 =C2=A0 =C2=A0req.async =3D 1;<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (bifurcated_support) {<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* request async be=
cause of the deadlock problem */<br>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0req.async =3D 1;<br=
>
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}<br>
<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret =3D kni_net_process_request(dev, &amp;req);=
<br>
<br>
-- <br>
2.31.1<br>
<br>
</blockquote></div>

--00000000000097a04d05d0febbb0--