All of lore.kernel.org
 help / color / mirror / Atom feed
From: Lee Jones <lee@kernel.org>
To: Dmitry Rokosov <ddrokosov@salutedevices.com>
Cc: pavel@ucw.cz, linux-kernel@vger.kernel.org,
	linux-leds@vger.kernel.org, kernel@salutedevices.com,
	rockosov@gmail.com, Alexey Romanov <avromanov@salutedevices.com>
Subject: Re: [PATCH v1] leds: introduce ordered workqueue for leds events instead of system_wq
Date: Tue, 3 Sep 2024 15:01:19 +0100	[thread overview]
Message-ID: <20240903140119.GW6858@google.com> (raw)
In-Reply-To: <20240820155407.32729-1-ddrokosov@salutedevices.com>

On Tue, 20 Aug 2024, Dmitry Rokosov wrote:

> This allows to setup ordered workqueue for leds events. This may be
> useful, because default 'system_wq' does not guarantee execution order
> of each work_struct, thus for several brightness update requests (for
> multiple leds), real brightness switch could be in random order.
> 
> Yes, for sysfs-based leds we have flush_work() call inside
> brightness_store() operation, but it's blocking call, so userspace
> caller can be blocked at a long time, which means leds animation stream
> can be broken.
> 
> Ordered workqueue has the same behaviour as system_wq + flush_work(),
> but all scheduled works are async and userspace caller is not blocked,
> which it better for userspace animation scheduling.
> 
> Signed-off-by: Alexey Romanov <avromanov@salutedevices.com>
> Signed-off-by: Dmitry Rokosov <ddrokosov@salutedevices.com>
> ---
>  drivers/leds/led-class.c | 12 +++++++++++-
>  drivers/leds/led-core.c  |  6 +++---
>  include/linux/leds.h     |  1 +
>  3 files changed, 15 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
> index ba1be15cfd8e..fba12471cf1f 100644
> --- a/drivers/leds/led-class.c
> +++ b/drivers/leds/led-class.c
> @@ -25,6 +25,8 @@
>  static DEFINE_MUTEX(leds_lookup_lock);
>  static LIST_HEAD(leds_lookup_list);
>  
> +static struct workqueue_struct *leds_wq;

Does this _have_ to be global?

Isn't there a suitable data structure that we can store it in?

>  static ssize_t brightness_show(struct device *dev,
>  		struct device_attribute *attr, char *buf)
>  {
> @@ -57,7 +59,6 @@ static ssize_t brightness_store(struct device *dev,
>  	if (state == LED_OFF)
>  		led_trigger_remove(led_cdev);
>  	led_set_brightness(led_cdev, state);
> -	flush_work(&led_cdev->set_brightness_work);
>  
>  	ret = size;
>  unlock:
> @@ -549,6 +550,8 @@ int led_classdev_register_ext(struct device *parent,
>  
>  	led_update_brightness(led_cdev);
>  
> +	led_cdev->wq = leds_wq;
> +
>  	led_init_core(led_cdev);
>  
>  #ifdef CONFIG_LEDS_TRIGGERS
> @@ -667,12 +670,19 @@ EXPORT_SYMBOL_GPL(devm_led_classdev_unregister);
>  
>  static int __init leds_init(void)
>  {
> +	leds_wq = alloc_ordered_workqueue("leds", 0);
> +	if (!leds_wq) {
> +		pr_err("failed to create leds ordered workqueue\n");

Nit: "LEDs"

> +		return -ENOMEM;
> +	}
> +
>  	return class_register(&leds_class);
>  }
>  
>  static void __exit leds_exit(void)
>  {
>  	class_unregister(&leds_class);
> +	destroy_workqueue(leds_wq);
>  }
>  
>  subsys_initcall(leds_init);
> diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
> index 89c9806cc97f..9769ac49be20 100644
> --- a/drivers/leds/led-core.c
> +++ b/drivers/leds/led-core.c
> @@ -266,7 +266,7 @@ void led_blink_set_nosleep(struct led_classdev *led_cdev, unsigned long delay_on
>  		led_cdev->delayed_delay_on = delay_on;
>  		led_cdev->delayed_delay_off = delay_off;
>  		set_bit(LED_SET_BLINK, &led_cdev->work_flags);
> -		schedule_work(&led_cdev->set_brightness_work);
> +		queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
>  		return;
>  	}
>  
> @@ -297,7 +297,7 @@ void led_set_brightness(struct led_classdev *led_cdev, unsigned int brightness)
>  		 */
>  		if (!brightness) {
>  			set_bit(LED_BLINK_DISABLE, &led_cdev->work_flags);
> -			schedule_work(&led_cdev->set_brightness_work);
> +			queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
>  		} else {
>  			set_bit(LED_BLINK_BRIGHTNESS_CHANGE,
>  				&led_cdev->work_flags);
> @@ -333,7 +333,7 @@ void led_set_brightness_nopm(struct led_classdev *led_cdev, unsigned int value)
>  		set_bit(LED_SET_BRIGHTNESS_OFF, &led_cdev->work_flags);
>  	}
>  
> -	schedule_work(&led_cdev->set_brightness_work);
> +	queue_work(led_cdev->wq, &led_cdev->set_brightness_work);
>  }
>  EXPORT_SYMBOL_GPL(led_set_brightness_nopm);
>  
> diff --git a/include/linux/leds.h b/include/linux/leds.h
> index 6300313c46b7..7c9f1cb12ab9 100644
> --- a/include/linux/leds.h
> +++ b/include/linux/leds.h
> @@ -169,6 +169,7 @@ struct led_classdev {
>  	int			 new_blink_brightness;
>  	void			(*flash_resume)(struct led_classdev *led_cdev);
>  
> +	struct workqueue_struct *wq; /* LED workqueue */
>  	struct work_struct	set_brightness_work;
>  	int			delayed_set_value;
>  	unsigned long		delayed_delay_on;
> -- 
> 2.43.0
> 
> 

-- 
Lee Jones [李琼斯]

  parent reply	other threads:[~2024-09-03 14:01 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-20 15:54 [PATCH v1] leds: introduce ordered workqueue for leds events instead of system_wq Dmitry Rokosov
2024-08-22 13:38 ` ATTENTION USERS/TESTERS: " Lee Jones
2024-09-03 13:59   ` Lee Jones
2024-09-03 14:01 ` Lee Jones [this message]
2024-09-03 14:59   ` Dmitry Rokosov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240903140119.GW6858@google.com \
    --to=lee@kernel.org \
    --cc=avromanov@salutedevices.com \
    --cc=ddrokosov@salutedevices.com \
    --cc=kernel@salutedevices.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-leds@vger.kernel.org \
    --cc=pavel@ucw.cz \
    --cc=rockosov@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.