All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: Gideon Heinz <gideonheinz02@gmail.com>
Cc: "Jiri Kosina" <jikos@kernel.org>,
	"Benjamin Tissoires" <bentiss@kernel.org>,
	"Filipe Laíns" <lains@riseup.net>,
	"Bastien Nocera" <hadess@hadess.net>,
	"Hans de Goede" <hansg@kernel.org>,
	"Edwin Velds" <e.velds@gmail.com>,
	"Stuart Hayhurst" <stuart.a.hayhurst@gmail.com>,
	"Andrey Smirnov" <andrew.smirnov@gmail.com>,
	linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org
Subject: Re: [PATCH v2 00/33] HID: logitech-hidpp: G920 force-feedback fixes, rework, and cleanups
Date: Wed, 11 Nov 2026 18:43:26 -0800	[thread overview]
Message-ID: <2f722967b6db0692d4dd4164aff39b62@gmail.com> (raw)
In-Reply-To: <CAPb1+K2BxnfQ7VUQ15td5f9pVhn-ARSM9EjfOU8WuW72o+cvPg@mail.gmail.com>

Hi Gideon,

On Thu, Nov 12, 2026 at 02:30:39AM +0100, Gideon Heinz wrote:
> Hi Dmitry,
>
> I tested v2 of the series on my G920 (046d:c262). Everything on my
> list works except one scenario that takes the whole machine down, with
> and without your series (last item).
...
>  - rmmod with fftest holding the device open: rmmod returned after
>    2.99 s with "Unloading HID++ force feedback" and nothing else in
>    dmesg. When I then exited fftest (entering -1), the machine went
>    down: the first time with a garbled panic screen that I couldn't
>    read, and on later attempts as a total hang with no output. The
>    same sequence on stock Arch 7.2.11-arch1-1 with the unpatched
>    driver also hangs the whole system, so this predates the series.
>
>    To reproduce: with the module loaded and the G920 plugged in, start
>    fftest on its event node and leave it at the effect prompt, run
>    "rmmod hid_logitech_hidpp" from another terminal, then enter -1 in
>    fftest.
>
>    I could not recover a trace yet and will send one if I manage to.
>
>    My guess, from reading the code and not verified by a trace:
>    hidpp_ff_create() stores hidpp_ff_destroy() and the other FF
>    callbacks in the ff_device as pointers into the module. With fftest
>    holding the evdev open, the input_dev outlives the driver, so when
>    fftest closes, the final input_dev release calls ff->destroy in
>    module code that rmmod has already freed.

Thank you very much for the thorough testing!

Your diagnosis is spot on. Opening /dev/input/eventX pins the evdev cdev
(and through it input_dev), but does not hold a module reference on the
underlying HID driver. When rmmod unloads hid_logitech_hidpp while fftest
still has the file descriptor open, __input_unregister_device() disconnects
evdev (flushing effects, closing the device, and marking evdev dead so all
subsequent ioctls and writes return -ENODEV) and runs ff->stop(), after
which rmmod frees the module text. When fftest finally exits and closes the
file descriptor, input_dev_release() calls input_ff_destroy(), which
invokes ff->destroy() pointing into the already-unmapped module text.

Rather than working around this in individual drivers with a separate
ff->stop() callback, input core should call input_ff_destroy() directly in
__input_unregister_device() once all handlers are disconnected and the
device is removed from sysfs. At that point nothing touches dev->ff
anymore, and calling input_ff_destroy() there guarantees ff->destroy()
always runs while the driver and its module are still loaded (while the
second input_ff_destroy() call in input_dev_release() becomes a no-op once
dev->ff is NULL).

Could you try the input core patch below (with patch 22/33 "HID:
logitech-hidpp: shut down G920 force feedback on input unregister" dropped
from the hid-logitech-hidpp series, since ff->stop is removed and
hidpp_ff_destroy() will now run on input unregistration)?

Alternatively, if you prefer to test with your out-of-tree module build
without rebuilding the kernel, you can test the equivalent effect by
setting:

	ff->destroy = NULL;

inside hidpp_ff_stop() in hid-logitech-hidpp.c.

Thanks.

---
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Subject: [PATCH] Input: destroy force-feedback device on input unregistration

When an input device is unregistered while userspace holds an open file
descriptor to its event node, input_dev_release() is deferred until the
last file descriptor is closed. Because input_ff_destroy() was only
called from input_dev_release(), force-feedback teardown (ff->destroy
and freeing ff->private) could run after the parent driver had already
unbound, freed its device state, or even been unloaded via rmmod,
causing use-after-free errors or page faults in unmapped module text.

