[{"id":15035,"web_url":"https://patchwork.libcamera.org/comment/15035/","msgid":"<YB/yiecN9PkqQA59@pendragon.ideasonboard.com>","date":"2021-02-07T14:00:41","subject":"Re: [libcamera-devel] [PATCH 1/7] ipa: raspberrypi: AWB: Remove\n\tunnecessary locking for AWB settings","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi David,\n\nThank you for the patch.\n\nOn Thu, Feb 04, 2021 at 09:34:51AM +0000, David Plowman wrote:\n> AWB settings get updated synchronously with the main thread, so the\n> settings_mutex_ and associated locking can be removed.\n> \n> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> ---\n>  src/ipa/raspberrypi/controller/rpi/awb.cpp | 18 +++++-------------\n>  src/ipa/raspberrypi/controller/rpi/awb.hpp |  4 +---\n>  2 files changed, 6 insertions(+), 16 deletions(-)\n> \n> diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> index 62337b13..dabab726 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> @@ -185,13 +185,11 @@ unsigned int Awb::GetConvergenceFrames() const\n>  \n>  void Awb::SetMode(std::string const &mode_name)\n>  {\n> -\tstd::unique_lock<std::mutex> lock(settings_mutex_);\n>  \tmode_name_ = mode_name;\n>  }\n>  \n>  void Awb::SetManualGains(double manual_r, double manual_b)\n>  {\n> -\tstd::unique_lock<std::mutex> lock(settings_mutex_);\n>  \t// If any of these are 0.0, we swich back to auto.\n>  \tmanual_r_ = manual_r;\n>  \tmanual_b_ = manual_b;\n\nThis patch looks good overall, but I think we have a race condition here\nas manual_r_ and manual_b_ are accessed in the AWB thread, without any\nlock. It's not a new issue introduced by this patch, so\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nbut it should be fixed.\n\n> @@ -229,14 +227,13 @@ void Awb::fetchAsyncResults()\n>  \tsync_results_ = async_results_;\n>  }\n>  \n> -void Awb::restartAsync(StatisticsPtr &stats, std::string const &mode_name,\n> -\t\t       double lux)\n> +void Awb::restartAsync(StatisticsPtr &stats, double lux)\n>  {\n>  \tLOG(RPiAwb, Debug) << \"Starting AWB calculation\";\n>  \t// this makes a new reference which belongs to the asynchronous thread\n>  \tstatistics_ = stats;\n>  \t// store the mode as it could technically change\n> -\tauto m = config_.modes.find(mode_name);\n> +\tauto m = config_.modes.find(mode_name_);\n>  \tmode_ = m != config_.modes.end()\n>  \t\t\t? &m->second\n>  \t\t\t: (mode_ == nullptr ? config_.default_mode : mode_);\n> @@ -244,8 +241,8 @@ void Awb::restartAsync(StatisticsPtr &stats, std::string const &mode_name,\n>  \tframe_phase_ = 0;\n>  \tasync_start_ = true;\n>  \tasync_started_ = true;\n> -\tsize_t len = mode_name.copy(async_results_.mode,\n> -\t\t\t\t    sizeof(async_results_.mode) - 1);\n> +\tsize_t len = mode_name_.copy(async_results_.mode,\n> +\t\t\t\t     sizeof(async_results_.mode) - 1);\n>  \tasync_results_.mode[len] = '\\0';\n>  \tasync_signal_.notify_one();\n>  }\n> @@ -294,11 +291,6 @@ void Awb::Process(StatisticsPtr &stats, Metadata *image_metadata)\n>  \tif (frame_phase_ >= (int)config_.frame_period ||\n>  \t    frame_count2_ < (int)config_.startup_frames) {\n>  \t\t// Update any settings and any image metadata that we need.\n> -\t\tstd::string mode_name;\n> -\t\t{\n> -\t\t\tstd::unique_lock<std::mutex> lock(settings_mutex_);\n> -\t\t\tmode_name = mode_name_;\n> -\t\t}\n>  \t\tstruct LuxStatus lux_status = {};\n>  \t\tlux_status.lux = 400; // in case no metadata\n>  \t\tif (image_metadata->Get(\"lux.status\", lux_status) != 0)\n> @@ -307,7 +299,7 @@ void Awb::Process(StatisticsPtr &stats, Metadata *image_metadata)\n>  \n>  \t\tstd::unique_lock<std::mutex> lock(mutex_);\n>  \t\tif (async_started_ == false)\n> -\t\t\trestartAsync(stats, mode_name, lux_status.lux);\n> +\t\t\trestartAsync(stats, lux_status.lux);\n>  \t}\n>  }\n>  \n> diff --git a/src/ipa/raspberrypi/controller/rpi/awb.hpp b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> index 83b81498..1b39ab4b 100644\n> --- a/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> +++ b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> @@ -134,11 +134,9 @@ private:\n>  \tAwbStatus sync_results_;\n>  \tAwbStatus prev_sync_results_;\n>  \tstd::string mode_name_;\n> -\tstd::mutex settings_mutex_;\n>  \t// The following are for the asynchronous thread to use, though the main\n>  \t// thread can set/reset them if the async thread is known to be idle:\n> -\tvoid restartAsync(StatisticsPtr &stats, std::string const &mode_name,\n> -\t\t\t  double lux);\n> +\tvoid restartAsync(StatisticsPtr &stats, double lux);\n>  \t// copy out the results from the async thread so that it can be restarted\n>  \tvoid fetchAsyncResults();\n>  \tStatisticsPtr statistics_;","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 40B1ABD160\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun,  7 Feb 2021 14:01:06 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 76CBC601B0;\n\tSun,  7 Feb 2021 15:01:05 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 564B0601AB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun,  7 Feb 2021 15:01:04 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D5CF8F3;\n\tSun,  7 Feb 2021 15:01:03 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"mzVrKRsY\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1612706464;\n\tbh=k7hpCl5Mj09GRIHxsfePfkhFYEIhKjr5crLzKz+09cg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=mzVrKRsYExnPLUYKmP/lCY4/a/9/wY4YKkf3u6ZGGiKLco3MUDUBGb8bqnEECZjV0\n\t3ocs5nwF2M2kdN0QLp1aTCDRJjhupt047K+G7eOWOWXhjGRaIsbi4MX03avwhikc+a\n\t4YXKUfPtNofqALpe86YtHfr7itYI7WPWM5MTyYLs=","Date":"Sun, 7 Feb 2021 16:00:41 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"David Plowman <david.plowman@raspberrypi.com>","Message-ID":"<YB/yiecN9PkqQA59@pendragon.ideasonboard.com>","References":"<20210204093457.6879-1-david.plowman@raspberrypi.com>\n\t<20210204093457.6879-2-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20210204093457.6879-2-david.plowman@raspberrypi.com>","Subject":"Re: [libcamera-devel] [PATCH 1/7] ipa: raspberrypi: AWB: Remove\n\tunnecessary locking for AWB settings","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":15042,"web_url":"https://patchwork.libcamera.org/comment/15042/","msgid":"<CAHW6GYL6qWQN_WxOok9S_hx85vEkpU5hh9P1znd6WEEAP411Ng@mail.gmail.com>","date":"2021-02-07T18:04:11","subject":"Re: [libcamera-devel] [PATCH 1/7] ipa: raspberrypi: AWB: Remove\n\tunnecessary locking for AWB settings","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/people/42/","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"content":"Hi Laurent\n\nThanks for the review and for applying the patches!\n\nOn Sun, 7 Feb 2021 at 14:01, Laurent Pinchart\n<laurent.pinchart@ideasonboard.com> wrote:\n>\n> Hi David,\n>\n> Thank you for the patch.\n>\n> On Thu, Feb 04, 2021 at 09:34:51AM +0000, David Plowman wrote:\n> > AWB settings get updated synchronously with the main thread, so the\n> > settings_mutex_ and associated locking can be removed.\n> >\n> > Signed-off-by: David Plowman <david.plowman@raspberrypi.com>\n> > ---\n> >  src/ipa/raspberrypi/controller/rpi/awb.cpp | 18 +++++-------------\n> >  src/ipa/raspberrypi/controller/rpi/awb.hpp |  4 +---\n> >  2 files changed, 6 insertions(+), 16 deletions(-)\n> >\n> > diff --git a/src/ipa/raspberrypi/controller/rpi/awb.cpp b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> > index 62337b13..dabab726 100644\n> > --- a/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> > +++ b/src/ipa/raspberrypi/controller/rpi/awb.cpp\n> > @@ -185,13 +185,11 @@ unsigned int Awb::GetConvergenceFrames() const\n> >\n> >  void Awb::SetMode(std::string const &mode_name)\n> >  {\n> > -     std::unique_lock<std::mutex> lock(settings_mutex_);\n> >       mode_name_ = mode_name;\n> >  }\n> >\n> >  void Awb::SetManualGains(double manual_r, double manual_b)\n> >  {\n> > -     std::unique_lock<std::mutex> lock(settings_mutex_);\n> >       // If any of these are 0.0, we swich back to auto.\n> >       manual_r_ = manual_r;\n> >       manual_b_ = manual_b;\n>\n> This patch looks good overall, but I think we have a race condition here\n> as manual_r_ and manual_b_ are accessed in the AWB thread, without any\n> lock. It's not a new issue introduced by this patch, so\n\nIndeed, I wonder why we'd never paid attention to that. I'll submit a\npatch for that shortly as I have some more (slightly more significant)\nmaintenance patches still in the works!\n\nThanks again and best regards\nDavid\n\n>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n> but it should be fixed.\n>\n> > @@ -229,14 +227,13 @@ void Awb::fetchAsyncResults()\n> >       sync_results_ = async_results_;\n> >  }\n> >\n> > -void Awb::restartAsync(StatisticsPtr &stats, std::string const &mode_name,\n> > -                    double lux)\n> > +void Awb::restartAsync(StatisticsPtr &stats, double lux)\n> >  {\n> >       LOG(RPiAwb, Debug) << \"Starting AWB calculation\";\n> >       // this makes a new reference which belongs to the asynchronous thread\n> >       statistics_ = stats;\n> >       // store the mode as it could technically change\n> > -     auto m = config_.modes.find(mode_name);\n> > +     auto m = config_.modes.find(mode_name_);\n> >       mode_ = m != config_.modes.end()\n> >                       ? &m->second\n> >                       : (mode_ == nullptr ? config_.default_mode : mode_);\n> > @@ -244,8 +241,8 @@ void Awb::restartAsync(StatisticsPtr &stats, std::string const &mode_name,\n> >       frame_phase_ = 0;\n> >       async_start_ = true;\n> >       async_started_ = true;\n> > -     size_t len = mode_name.copy(async_results_.mode,\n> > -                                 sizeof(async_results_.mode) - 1);\n> > +     size_t len = mode_name_.copy(async_results_.mode,\n> > +                                  sizeof(async_results_.mode) - 1);\n> >       async_results_.mode[len] = '\\0';\n> >       async_signal_.notify_one();\n> >  }\n> > @@ -294,11 +291,6 @@ void Awb::Process(StatisticsPtr &stats, Metadata *image_metadata)\n> >       if (frame_phase_ >= (int)config_.frame_period ||\n> >           frame_count2_ < (int)config_.startup_frames) {\n> >               // Update any settings and any image metadata that we need.\n> > -             std::string mode_name;\n> > -             {\n> > -                     std::unique_lock<std::mutex> lock(settings_mutex_);\n> > -                     mode_name = mode_name_;\n> > -             }\n> >               struct LuxStatus lux_status = {};\n> >               lux_status.lux = 400; // in case no metadata\n> >               if (image_metadata->Get(\"lux.status\", lux_status) != 0)\n> > @@ -307,7 +299,7 @@ void Awb::Process(StatisticsPtr &stats, Metadata *image_metadata)\n> >\n> >               std::unique_lock<std::mutex> lock(mutex_);\n> >               if (async_started_ == false)\n> > -                     restartAsync(stats, mode_name, lux_status.lux);\n> > +                     restartAsync(stats, lux_status.lux);\n> >       }\n> >  }\n> >\n> > diff --git a/src/ipa/raspberrypi/controller/rpi/awb.hpp b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> > index 83b81498..1b39ab4b 100644\n> > --- a/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> > +++ b/src/ipa/raspberrypi/controller/rpi/awb.hpp\n> > @@ -134,11 +134,9 @@ private:\n> >       AwbStatus sync_results_;\n> >       AwbStatus prev_sync_results_;\n> >       std::string mode_name_;\n> > -     std::mutex settings_mutex_;\n> >       // The following are for the asynchronous thread to use, though the main\n> >       // thread can set/reset them if the async thread is known to be idle:\n> > -     void restartAsync(StatisticsPtr &stats, std::string const &mode_name,\n> > -                       double lux);\n> > +     void restartAsync(StatisticsPtr &stats, double lux);\n> >       // copy out the results from the async thread so that it can be restarted\n> >       void fetchAsyncResults();\n> >       StatisticsPtr statistics_;\n>\n> --\n> Regards,\n>\n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 5E161BD162\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun,  7 Feb 2021 18:04:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AC6B9601B5;\n\tSun,  7 Feb 2021 19:04:23 +0100 (CET)","from mail-oi1-x236.google.com (mail-oi1-x236.google.com\n\t[IPv6:2607:f8b0:4864:20::236])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6CEF0601AB\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun,  7 Feb 2021 19:04:22 +0100 (CET)","by mail-oi1-x236.google.com with SMTP id h6so13392783oie.5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 07 Feb 2021 10:04:22 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"sV0HmqKT\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=mime-version:references:in-reply-to:from:date:message-id:subject:to\n\t:cc; bh=DlT20ZTlkjzLiI+XlsybPzS/L0lOvqJuLNHKLGWQSpM=;\n\tb=sV0HmqKTB4fFuEMDLzQfcY1Wo7NcjWBzx4FqU0vx7j6ZrhZIYOy1+NZv1yOXd6DG4x\n\tfys7SDGKGVrkDTFjz8TcJzchF6eStVij5L1+EVITKSGNKucEs7/5P8jq5XGATZV1J8zq\n\tD/EwiVd8hvydGyREIhx7cEY6LpGG4iAi/kZkUJWsRLYPtGsao5077Q85znFVs97CqJI3\n\tEHfawNmxHQeyPEtoViJfmbDnrqBkDdgpWLiu2/XUVPIH2PlH3ywP9PHgsvpuM7RbBrHn\n\tkawSaYFdCrtO67iS4uG5pVfiuz2KHB48vii/xdckGguBHQW5SUe9yvDVtl855X1IhyTh\n\t878g==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:mime-version:references:in-reply-to:from:date\n\t:message-id:subject:to:cc;\n\tbh=DlT20ZTlkjzLiI+XlsybPzS/L0lOvqJuLNHKLGWQSpM=;\n\tb=Y+22tYOplRle/Zb0OxKiWz6l0dIxN0DTkZB6ukINJnUOpk410PrHdXmkUgWRD04oUD\n\tBl4JApIhYhP6FqSGERh/Z92sd2NaMDkuNwjOCf3+S9j4d7aWZwCASfDxw7xze2eCrAv4\n\tOLtil/l0JMhxzWSmA72tQcq8PaczVFVme2wRM+BULDhqMHbkuhdujn8jXjZU7/Cb9xaL\n\t704IIAGHuaDMwOK54h9IzMjFDavUclUKD6Rlw9mS32ZHE9Slio/0YGnUNOi/g2AuK0Z1\n\t2ZisOoXMSIP6nH+5gz9V46nrcVL0nv9/N3aPqgz/t/Q8wrPhtUi2p3okNYVd5DeQfjCY\n\taQJA==","X-Gm-Message-State":"AOAM530bdORtgsMaTRHzmql8niIa5a6uGQ8pXuX4D+Oh2wkrbNb3OqMi\n\teTu8cbd/o3QxtV7LLF8CkWCzNF1ACAteX0bzHQJnmRCBT9pDrg==","X-Google-Smtp-Source":"ABdhPJwEcAbLP00WeMIh72EqI22utAwedTMyH6f+Y/+cv/OQHmBBRnY5v/aj+qX/SmhdbJk8wX6A71472aUapcKxOUg=","X-Received":"by 2002:aca:1003:: with SMTP id 3mr3051060oiq.22.1612721061240; \n\tSun, 07 Feb 2021 10:04:21 -0800 (PST)","MIME-Version":"1.0","References":"<20210204093457.6879-1-david.plowman@raspberrypi.com>\n\t<20210204093457.6879-2-david.plowman@raspberrypi.com>\n\t<YB/yiecN9PkqQA59@pendragon.ideasonboard.com>","In-Reply-To":"<YB/yiecN9PkqQA59@pendragon.ideasonboard.com>","From":"David Plowman <david.plowman@raspberrypi.com>","Date":"Sun, 7 Feb 2021 18:04:11 +0000","Message-ID":"<CAHW6GYL6qWQN_WxOok9S_hx85vEkpU5hh9P1znd6WEEAP411Ng@mail.gmail.com>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 1/7] ipa: raspberrypi: AWB: Remove\n\tunnecessary locking for AWB settings","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera devel <libcamera-devel@lists.libcamera.org>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]