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 v2] leds: introduce ordered workqueue for leds events instead of system_wq
Date: Tue, 17 Sep 2024 09:04:12 +0100	[thread overview]
Message-ID: <20240917080412.GB9955@google.com> (raw)
In-Reply-To: <20240916111733.c5rp4l666rtdz7bt@CAB-WSD-L081021>

On Mon, 16 Sep 2024, Dmitry Rokosov wrote:

> Hello Lee!
> 
> What are the next steps? Should I make any changes, or are we waiting
> for test results from the mailing list members?

This is an intrusive core change that was submitted during -rc6.

It's going to need some time on the list for people to respond.

> Sorry for the ping.
> 
> On Wed, Sep 04, 2024 at 01:39:30AM +0300, 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>
> > ---
> > Changes v2 since v1 at [1]:
> >     - replace "leds" with "LEDs" in the log message
> > 
> > Links:
> >     [1] https://lore.kernel.org/all/20240820155407.32729-1-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 c66d1bead0a4..b5e28ad54f7f 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;
> > +
> >  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:
> > @@ -548,6 +549,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
> > @@ -666,12 +669,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");
> > +		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
> > 
> 
> -- 
> Thank you,
> Dmitry

-- 
Lee Jones [李琼斯]

  reply	other threads:[~2024-09-17  8:04 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-03 22:39 [PATCH v2] leds: introduce ordered workqueue for leds events instead of system_wq Dmitry Rokosov
2024-09-16 11:18 ` Dmitry Rokosov
2024-09-17  8:04   ` Lee Jones [this message]
2024-10-22 14:22     ` Dmitry Rokosov
2024-10-29 20:06       ` Dmitry Rokosov
2024-10-31 10:28         ` Lee Jones
2024-11-06  8:11 ` (subset) " Lee Jones
2024-11-06  8:12   ` Lee Jones

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=20240917080412.GB9955@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.