Commit ef166ce08801 ("Input: stop force-feedback timer when
unregistering input devices") added a separate ff->stop callback for
ff-memless, but left ff->destroy invoked from input_dev_release().

Once __input_unregister_device() has disconnected all input handlers
(which flushes effects, closes the device, and marks evdev dead) and
deleted the device from sysfs, nothing accesses dev->ff anymore. Call
input_ff_destroy() directly in __input_unregister_device() so that
ff->destroy() always runs synchronously while the driver and its module
are still active, and remove the now-redundant ff->stop callback. Keep
input_ff_destroy() in input_dev_release() (where it is a no-op once
dev->ff is NULL) to handle input_free_device() on devices that were
never registered.

Fixes: 509ca1a93836 ("Input: implement new force feedback interface")
Cc: stable@vger.kernel.org
Reported-by: Gideon Heinz <gideonheinz02@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/ff-core.c    |  2 +-
 drivers/input/ff-memless.c | 23 -----------------------
 drivers/input/input.c      |  5 ++---
 include/linux/input.h      |  3 ---
 4 files changed, 3 insertions(+), 30 deletions(-)

diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
index 0e5d1d1ceb46..133b4622dc49 100644
--- a/drivers/input/ff-core.c
+++ b/drivers/input/ff-core.c
@@ -338,7 +338,7 @@ EXPORT_SYMBOL_GPL(input_ff_create);
  *
  * This function is only needed in error path as input core will
  * automatically free force feedback structures when device is
- * destroyed.
+ * unregistered or destroyed.
  */
 void input_ff_destroy(struct input_dev *dev)
 {
diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c
index d1fefd1dfc0d..3069436148ec 100644
--- a/drivers/input/ff-memless.c
+++ b/drivers/input/ff-memless.c
@@ -483,32 +483,10 @@ static void ml_ff_destroy(struct ff_device *ff)
 {
 	struct ml_device *ml = ff->private;
 
-	/*
-	 * The timer is normally shut down in ml_ff_stop() when the device
-	 * is unregistered. However, we still shut it down here as a safety
-	 * net and for cases where the device was never registered (e.g.
-	 * error paths during probe).
-	 */
 	timer_shutdown_sync(&ml->timer);
-
 	kfree(ml->private);
 }
 
-static void ml_ff_stop(struct ff_device *ff)
-{
-	struct ml_device *ml = ff->private;
-
-	/*
-	 * Even though we stop all playing effects when tearing down an
-	 * input device (by the way of evdev calling input_flush_device()
-	 * that calls into input_ff_flush() that stops and erases all
-	 * effects), we do not actually shutdown the timer, and therefore
-	 * we should do it here to prevent it firing after the input
-	 * device is unregistered and its associated resources are freed.
-	 */
-	timer_shutdown_sync(&ml->timer);
-}
-
 /**
  * input_ff_create_memless() - create memoryless force-feedback device
  * @dev: input device supporting force-feedback
@@ -543,7 +521,6 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
 	ff->playback = ml_ff_playback;
 	ff->set_gain = ml_ff_set_gain;
 	ff->destroy = ml_ff_destroy;
-	ff->stop = ml_ff_stop;
 
 	/* we can emulate periodic effects with RUMBLE */
 	if (test_bit(FF_RUMBLE, ff->ffbit)) {
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 210635ef147e..7be69deed8eb 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -2286,10 +2286,9 @@ static void __input_unregister_device(struct input_dev *dev)
 		input_wakeup_procfs_readers();
 	}
 
-	if (dev->ff && dev->ff->stop)
-		dev->ff->stop(dev->ff);
-
 	device_del(&dev->dev);
+
+	input_ff_destroy(dev);
 }
 
 static void devm_input_device_unregister(struct device *dev, void *res)
diff --git a/include/linux/input.h b/include/linux/input.h
index 3381608127f7..02047cc45d04 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -549,8 +549,6 @@ extern const struct class input_class;
  * @set_autocenter: Called to auto-center device
  * @destroy: called by input core when parent input device is being
  *	destroyed
- * @stop: called by input core when parent input device is being
- *	unregistered
  * @private: driver-specific data, will be freed automatically
  * @ffbit: bitmap of force feedback capabilities truly supported by
  *	device (not emulated like ones in input_dev->ffbit)
@@ -579,7 +577,6 @@ struct ff_device {
 	void (*set_autocenter)(struct input_dev *dev, u16 magnitude);
 
 	void (*destroy)(struct ff_device *);
-	void (*stop)(struct ff_device *);
 
 	void *private;
 

-- 
Dmitry

  reply	other threads:[~2026-11-12  2:43 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11  6:47 [PATCH v2 00/33] HID: logitech-hidpp: G920 force-feedback fixes, rework, and cleanups Dmitry Torokhov
2026-11-11  6:47 ` [PATCH v2 01/33] HID: logitech-hidpp: fix G920 force-feedback initialization timeout Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 02/33] HID: logitech-hidpp: use GFP_ATOMIC in hidpp_ff_queue_work() Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 03/33] HID: logitech-hidpp: drain G920 FF workqueue before closing transport Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 04/33] HID: logitech-hidpp: disable works before stopping transport Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 05/33] HID: logitech-hidpp: do not store ERR_PTR in battery->ps Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 06/33] HID: logitech-hidpp: avoid NULL subtraction in consumer key report fixup Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 07/33] HID: logitech-hidpp: fix off-by-one in G920 force-feedback slot tracking Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 08/33] HID: logitech-hidpp: do not retry timeouts and transport errors in hidpp_send_message_sync() Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 09/33] HID: logitech-hidpp: initialize response buffer before publishing send_receive_buf Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 10/33] HID: logitech-hidpp: fix HID++ 1.0 battery mileage event parsing Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 11/33] HID: logitech-hidpp: handle negative errors in hidpp20_get_adc_measurement_1f20() Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 12/33] HID: logitech-hidpp: mark device online on unified battery 0x1004 events Dmitry Torokhov
2026-11-11  8:22   ` sashiko-bot
2026-11-11 18:57     ` Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 13/33] HID: logitech-hidpp: fix K750 solar battery feature lookup and reconnect Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 14/33] HID: logitech-hidpp: expose charge_type property for battery voltage feature Dmitry Torokhov
2026-11-11  8:39   ` sashiko-bot
2026-11-11 18:57     ` Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 15/33] HID: logitech-hidpp: keep connect work disabled until hid_connect() completes Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 16/33] HID: logitech-hidpp: preserve transport error codes in __hidpp_send_report() Dmitry Torokhov
2026-11-11  8:47   ` sashiko-bot
2026-11-11 18:57     ` Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 17/33] HID: logitech-hidpp: return negative error codes from hidpp_send_message_sync() Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 18/33] HID: logitech-hidpp: rework G920 force-feedback initialization Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 19/33] HID: logitech-hidpp: use sysfs_emit() in hidpp_ff_range_show() Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 20/33] HID: logitech-hidpp: manage G920 range sysfs attribute via dev_groups Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 21/33] HID: logitech-hidpp: execute G920 range sysfs store synchronously Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 22/33] HID: logitech-hidpp: shut down G920 force feedback on input unregister Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 23/33] HID: logitech-hidpp: index G920 force-feedback slots by effect ID Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 24/33] HID: logitech-hidpp: execute G920 effect upload and erase synchronously Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 25/33] HID: logitech-hidpp: clean up G920 force-feedback helpers Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 26/33] HID: logitech-hidpp: use unaligned accessors for multi-byte values Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 27/33] HID: logitech-hidpp: store device serial as a byte array Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 28/33] HID: logitech-hidpp: use guard() for send_mutex Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 29/33] HID: logitech-hidpp: use __free(kfree) for temporary allocations Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 30/33] HID: logitech-hidpp: use alloc_ordered_workqueue() for FF queue Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 31/33] HID: logitech-hidpp: manage send_mutex with devm_mutex_init() Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 32/33] HID: logitech-hidpp: manage ps_attribute_group with devm_device_add_group() Dmitry Torokhov
2026-11-11  6:48 ` [PATCH v2 33/33] HID: logitech-hidpp: remove unused kfifo and clean up minor helpers Dmitry Torokhov
2026-11-12  1:30 ` [PATCH v2 00/33] HID: logitech-hidpp: G920 force-feedback fixes, rework, and cleanups Gideon Heinz
2026-11-12  2:43   ` Dmitry Torokhov [this message]
2026-11-12 10:48     ` Gideon Heinz
2026-11-12 14:30       ` Gideon Heinz
2026-11-12 14:41         ` Gideon Heinz
2026-11-12 14:50           ` Gideon Heinz

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=2f722967b6db0692d4dd4164aff39b62@gmail.com \
    --to=dmitry.torokhov@gmail.com \
    --cc=andrew.smirnov@gmail.com \
    --cc=bentiss@kernel.org \
    --cc=e.velds@gmail.com \
    --cc=gideonheinz02@gmail.com \
    --cc=hadess@hadess.net \
    --cc=hansg@kernel.org \
    --cc=jikos@kernel.org \
    --cc=lains@riseup.net \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=stuart.a.hayhurst@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.