Acked-by: Yin Lin<[email protected]>

Best regards,
Yin

On Tue, Nov 22, 2016 at 5:32 PM, Shashank Ram <[email protected]> wrote:

> Previously, the IP Helper thread would wait for an event
> but with a timeout of 0, which resulted in the thread
> busy waiting causing high CPU usage by the kernel.
> Since the IP Helper thread is only required based on
> certain events, it makes sense to wait indefinitely
> till we receieve such an event notification to wake up
> the thread. This change aims to address this issue.
>
> When OvsEnqueueIpHelperRequest() or OvsInternalAdapterUp()
> is called, the ovsNumIpHelperRequests counter is incremented,
> but upon consumption of the request, is not decremented.
> Since the wakeup logic for the thread is determined by this
> counter value, we need to reset the counter back correctly
> once the request has been consumed by the IP Helper thread.
>
> Signed-off-by: Shashank Ram <[email protected]>
> ---
>  datapath-windows/ovsext/IpHelper.c | 15 +++++++++++++--
>  1 file changed, 13 insertions(+), 2 deletions(-)
>
> diff --git a/datapath-windows/ovsext/IpHelper.c b/datapath-windows/ovsext/
> IpHelper.c
> index d747e8c..636cf95 100644
> --- a/datapath-windows/ovsext/IpHelper.c
> +++ b/datapath-windows/ovsext/IpHelper.c
> @@ -1091,9 +1091,11 @@ OvsInternalAdapterUp(GUID *netCfgInstanceId)
>      InsertHeadList(&ovsIpHelperRequestList, &request->link);
>      ovsNumIpHelperRequests++;
>      if (ovsNumIpHelperRequests == 1) {
> +        NdisReleaseSpinLock(&ovsIpHelperLock);
>          OvsWakeupIPHelper();
> +    } else {
> +        NdisReleaseSpinLock(&ovsIpHelperLock);
>      }
> -    NdisReleaseSpinLock(&ovsIpHelperLock);
>  }
>
>
> @@ -1455,12 +1457,14 @@ OvsStartIpHelper(PVOID data)
>      POVS_IPNEIGH_ENTRY ipn;
>      PLIST_ENTRY link;
>      UINT64   timeVal, timeout;
> +    PLARGE_INTEGER threadSleepTimeout;
>
>      OVS_LOG_INFO("Start the IP Helper Thread, context: %p", context);
>
>      NdisAcquireSpinLock(&ovsIpHelperLock);
>      while (!context->exit) {
>
> +        threadSleepTimeout = NULL;
>          timeout = 0;
>          while (!IsListEmpty(&ovsIpHelperRequestList)) {
>              if (context->exit) {
> @@ -1468,6 +1472,7 @@ OvsStartIpHelper(PVOID data)
>              }
>              link = ovsIpHelperRequestList.Flink;
>              RemoveEntryList(link);
> +            ovsNumIpHelperRequests--;
>              NdisReleaseSpinLock(&ovsIpHelperLock);
>              req = CONTAINING_RECORD(link, OVS_IP_HELPER_REQUEST, link);
>              switch (req->command) {
> @@ -1497,6 +1502,7 @@ OvsStartIpHelper(PVOID data)
>              KeQuerySystemTime((LARGE_INTEGER *)&timeVal);
>              if (ipn->timeout > timeVal) {
>                  timeout = ipn->timeout;
> +                threadSleepTimeout = (PLARGE_INTEGER)&timeout;
>                  break;
>              }
>              ipAddr = ipn->ipAddr;
> @@ -1519,8 +1525,13 @@ ip_helper_wait:
>          KeClearEvent(&context->event);
>          NdisReleaseSpinLock(&ovsIpHelperLock);
>
> +        /*
> +         * Wait indefinitely for the thread to be woken up.
> +         * Passing NULL as the Timeout value in the below
> +         * call to KeWaitForSingleObject achieves this.
> +         */
>          KeWaitForSingleObject(&context->event, Executive, KernelMode,
> -                              FALSE, (LARGE_INTEGER *)&timeout);
> +                              FALSE, threadSleepTimeout);
>          NdisAcquireSpinLock(&ovsIpHelperLock);
>      }
>      NdisReleaseSpinLock(&ovsIpHelperLock);
> --
> 2.6.2
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to