* [PATCH 0/8] Convert input core to use new cleanup facilities
@ 2024-11-07 7:15 Dmitry Torokhov
2024-11-07 7:15 ` [PATCH 1/8] Input: ff-core - convert locking to guard notation Dmitry Torokhov
` (8 more replies)
0 siblings, 9 replies; 15+ messages in thread
From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel
Hi,
This series converts input core (but not input handlers such as evdev,
joydev, etc) to use new __free() and guard() cleanup facilities that
simplify the code and ensure that all resources are released
appropriately.
Input handlers will be converted separately later.
Thanks!
Dmitry Torokhov (8):
Input: ff-core - convert locking to guard notation
Input: ff-core - make use of __free() cleanup facility
Input: ff-memless - convert locking to guard notation
Input: ff-memless - make use of __free() cleanup facility
Input: mt - convert locking to guard notation
Input: mt - make use of __free() cleanup facility
Input: poller - convert locking to guard notation
Input: use guard notation in input core
drivers/input/ff-core.c | 90 ++++------
drivers/input/ff-memless.c | 17 +-
drivers/input/input-mt.c | 34 ++--
drivers/input/input-poller.c | 4 +-
drivers/input/input.c | 339 ++++++++++++++---------------------
5 files changed, 184 insertions(+), 300 deletions(-)
--
Dmitry
^ permalink raw reply [flat|nested] 15+ messages in thread* [PATCH 1/8] Input: ff-core - convert locking to guard notation 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov @ 2024-11-07 7:15 ` Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility Dmitry Torokhov ` (7 subsequent siblings) 8 siblings, 0 replies; 15+ messages in thread From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel Use guard() and scoped_guard() notation instead of explicitly acquiring and releasing spinlocks and mutexes to simplify the code and ensure that all locks are released properly. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/ff-core.c | 71 +++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 42 deletions(-) diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 609a5f01761b..eb01bcb69d00 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -93,7 +93,7 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, { struct ff_device *ff = dev->ff; struct ff_effect *old; - int ret = 0; + int error; int id; if (!test_bit(EV_FF, dev->evbit)) @@ -114,22 +114,20 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, } if (!test_bit(effect->type, ff->ffbit)) { - ret = compat_effect(ff, effect); - if (ret) - return ret; + error = compat_effect(ff, effect); + if (error) + return error; } - mutex_lock(&ff->mutex); + guard(mutex)(&ff->mutex); if (effect->id == -1) { for (id = 0; id < ff->max_effects; id++) if (!ff->effect_owners[id]) break; - if (id >= ff->max_effects) { - ret = -ENOSPC; - goto out; - } + if (id >= ff->max_effects) + return -ENOSPC; effect->id = id; old = NULL; @@ -137,30 +135,26 @@ int input_ff_upload(struct input_dev *dev, struct ff_effect *effect, } else { id = effect->id; - ret = check_effect_access(ff, id, file); - if (ret) - goto out; + error = check_effect_access(ff, id, file); + if (error) + return error; old = &ff->effects[id]; - if (!check_effects_compatible(effect, old)) { - ret = -EINVAL; - goto out; - } + if (!check_effects_compatible(effect, old)) + return -EINVAL; } - ret = ff->upload(dev, effect, old); - if (ret) - goto out; + error = ff->upload(dev, effect, old); + if (error) + return error; - spin_lock_irq(&dev->event_lock); - ff->effects[id] = *effect; - ff->effect_owners[id] = file; - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) { + ff->effects[id] = *effect; + ff->effect_owners[id] = file; + } - out: - mutex_unlock(&ff->mutex); - return ret; + return 0; } EXPORT_SYMBOL_GPL(input_ff_upload); @@ -178,17 +172,16 @@ static int erase_effect(struct input_dev *dev, int effect_id, if (error) return error; - spin_lock_irq(&dev->event_lock); - ff->playback(dev, effect_id, 0); - ff->effect_owners[effect_id] = NULL; - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) { + ff->playback(dev, effect_id, 0); + ff->effect_owners[effect_id] = NULL; + } if (ff->erase) { error = ff->erase(dev, effect_id); if (error) { - spin_lock_irq(&dev->event_lock); - ff->effect_owners[effect_id] = file; - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) + ff->effect_owners[effect_id] = file; return error; } @@ -210,16 +203,12 @@ static int erase_effect(struct input_dev *dev, int effect_id, int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file) { struct ff_device *ff = dev->ff; - int ret; if (!test_bit(EV_FF, dev->evbit)) return -ENOSYS; - mutex_lock(&ff->mutex); - ret = erase_effect(dev, effect_id, file); - mutex_unlock(&ff->mutex); - - return ret; + guard(mutex)(&ff->mutex); + return erase_effect(dev, effect_id, file); } EXPORT_SYMBOL_GPL(input_ff_erase); @@ -239,13 +228,11 @@ int input_ff_flush(struct input_dev *dev, struct file *file) dev_dbg(&dev->dev, "flushing now\n"); - mutex_lock(&ff->mutex); + guard(mutex)(&ff->mutex); for (i = 0; i < ff->max_effects; i++) erase_effect(dev, i, file); - mutex_unlock(&ff->mutex); - return 0; } EXPORT_SYMBOL_GPL(input_ff_flush); -- 2.47.0.277.g8800431eea-goog ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 1/8] Input: ff-core - convert locking to guard notation Dmitry Torokhov @ 2024-11-07 7:15 ` Dmitry Torokhov [not found] ` <CGME20241220123701eucas1p23125e0738985ffe35cbe9624dff08972@eucas1p2.samsung.com> 2024-11-07 7:15 ` [PATCH 3/8] Input: ff-memless - convert locking to guard notation Dmitry Torokhov ` (6 subsequent siblings) 8 siblings, 1 reply; 15+ messages in thread From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel Annotate allocated memory with __free(kfree) to simplify the code and make sure memory is released appropriately. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/ff-core.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index eb01bcb69d00..a235d2eb6b31 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -290,8 +290,6 @@ EXPORT_SYMBOL_GPL(input_ff_event); */ int input_ff_create(struct input_dev *dev, unsigned int max_effects) { - struct ff_device *ff; - size_t ff_dev_size; int i; if (!max_effects) { @@ -304,25 +302,20 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) return -EINVAL; } - ff_dev_size = struct_size(ff, effect_owners, max_effects); - if (ff_dev_size == SIZE_MAX) /* overflow */ - return -EINVAL; - - ff = kzalloc(ff_dev_size, GFP_KERNEL); + struct ff_device *ff __free(kfree) = + kzalloc(struct_size(ff, effect_owners, max_effects), + GFP_KERNEL); if (!ff) return -ENOMEM; - ff->effects = kcalloc(max_effects, sizeof(struct ff_effect), - GFP_KERNEL); - if (!ff->effects) { - kfree(ff); + ff->effects = kcalloc(max_effects, sizeof(*ff->effects), GFP_KERNEL); + if (!ff->effects) return -ENOMEM; - } ff->max_effects = max_effects; mutex_init(&ff->mutex); - dev->ff = ff; + dev->ff = no_free_ptr(ff); dev->flush = input_ff_flush; dev->event = input_ff_event; __set_bit(EV_FF, dev->evbit); -- 2.47.0.277.g8800431eea-goog ^ permalink raw reply related [flat|nested] 15+ messages in thread
[parent not found: <CGME20241220123701eucas1p23125e0738985ffe35cbe9624dff08972@eucas1p2.samsung.com>]
* Re: [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility [not found] ` <CGME20241220123701eucas1p23125e0738985ffe35cbe9624dff08972@eucas1p2.samsung.com> @ 2024-12-20 12:36 ` Marek Szyprowski 2024-12-20 17:22 ` Dmitry Torokhov 0 siblings, 1 reply; 15+ messages in thread From: Marek Szyprowski @ 2024-12-20 12:36 UTC (permalink / raw) To: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires, Hans de Goede Cc: linux-input, linux-kernel, 'Linux Samsung SOC' On 07.11.2024 08:15, Dmitry Torokhov wrote: > Annotate allocated memory with __free(kfree) to simplify the code and > make sure memory is released appropriately. > > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> > --- > drivers/input/ff-core.c | 19 ++++++------------- > 1 file changed, 6 insertions(+), 13 deletions(-) This patch landed in linux-next as commit 5203b3a18c1b ("Input: ff-core - make use of __free() cleanup facility"). In my tests I found that it causes the following kernel panic on some of my test boards. Reverting it, together with fd5ba0501d38 ("Input: ff-memless - make use of __free() cleanup facility") on top of next-20241220 fixes this panic issue. Here is the relevant log captured on Samsung Exynos4412 ARM 32bit-based Trats2 board: 8<--- cut here --- Unable to handle kernel NULL pointer dereference at virtual address 00000024 when read [00000024] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP ARM Modules linked in: CPU: 1 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.13.0-rc3-next-20241220 #15500 Hardware name: Samsung Exynos (Flattened Device Tree) PC is at input_ff_create+0xa0/0x13c LR is at input_ff_create+0xb8/0x13c pc : [<c08d7e14>] lr : [<c08d7e2c>] psr: 80000013 ... Process swapper/0 (pid: 1, stack limit = 0x(ptrval)) ... Call trace: input_ff_create from input_ff_create_memless+0x8c/0x160 input_ff_create_memless from max77693_haptic_probe+0x1b0/0x284 max77693_haptic_probe from platform_probe+0x80/0xc0 platform_probe from really_probe+0x154/0x3ac really_probe from __driver_probe_device+0xa0/0x1d4 __driver_probe_device from driver_probe_device+0x30/0xd0 driver_probe_device from __driver_attach+0x10c/0x190 __driver_attach from bus_for_each_dev+0x60/0xb4 bus_for_each_dev from bus_add_driver+0xe0/0x220 bus_add_driver from driver_register+0x7c/0x118 driver_register from do_one_initcall+0x6c/0x328 do_one_initcall from kernel_init_freeable+0x1c8/0x218 kernel_init_freeable from kernel_init+0x1c/0x12c kernel_init from ret_from_fork+0x14/0x28 Exception stack(0xf0845fb0 to 0xf0845ff8) ... ---[ end trace 0000000000000000 ]--- Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b ]--- > diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c > index eb01bcb69d00..a235d2eb6b31 100644 > --- a/drivers/input/ff-core.c > +++ b/drivers/input/ff-core.c > @@ -290,8 +290,6 @@ EXPORT_SYMBOL_GPL(input_ff_event); > */ > int input_ff_create(struct input_dev *dev, unsigned int max_effects) > { > - struct ff_device *ff; > - size_t ff_dev_size; > int i; > > if (!max_effects) { > @@ -304,25 +302,20 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) > return -EINVAL; > } > > - ff_dev_size = struct_size(ff, effect_owners, max_effects); > - if (ff_dev_size == SIZE_MAX) /* overflow */ > - return -EINVAL; > - > - ff = kzalloc(ff_dev_size, GFP_KERNEL); > + struct ff_device *ff __free(kfree) = > + kzalloc(struct_size(ff, effect_owners, max_effects), > + GFP_KERNEL); > if (!ff) > return -ENOMEM; > > - ff->effects = kcalloc(max_effects, sizeof(struct ff_effect), > - GFP_KERNEL); > - if (!ff->effects) { > - kfree(ff); > + ff->effects = kcalloc(max_effects, sizeof(*ff->effects), GFP_KERNEL); > + if (!ff->effects) > return -ENOMEM; > - } > > ff->max_effects = max_effects; > mutex_init(&ff->mutex); > > - dev->ff = ff; > + dev->ff = no_free_ptr(ff); > dev->flush = input_ff_flush; > dev->event = input_ff_event; > __set_bit(EV_FF, dev->evbit); Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility 2024-12-20 12:36 ` Marek Szyprowski @ 2024-12-20 17:22 ` Dmitry Torokhov 2024-12-20 17:38 ` Marek Szyprowski 0 siblings, 1 reply; 15+ messages in thread From: Dmitry Torokhov @ 2024-12-20 17:22 UTC (permalink / raw) To: Marek Szyprowski Cc: Jiri Kosina, Benjamin Tissoires, Hans de Goede, linux-input, linux-kernel, 'Linux Samsung SOC' On Fri, Dec 20, 2024 at 01:36:59PM +0100, Marek Szyprowski wrote: > On 07.11.2024 08:15, Dmitry Torokhov wrote: > > Annotate allocated memory with __free(kfree) to simplify the code and > > make sure memory is released appropriately. > > > > Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> > > --- > > drivers/input/ff-core.c | 19 ++++++------------- > > 1 file changed, 6 insertions(+), 13 deletions(-) > > This patch landed in linux-next as commit 5203b3a18c1b ("Input: ff-core > - make use of __free() cleanup facility"). In my tests I found that it > causes the following kernel panic on some of my test boards. Reverting > it, together with fd5ba0501d38 ("Input: ff-memless - make use of > __free() cleanup facility") on top of next-20241220 fixes this panic > issue. Gah, I fixed this once and then undid it for some reason. I think the following should fix the problem: diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index a235d2eb6b31..c25e05eeb8e5 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -315,7 +315,6 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) ff->max_effects = max_effects; mutex_init(&ff->mutex); - dev->ff = no_free_ptr(ff); dev->flush = input_ff_flush; dev->event = input_ff_event; __set_bit(EV_FF, dev->evbit); @@ -328,6 +327,7 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) if (test_bit(FF_PERIODIC, ff->ffbit)) __set_bit(FF_RUMBLE, dev->ffbit); + dev->ff = no_free_ptr(ff); return 0; } EXPORT_SYMBOL_GPL(input_ff_create); diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index 0bbeceb35545..e9120ba6bae0 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -524,7 +524,6 @@ int input_ff_create_memless(struct input_dev *dev, void *data, return error; ff = dev->ff; - ff->private = no_free_ptr(ml); ff->upload = ml_ff_upload; ff->playback = ml_ff_playback; ff->set_gain = ml_ff_set_gain; @@ -541,6 +540,8 @@ int input_ff_create_memless(struct input_dev *dev, void *data, for (i = 0; i < FF_MEMLESS_EFFECTS; i++) ml->states[i].effect = &ff->effects[i]; + ff->private = no_free_ptr(ml); + return 0; } EXPORT_SYMBOL_GPL(input_ff_create_memless); Thanks. -- Dmitry ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility 2024-12-20 17:22 ` Dmitry Torokhov @ 2024-12-20 17:38 ` Marek Szyprowski 2024-12-20 17:39 ` Dmitry Torokhov 0 siblings, 1 reply; 15+ messages in thread From: Marek Szyprowski @ 2024-12-20 17:38 UTC (permalink / raw) To: Dmitry Torokhov Cc: Jiri Kosina, Benjamin Tissoires, Hans de Goede, linux-input, linux-kernel, 'Linux Samsung SOC' On 20.12.2024 18:22, Dmitry Torokhov wrote: > On Fri, Dec 20, 2024 at 01:36:59PM +0100, Marek Szyprowski wrote: >> On 07.11.2024 08:15, Dmitry Torokhov wrote: >>> Annotate allocated memory with __free(kfree) to simplify the code and >>> make sure memory is released appropriately. >>> >>> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> >>> --- >>> drivers/input/ff-core.c | 19 ++++++------------- >>> 1 file changed, 6 insertions(+), 13 deletions(-) >> This patch landed in linux-next as commit 5203b3a18c1b ("Input: ff-core >> - make use of __free() cleanup facility"). In my tests I found that it >> causes the following kernel panic on some of my test boards. Reverting >> it, together with fd5ba0501d38 ("Input: ff-memless - make use of >> __free() cleanup facility") on top of next-20241220 fixes this panic >> issue. > Gah, I fixed this once and then undid it for some reason. I think the > following should fix the problem: Yep, this fixes the problem. Feel free to add: Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> > diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c > index a235d2eb6b31..c25e05eeb8e5 100644 > --- a/drivers/input/ff-core.c > +++ b/drivers/input/ff-core.c > @@ -315,7 +315,6 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) > ff->max_effects = max_effects; > mutex_init(&ff->mutex); > > - dev->ff = no_free_ptr(ff); > dev->flush = input_ff_flush; > dev->event = input_ff_event; > __set_bit(EV_FF, dev->evbit); > @@ -328,6 +327,7 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) > if (test_bit(FF_PERIODIC, ff->ffbit)) > __set_bit(FF_RUMBLE, dev->ffbit); > > + dev->ff = no_free_ptr(ff); > return 0; > } > EXPORT_SYMBOL_GPL(input_ff_create); > diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c > index 0bbeceb35545..e9120ba6bae0 100644 > --- a/drivers/input/ff-memless.c > +++ b/drivers/input/ff-memless.c > @@ -524,7 +524,6 @@ int input_ff_create_memless(struct input_dev *dev, void *data, > return error; > > ff = dev->ff; > - ff->private = no_free_ptr(ml); > ff->upload = ml_ff_upload; > ff->playback = ml_ff_playback; > ff->set_gain = ml_ff_set_gain; > @@ -541,6 +540,8 @@ int input_ff_create_memless(struct input_dev *dev, void *data, > for (i = 0; i < FF_MEMLESS_EFFECTS; i++) > ml->states[i].effect = &ff->effects[i]; > > + ff->private = no_free_ptr(ml); > + > return 0; > } > EXPORT_SYMBOL_GPL(input_ff_create_memless); > > > Thanks. > Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility 2024-12-20 17:38 ` Marek Szyprowski @ 2024-12-20 17:39 ` Dmitry Torokhov 2024-12-20 17:50 ` Marek Szyprowski 0 siblings, 1 reply; 15+ messages in thread From: Dmitry Torokhov @ 2024-12-20 17:39 UTC (permalink / raw) To: Marek Szyprowski Cc: Jiri Kosina, Benjamin Tissoires, Hans de Goede, linux-input, linux-kernel, 'Linux Samsung SOC' On Fri, Dec 20, 2024 at 06:38:04PM +0100, Marek Szyprowski wrote: > On 20.12.2024 18:22, Dmitry Torokhov wrote: > > On Fri, Dec 20, 2024 at 01:36:59PM +0100, Marek Szyprowski wrote: > >> On 07.11.2024 08:15, Dmitry Torokhov wrote: > >>> Annotate allocated memory with __free(kfree) to simplify the code and > >>> make sure memory is released appropriately. > >>> > >>> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> > >>> --- > >>> drivers/input/ff-core.c | 19 ++++++------------- > >>> 1 file changed, 6 insertions(+), 13 deletions(-) > >> This patch landed in linux-next as commit 5203b3a18c1b ("Input: ff-core > >> - make use of __free() cleanup facility"). In my tests I found that it > >> causes the following kernel panic on some of my test boards. Reverting > >> it, together with fd5ba0501d38 ("Input: ff-memless - make use of > >> __free() cleanup facility") on top of next-20241220 fixes this panic > >> issue. > > Gah, I fixed this once and then undid it for some reason. I think the > > following should fix the problem: > > Yep, this fixes the problem. Feel free to add: > > Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> > Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> Thank you for the report and testing. Do you mind if I fold these fixes into original patches? Thanks. -- Dmitry ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility 2024-12-20 17:39 ` Dmitry Torokhov @ 2024-12-20 17:50 ` Marek Szyprowski 0 siblings, 0 replies; 15+ messages in thread From: Marek Szyprowski @ 2024-12-20 17:50 UTC (permalink / raw) To: Dmitry Torokhov Cc: Jiri Kosina, Benjamin Tissoires, Hans de Goede, linux-input, linux-kernel, 'Linux Samsung SOC' On 20.12.2024 18:39, Dmitry Torokhov wrote: > On Fri, Dec 20, 2024 at 06:38:04PM +0100, Marek Szyprowski wrote: >> On 20.12.2024 18:22, Dmitry Torokhov wrote: >>> On Fri, Dec 20, 2024 at 01:36:59PM +0100, Marek Szyprowski wrote: >>>> On 07.11.2024 08:15, Dmitry Torokhov wrote: >>>>> Annotate allocated memory with __free(kfree) to simplify the code and >>>>> make sure memory is released appropriately. >>>>> >>>>> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> >>>>> --- >>>>> drivers/input/ff-core.c | 19 ++++++------------- >>>>> 1 file changed, 6 insertions(+), 13 deletions(-) >>>> This patch landed in linux-next as commit 5203b3a18c1b ("Input: ff-core >>>> - make use of __free() cleanup facility"). In my tests I found that it >>>> causes the following kernel panic on some of my test boards. Reverting >>>> it, together with fd5ba0501d38 ("Input: ff-memless - make use of >>>> __free() cleanup facility") on top of next-20241220 fixes this panic >>>> issue. >>> Gah, I fixed this once and then undid it for some reason. I think the >>> following should fix the problem: >> Yep, this fixes the problem. Feel free to add: >> >> Reported-by: Marek Szyprowski <m.szyprowski@samsung.com> >> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com> > Thank you for the report and testing. Do you mind if I fold these fixes > into original patches? Go ahead, no problem for me. Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 3/8] Input: ff-memless - convert locking to guard notation 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 1/8] Input: ff-core - convert locking to guard notation Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility Dmitry Torokhov @ 2024-11-07 7:15 ` Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 4/8] Input: ff-memless - make use of __free() cleanup facility Dmitry Torokhov ` (5 subsequent siblings) 8 siblings, 0 replies; 15+ messages in thread From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel Use guard() notation instead of explicitly acquiring and releasing spinlocks to simplify the code and ensure that all locks are released. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/ff-memless.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index c321cdabd214..ec99c070a97c 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -401,13 +401,11 @@ static void ml_effect_timer(struct timer_list *t) { struct ml_device *ml = from_timer(ml, t, timer); struct input_dev *dev = ml->dev; - unsigned long flags; pr_debug("timer: updating effects\n"); - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); ml_play_effects(ml); - spin_unlock_irqrestore(&dev->event_lock, flags); } /* @@ -465,7 +463,7 @@ static int ml_ff_upload(struct input_dev *dev, struct ml_device *ml = dev->ff->private; struct ml_effect_state *state = &ml->states[effect->id]; - spin_lock_irq(&dev->event_lock); + guard(spinlock_irq)(&dev->event_lock); if (test_bit(FF_EFFECT_STARTED, &state->flags)) { __clear_bit(FF_EFFECT_PLAYING, &state->flags); @@ -477,8 +475,6 @@ static int ml_ff_upload(struct input_dev *dev, ml_schedule_timer(ml); } - spin_unlock_irq(&dev->event_lock); - return 0; } -- 2.47.0.277.g8800431eea-goog ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 4/8] Input: ff-memless - make use of __free() cleanup facility 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov ` (2 preceding siblings ...) 2024-11-07 7:15 ` [PATCH 3/8] Input: ff-memless - convert locking to guard notation Dmitry Torokhov @ 2024-11-07 7:15 ` Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 5/8] Input: mt - convert locking to guard notation Dmitry Torokhov ` (4 subsequent siblings) 8 siblings, 0 replies; 15+ messages in thread From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel Annotate allocated memory with __free(kfree) to simplify the code and make sure memory is released appropriately. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/ff-memless.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index ec99c070a97c..0bbeceb35545 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -503,12 +503,11 @@ static void ml_ff_destroy(struct ff_device *ff) int input_ff_create_memless(struct input_dev *dev, void *data, int (*play_effect)(struct input_dev *, void *, struct ff_effect *)) { - struct ml_device *ml; struct ff_device *ff; int error; int i; - ml = kzalloc(sizeof(struct ml_device), GFP_KERNEL); + struct ml_device *ml __free(kfree) = kzalloc(sizeof(*ml), GFP_KERNEL); if (!ml) return -ENOMEM; @@ -521,13 +520,11 @@ int input_ff_create_memless(struct input_dev *dev, void *data, set_bit(FF_GAIN, dev->ffbit); error = input_ff_create(dev, FF_MEMLESS_EFFECTS); - if (error) { - kfree(ml); + if (error) return error; - } ff = dev->ff; - ff->private = ml; + ff->private = no_free_ptr(ml); ff->upload = ml_ff_upload; ff->playback = ml_ff_playback; ff->set_gain = ml_ff_set_gain; -- 2.47.0.277.g8800431eea-goog ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 5/8] Input: mt - convert locking to guard notation 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov ` (3 preceding siblings ...) 2024-11-07 7:15 ` [PATCH 4/8] Input: ff-memless - make use of __free() cleanup facility Dmitry Torokhov @ 2024-11-07 7:15 ` Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 6/8] Input: mt - make use of __free() cleanup facility Dmitry Torokhov ` (3 subsequent siblings) 8 siblings, 0 replies; 15+ messages in thread From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel Use guard() notation instead of explicitly acquiring and releasing spinlocks to simplify the code and ensure that all locks are released. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/input-mt.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 6b04a674f832..45e41fc9059c 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -285,14 +285,10 @@ void input_mt_drop_unused(struct input_dev *dev) struct input_mt *mt = dev->mt; if (mt) { - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); __input_mt_drop_unused(dev, mt); mt->frame++; - - spin_unlock_irqrestore(&dev->event_lock, flags); } } EXPORT_SYMBOL(input_mt_drop_unused); @@ -339,11 +335,8 @@ void input_mt_sync_frame(struct input_dev *dev) return; if (mt->flags & INPUT_MT_DROP_UNUSED) { - unsigned long flags; - - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); __input_mt_drop_unused(dev, mt); - spin_unlock_irqrestore(&dev->event_lock, flags); } if ((mt->flags & INPUT_MT_POINTER) && !(mt->flags & INPUT_MT_SEMI_MT)) -- 2.47.0.277.g8800431eea-goog ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 6/8] Input: mt - make use of __free() cleanup facility 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov ` (4 preceding siblings ...) 2024-11-07 7:15 ` [PATCH 5/8] Input: mt - convert locking to guard notation Dmitry Torokhov @ 2024-11-07 7:15 ` Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 7/8] Input: poller - convert locking to guard notation Dmitry Torokhov ` (2 subsequent siblings) 8 siblings, 0 replies; 15+ messages in thread From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel Annotate allocated memory with __free(kfree) to simplify the code and make sure memory is released appropriately. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/input-mt.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 45e41fc9059c..337006dd9dcf 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -39,20 +39,20 @@ static void copy_abs(struct input_dev *dev, unsigned int dst, unsigned int src) int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, unsigned int flags) { - struct input_mt *mt = dev->mt; - int i; - if (!num_slots) return 0; - if (mt) - return mt->num_slots != num_slots ? -EINVAL : 0; + + if (dev->mt) + return dev->mt->num_slots != num_slots ? -EINVAL : 0; + /* Arbitrary limit for avoiding too large memory allocation. */ if (num_slots > 1024) return -EINVAL; - mt = kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); + struct input_mt *mt __free(kfree) = + kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); if (!mt) - goto err_mem; + return -ENOMEM; mt->num_slots = num_slots; mt->flags = flags; @@ -86,21 +86,18 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, unsigned int n2 = num_slots * num_slots; mt->red = kcalloc(n2, sizeof(*mt->red), GFP_KERNEL); if (!mt->red) - goto err_mem; + return -ENOMEM; } /* Mark slots as 'inactive' */ - for (i = 0; i < num_slots; i++) + for (unsigned int i = 0; i < num_slots; i++) input_mt_set_value(&mt->slots[i], ABS_MT_TRACKING_ID, -1); /* Mark slots as 'unused' */ mt->frame = 1; - dev->mt = mt; + dev->mt = no_free_ptr(mt); return 0; -err_mem: - kfree(mt); - return -ENOMEM; } EXPORT_SYMBOL(input_mt_init_slots); -- 2.47.0.277.g8800431eea-goog ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 7/8] Input: poller - convert locking to guard notation 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov ` (5 preceding siblings ...) 2024-11-07 7:15 ` [PATCH 6/8] Input: mt - make use of __free() cleanup facility Dmitry Torokhov @ 2024-11-07 7:15 ` Dmitry Torokhov 2024-11-07 7:15 ` [PATCH 8/8] Input: use guard notation in input core Dmitry Torokhov 2024-12-17 21:59 ` [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov 8 siblings, 0 replies; 15+ messages in thread From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel Use guard() notation instead of explicitly acquiring and releasing mutex to simplify the code and ensure that it is released. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/input-poller.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/input/input-poller.c b/drivers/input/input-poller.c index 688e3cb1c2a0..9c57713a6151 100644 --- a/drivers/input/input-poller.c +++ b/drivers/input/input-poller.c @@ -162,7 +162,7 @@ static ssize_t input_dev_set_poll_interval(struct device *dev, if (interval > poller->poll_interval_max) return -EINVAL; - mutex_lock(&input->mutex); + guard(mutex)(&input->mutex); poller->poll_interval = interval; @@ -172,8 +172,6 @@ static ssize_t input_dev_set_poll_interval(struct device *dev, input_dev_poller_queue_work(poller); } - mutex_unlock(&input->mutex); - return count; } -- 2.47.0.277.g8800431eea-goog ^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH 8/8] Input: use guard notation in input core 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov ` (6 preceding siblings ...) 2024-11-07 7:15 ` [PATCH 7/8] Input: poller - convert locking to guard notation Dmitry Torokhov @ 2024-11-07 7:15 ` Dmitry Torokhov 2024-12-17 21:59 ` [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov 8 siblings, 0 replies; 15+ messages in thread From: Dmitry Torokhov @ 2024-11-07 7:15 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel Switch input core to use "guard" notation when acquiring spinlocks and mutexes to simplify the code and ensure that locks are automatically released when control leaves critical section. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> --- drivers/input/input.c | 339 ++++++++++++++++-------------------------- 1 file changed, 131 insertions(+), 208 deletions(-) diff --git a/drivers/input/input.c b/drivers/input/input.c index fd9d40286b75..d73231e695f8 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -115,23 +115,23 @@ static void input_pass_values(struct input_dev *dev, lockdep_assert_held(&dev->event_lock); - rcu_read_lock(); + scoped_guard(rcu) { + handle = rcu_dereference(dev->grab); + if (handle) { + count = handle->handle_events(handle, vals, count); + break; + } - handle = rcu_dereference(dev->grab); - if (handle) { - count = handle->handle_events(handle, vals, count); - } else { - list_for_each_entry_rcu(handle, &dev->h_list, d_node) + list_for_each_entry_rcu(handle, &dev->h_list, d_node) { if (handle->open) { count = handle->handle_events(handle, vals, count); if (!count) break; } + } } - rcu_read_unlock(); - /* trigger auto repeat for key events */ if (test_bit(EV_REP, dev->evbit) && test_bit(EV_KEY, dev->evbit)) { for (v = vals; v != vals + count; v++) { @@ -390,13 +390,9 @@ void input_handle_event(struct input_dev *dev, void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { - unsigned long flags; - if (is_event_supported(type, dev->evbit, EV_MAX)) { - - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); input_handle_event(dev, type, code, value); - spin_unlock_irqrestore(&dev->event_lock, flags); } } EXPORT_SYMBOL(input_event); @@ -417,18 +413,15 @@ void input_inject_event(struct input_handle *handle, { struct input_dev *dev = handle->dev; struct input_handle *grab; - unsigned long flags; if (is_event_supported(type, dev->evbit, EV_MAX)) { - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); + guard(rcu)(); - rcu_read_lock(); grab = rcu_dereference(dev->grab); if (!grab || grab == handle) input_handle_event(dev, type, code, value); - rcu_read_unlock(); - spin_unlock_irqrestore(&dev->event_lock, flags); } } EXPORT_SYMBOL(input_inject_event); @@ -526,22 +519,15 @@ EXPORT_SYMBOL(input_copy_abs); int input_grab_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; - int retval; - retval = mutex_lock_interruptible(&dev->mutex); - if (retval) - return retval; + scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) { + if (dev->grab) + return -EBUSY; - if (dev->grab) { - retval = -EBUSY; - goto out; + rcu_assign_pointer(dev->grab, handle); } - rcu_assign_pointer(dev->grab, handle); - - out: - mutex_unlock(&dev->mutex); - return retval; + return 0; } EXPORT_SYMBOL(input_grab_device); @@ -576,9 +562,8 @@ void input_release_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; - mutex_lock(&dev->mutex); + guard(mutex)(&dev->mutex); __input_release_device(handle); - mutex_unlock(&dev->mutex); } EXPORT_SYMBOL(input_release_device); @@ -592,67 +577,57 @@ EXPORT_SYMBOL(input_release_device); int input_open_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; - int retval; - - retval = mutex_lock_interruptible(&dev->mutex); - if (retval) - return retval; - - if (dev->going_away) { - retval = -ENODEV; - goto out; - } + int error; - handle->open++; + scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) { + if (dev->going_away) + return -ENODEV; - if (handle->handler->passive_observer) - goto out; + handle->open++; - if (dev->users++ || dev->inhibited) { - /* - * Device is already opened and/or inhibited, - * so we can exit immediately and report success. - */ - goto out; - } + if (handle->handler->passive_observer) + return 0; - if (dev->open) { - retval = dev->open(dev); - if (retval) { - dev->users--; - handle->open--; + if (dev->users++ || dev->inhibited) { /* - * Make sure we are not delivering any more events - * through this handle + * Device is already opened and/or inhibited, + * so we can exit immediately and report success. */ - synchronize_rcu(); - goto out; + return 0; } - } - if (dev->poller) - input_dev_poller_start(dev->poller); + if (dev->open) { + error = dev->open(dev); + if (error) { + dev->users--; + handle->open--; + /* + * Make sure we are not delivering any more + * events through this handle. + */ + synchronize_rcu(); + return error; + } + } - out: - mutex_unlock(&dev->mutex); - return retval; + if (dev->poller) + input_dev_poller_start(dev->poller); + } + + return 0; } EXPORT_SYMBOL(input_open_device); int input_flush_device(struct input_handle *handle, struct file *file) { struct input_dev *dev = handle->dev; - int retval; - retval = mutex_lock_interruptible(&dev->mutex); - if (retval) - return retval; - - if (dev->flush) - retval = dev->flush(dev, file); + scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) { + if (dev->flush) + return dev->flush(dev, file); + } - mutex_unlock(&dev->mutex); - return retval; + return 0; } EXPORT_SYMBOL(input_flush_device); @@ -667,7 +642,7 @@ void input_close_device(struct input_handle *handle) { struct input_dev *dev = handle->dev; - mutex_lock(&dev->mutex); + guard(mutex)(&dev->mutex); __input_release_device(handle); @@ -688,8 +663,6 @@ void input_close_device(struct input_handle *handle) */ synchronize_rcu(); } - - mutex_unlock(&dev->mutex); } EXPORT_SYMBOL(input_close_device); @@ -726,11 +699,10 @@ static void input_disconnect_device(struct input_dev *dev) * not to protect access to dev->going_away but rather to ensure * that there are no threads in the middle of input_open_device() */ - mutex_lock(&dev->mutex); - dev->going_away = true; - mutex_unlock(&dev->mutex); + scoped_guard(mutex, &dev->mutex) + dev->going_away = true; - spin_lock_irq(&dev->event_lock); + guard(spinlock_irq)(&dev->event_lock); /* * Simulate keyup events for all pressed keys so that handlers @@ -743,8 +715,6 @@ static void input_disconnect_device(struct input_dev *dev) list_for_each_entry(handle, &dev->h_list, d_node) handle->open = 0; - - spin_unlock_irq(&dev->event_lock); } /** @@ -901,14 +871,9 @@ static int input_default_setkeycode(struct input_dev *dev, */ int input_get_keycode(struct input_dev *dev, struct input_keymap_entry *ke) { - unsigned long flags; - int retval; + guard(spinlock_irqsave)(&dev->event_lock); - spin_lock_irqsave(&dev->event_lock, flags); - retval = dev->getkeycode(dev, ke); - spin_unlock_irqrestore(&dev->event_lock, flags); - - return retval; + return dev->getkeycode(dev, ke); } EXPORT_SYMBOL(input_get_keycode); @@ -923,18 +888,17 @@ EXPORT_SYMBOL(input_get_keycode); int input_set_keycode(struct input_dev *dev, const struct input_keymap_entry *ke) { - unsigned long flags; unsigned int old_keycode; - int retval; + int error; if (ke->keycode > KEY_MAX) return -EINVAL; - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); - retval = dev->setkeycode(dev, ke, &old_keycode); - if (retval) - goto out; + error = dev->setkeycode(dev, ke, &old_keycode); + if (error) + return error; /* Make sure KEY_RESERVED did not get enabled. */ __clear_bit(KEY_RESERVED, dev->keybit); @@ -962,10 +926,7 @@ int input_set_keycode(struct input_dev *dev, EV_SYN, SYN_REPORT, 1); } - out: - spin_unlock_irqrestore(&dev->event_lock, flags); - - return retval; + return 0; } EXPORT_SYMBOL(input_set_keycode); @@ -1802,26 +1763,21 @@ static void input_dev_toggle(struct input_dev *dev, bool activate) */ void input_reset_device(struct input_dev *dev) { - unsigned long flags; - - mutex_lock(&dev->mutex); - spin_lock_irqsave(&dev->event_lock, flags); + guard(mutex)(&dev->mutex); + guard(spinlock_irqsave)(&dev->event_lock); input_dev_toggle(dev, true); if (input_dev_release_keys(dev)) input_handle_event(dev, EV_SYN, SYN_REPORT, 1); - - spin_unlock_irqrestore(&dev->event_lock, flags); - mutex_unlock(&dev->mutex); } EXPORT_SYMBOL(input_reset_device); static int input_inhibit_device(struct input_dev *dev) { - mutex_lock(&dev->mutex); + guard(mutex)(&dev->mutex); if (dev->inhibited) - goto out; + return 0; if (dev->users) { if (dev->close) @@ -1830,54 +1786,50 @@ static int input_inhibit_device(struct input_dev *dev) input_dev_poller_stop(dev->poller); } - spin_lock_irq(&dev->event_lock); - input_mt_release_slots(dev); - input_dev_release_keys(dev); - input_handle_event(dev, EV_SYN, SYN_REPORT, 1); - input_dev_toggle(dev, false); - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) { + input_mt_release_slots(dev); + input_dev_release_keys(dev); + input_handle_event(dev, EV_SYN, SYN_REPORT, 1); + input_dev_toggle(dev, false); + } dev->inhibited = true; -out: - mutex_unlock(&dev->mutex); return 0; } static int input_uninhibit_device(struct input_dev *dev) { - int ret = 0; + int error; - mutex_lock(&dev->mutex); + guard(mutex)(&dev->mutex); if (!dev->inhibited) - goto out; + return 0; if (dev->users) { if (dev->open) { - ret = dev->open(dev); - if (ret) - goto out; + error = dev->open(dev); + if (error) + return error; } if (dev->poller) input_dev_poller_start(dev->poller); } dev->inhibited = false; - spin_lock_irq(&dev->event_lock); - input_dev_toggle(dev, true); - spin_unlock_irq(&dev->event_lock); -out: - mutex_unlock(&dev->mutex); - return ret; + scoped_guard(spinlock_irq, &dev->event_lock) + input_dev_toggle(dev, true); + + return 0; } static int input_dev_suspend(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - spin_lock_irq(&input_dev->event_lock); + guard(spinlock_irq)(&input_dev->event_lock); /* * Keys that are pressed now are unlikely to be @@ -1889,8 +1841,6 @@ static int input_dev_suspend(struct device *dev) /* Turn off LEDs and sounds, if any are active. */ input_dev_toggle(input_dev, false); - spin_unlock_irq(&input_dev->event_lock); - return 0; } @@ -1898,13 +1848,11 @@ static int input_dev_resume(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - spin_lock_irq(&input_dev->event_lock); + guard(spinlock_irq)(&input_dev->event_lock); /* Restore state of LEDs and sounds, if any were active. */ input_dev_toggle(input_dev, true); - spin_unlock_irq(&input_dev->event_lock); - return 0; } @@ -1912,7 +1860,7 @@ static int input_dev_freeze(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - spin_lock_irq(&input_dev->event_lock); + guard(spinlock_irq)(&input_dev->event_lock); /* * Keys that are pressed now are unlikely to be @@ -1921,8 +1869,6 @@ static int input_dev_freeze(struct device *dev) if (input_dev_release_keys(input_dev)) input_handle_event(input_dev, EV_SYN, SYN_REPORT, 1); - spin_unlock_irq(&input_dev->event_lock); - return 0; } @@ -1930,13 +1876,11 @@ static int input_dev_poweroff(struct device *dev) { struct input_dev *input_dev = to_input_dev(dev); - spin_lock_irq(&input_dev->event_lock); + guard(spinlock_irq)(&input_dev->event_lock); /* Turn off LEDs and sounds, if any are active. */ input_dev_toggle(input_dev, false); - spin_unlock_irq(&input_dev->event_lock); - return 0; } @@ -2277,18 +2221,16 @@ static void __input_unregister_device(struct input_dev *dev) input_disconnect_device(dev); - mutex_lock(&input_mutex); - - list_for_each_entry_safe(handle, next, &dev->h_list, d_node) - handle->handler->disconnect(handle); - WARN_ON(!list_empty(&dev->h_list)); + scoped_guard(mutex, &input_mutex) { + list_for_each_entry_safe(handle, next, &dev->h_list, d_node) + handle->handler->disconnect(handle); + WARN_ON(!list_empty(&dev->h_list)); - del_timer_sync(&dev->timer); - list_del_init(&dev->node); + del_timer_sync(&dev->timer); + list_del_init(&dev->node); - input_wakeup_procfs_readers(); - - mutex_unlock(&input_mutex); + input_wakeup_procfs_readers(); + } device_del(&dev->dev); } @@ -2311,9 +2253,8 @@ static void devm_input_device_unregister(struct device *dev, void *res) static void input_repeat_key(struct timer_list *t) { struct input_dev *dev = from_timer(dev, t, timer); - unsigned long flags; - spin_lock_irqsave(&dev->event_lock, flags); + guard(spinlock_irqsave)(&dev->event_lock); if (!dev->inhibited && test_bit(dev->repeat_key, dev->key) && @@ -2327,8 +2268,6 @@ static void input_repeat_key(struct timer_list *t) mod_timer(&dev->timer, jiffies + msecs_to_jiffies(dev->rep[REP_PERIOD])); } - - spin_unlock_irqrestore(&dev->event_lock, flags); } /** @@ -2373,10 +2312,10 @@ static int input_device_tune_vals(struct input_dev *dev) if (!vals) return -ENOMEM; - spin_lock_irq(&dev->event_lock); - dev->max_vals = max_vals; - swap(dev->vals, vals); - spin_unlock_irq(&dev->event_lock); + scoped_guard(spinlock_irq, &dev->event_lock) { + dev->max_vals = max_vals; + swap(dev->vals, vals); + } /* Because of swap() above, this frees the old vals memory */ kfree(vals); @@ -2468,18 +2407,15 @@ int input_register_device(struct input_dev *dev) path ? path : "N/A"); kfree(path); - error = mutex_lock_interruptible(&input_mutex); - if (error) - goto err_device_del; + error = -EINTR; + scoped_cond_guard(mutex_intr, goto err_device_del, &input_mutex) { + list_add_tail(&dev->node, &input_dev_list); - list_add_tail(&dev->node, &input_dev_list); + list_for_each_entry(handler, &input_handler_list, node) + input_attach_handler(dev, handler); - list_for_each_entry(handler, &input_handler_list, node) - input_attach_handler(dev, handler); - - input_wakeup_procfs_readers(); - - mutex_unlock(&input_mutex); + input_wakeup_procfs_readers(); + } if (dev->devres_managed) { dev_dbg(dev->dev.parent, "%s: registering %s with devres.\n", @@ -2559,20 +2495,17 @@ int input_register_handler(struct input_handler *handler) if (error) return error; - INIT_LIST_HEAD(&handler->h_list); + scoped_cond_guard(mutex_intr, return -EINTR, &input_mutex) { + INIT_LIST_HEAD(&handler->h_list); - error = mutex_lock_interruptible(&input_mutex); - if (error) - return error; - - list_add_tail(&handler->node, &input_handler_list); + list_add_tail(&handler->node, &input_handler_list); - list_for_each_entry(dev, &input_dev_list, node) - input_attach_handler(dev, handler); + list_for_each_entry(dev, &input_dev_list, node) + input_attach_handler(dev, handler); - input_wakeup_procfs_readers(); + input_wakeup_procfs_readers(); + } - mutex_unlock(&input_mutex); return 0; } EXPORT_SYMBOL(input_register_handler); @@ -2588,7 +2521,7 @@ void input_unregister_handler(struct input_handler *handler) { struct input_handle *handle, *next; - mutex_lock(&input_mutex); + guard(mutex)(&input_mutex); list_for_each_entry_safe(handle, next, &handler->h_list, h_node) handler->disconnect(handle); @@ -2597,8 +2530,6 @@ void input_unregister_handler(struct input_handler *handler) list_del_init(&handler->node); input_wakeup_procfs_readers(); - - mutex_unlock(&input_mutex); } EXPORT_SYMBOL(input_unregister_handler); @@ -2618,19 +2549,17 @@ int input_handler_for_each_handle(struct input_handler *handler, void *data, int (*fn)(struct input_handle *, void *)) { struct input_handle *handle; - int retval = 0; + int retval; - rcu_read_lock(); + guard(rcu)(); list_for_each_entry_rcu(handle, &handler->h_list, h_node) { retval = fn(handle, data); if (retval) - break; + return retval; } - rcu_read_unlock(); - - return retval; + return 0; } EXPORT_SYMBOL(input_handler_for_each_handle); @@ -2718,27 +2647,22 @@ int input_register_handle(struct input_handle *handle) { struct input_handler *handler = handle->handler; struct input_dev *dev = handle->dev; - int error; input_handle_setup_event_handler(handle); /* * We take dev->mutex here to prevent race with * input_release_device(). */ - error = mutex_lock_interruptible(&dev->mutex); - if (error) - return error; - - /* - * Filters go to the head of the list, normal handlers - * to the tail. - */ - if (handler->filter) - list_add_rcu(&handle->d_node, &dev->h_list); - else - list_add_tail_rcu(&handle->d_node, &dev->h_list); - - mutex_unlock(&dev->mutex); + scoped_cond_guard(mutex_intr, return -EINTR, &dev->mutex) { + /* + * Filters go to the head of the list, normal handlers + * to the tail. + */ + if (handler->filter) + list_add_rcu(&handle->d_node, &dev->h_list); + else + list_add_tail_rcu(&handle->d_node, &dev->h_list); + } /* * Since we are supposed to be called from ->connect() @@ -2774,9 +2698,8 @@ void input_unregister_handle(struct input_handle *handle) /* * Take dev->mutex to prevent race with input_release_device(). */ - mutex_lock(&dev->mutex); - list_del_rcu(&handle->d_node); - mutex_unlock(&dev->mutex); + scoped_guard(mutex, &dev->mutex) + list_del_rcu(&handle->d_node); synchronize_rcu(); } -- 2.47.0.277.g8800431eea-goog ^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH 0/8] Convert input core to use new cleanup facilities 2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov ` (7 preceding siblings ...) 2024-11-07 7:15 ` [PATCH 8/8] Input: use guard notation in input core Dmitry Torokhov @ 2024-12-17 21:59 ` Dmitry Torokhov 8 siblings, 0 replies; 15+ messages in thread From: Dmitry Torokhov @ 2024-12-17 21:59 UTC (permalink / raw) To: Jiri Kosina, Benjamin Tissoires, Hans de Goede; +Cc: linux-input, linux-kernel On Wed, Nov 06, 2024 at 11:15:27PM -0800, Dmitry Torokhov wrote: > Hi, > > This series converts input core (but not input handlers such as evdev, > joydev, etc) to use new __free() and guard() cleanup facilities that > simplify the code and ensure that all resources are released > appropriately. > > Input handlers will be converted separately later. Since there were no objections applied for the 6.14 merge window. Thanks. -- Dmitry ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2024-12-20 17:50 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-07 7:15 [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov
2024-11-07 7:15 ` [PATCH 1/8] Input: ff-core - convert locking to guard notation Dmitry Torokhov
2024-11-07 7:15 ` [PATCH 2/8] Input: ff-core - make use of __free() cleanup facility Dmitry Torokhov
[not found] ` <CGME20241220123701eucas1p23125e0738985ffe35cbe9624dff08972@eucas1p2.samsung.com>
2024-12-20 12:36 ` Marek Szyprowski
2024-12-20 17:22 ` Dmitry Torokhov
2024-12-20 17:38 ` Marek Szyprowski
2024-12-20 17:39 ` Dmitry Torokhov
2024-12-20 17:50 ` Marek Szyprowski
2024-11-07 7:15 ` [PATCH 3/8] Input: ff-memless - convert locking to guard notation Dmitry Torokhov
2024-11-07 7:15 ` [PATCH 4/8] Input: ff-memless - make use of __free() cleanup facility Dmitry Torokhov
2024-11-07 7:15 ` [PATCH 5/8] Input: mt - convert locking to guard notation Dmitry Torokhov
2024-11-07 7:15 ` [PATCH 6/8] Input: mt - make use of __free() cleanup facility Dmitry Torokhov
2024-11-07 7:15 ` [PATCH 7/8] Input: poller - convert locking to guard notation Dmitry Torokhov
2024-11-07 7:15 ` [PATCH 8/8] Input: use guard notation in input core Dmitry Torokhov
2024-12-17 21:59 ` [PATCH 0/8] Convert input core to use new cleanup facilities Dmitry Torokhov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).