From nobody Sat Sep 26 01:04:58 2026 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8140136605E for ; Sun, 6 Sep 2026 15:55:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.67.36.66 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710140; cv=none; b=Qo5V7JCHpU9tJ1m/fNCkMY8nWbnJq3+6BsaUbTUfS+44ATkRDGQ4mc2UtsfYdAAprQ37NJuTRoYmN3frm+gU590KFtquY1mzTqyJPx4jAoUVd9gjxUhxpkS34WqZfPc3q9zTRzOsIGDK8uBUeQ8HI+s5RmYF2qZ9Y710Wm96/1s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710140; c=relaxed/simple; bh=luUTVGwG8dPS2B8m7mVwkqSNgqVUD/fDXzGfu/5fGnE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=lzGwF/ITOuzO2swq2MkJ/mE3Odwrz0wVdkF/fuIXNICjUurWEb/na4tOjm5YslijZ5VkbyqogbrRXCXn7r7rncY5yIpA5b83o7fvo+oL3IfgUONdsxWMEzzdEPHmpsUccMBQXrnVVroF021uf5dREUakVfF45UC8gGmqgTZxxlk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de; spf=pass smtp.mailfrom=posteo.de; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b=HwMzHudi; arc=none smtp.client-ip=185.67.36.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=posteo.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b="HwMzHudi" Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id 7AF92240104 for ; Sun, 6 Sep 2026 17:55:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.de; s=1984.8680eb; t=1788710131; bh=OPTurngmT4y7HRgllpu2hIi/AvbYo/blTgxsel8dS9c=; h=From:Date:Subject:MIME-Version:Content-Type: Content-Transfer-Encoding:Message-Id:To:Cc:Autocrypt:OpenPGP:From; b=HwMzHudi95cq5VYiePpx2p50lL5CBHi6JsmzE5N4JsAPR3kXRyvYB0CF+m18VpG8k pjVFppDF2ltxDWYimzucv5L05sE59uILGQt06HVH7fEQdSN8aSkwtjDaG3V1bGEXmh LFAGRglnOfZ4QSlrjwzzyhHZHAYLR0s9pLNPASVh2BQ/+rT+cxbfATdg8Fe0LIdgL9 yvmt/0A3sMhxy1YEUPiWXUvb1lFX9D6hcDKFKFTzHjG1WkYB/Y26osuXany06sVKnJ HpCqtZ6aw22B0MlsTrafQT19LdjC5YNES6a+nyIm0J35zm+EJjIb1WXZF8anq8Gr2h 7KYYhxZ1iVYmQ== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4hdFCd6f9cz6tvk; Sun, 6 Sep 2026 17:55:25 +0200 (CEST) From: Markus Probst Date: Sun, 06 Sep 2026 15:55:28 +0000 Subject: [PATCH 1/5] tty: serdev: Export functions to pause receive_buf callback calls Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260906-rust_serdev_probe_refactor-v1-1-69cdae0074ec@posteo.de> References: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> In-Reply-To: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> To: Ayush Singh , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Eric Biggers , Ard Biesheuvel , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Jiri Slaby , "Rafael J. Wysocki" Cc: greybus-dev@lists.linaro.org, linux-serial@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, Markus Probst X-Developer-Signature: v=1; a=openpgp-sha256; l=6513; i=markus.probst@posteo.de; h=from:subject:message-id; bh=luUTVGwG8dPS2B8m7mVwkqSNgqVUD/fDXzGfu/5fGnE=; b=owEBiQJ2/ZANAwAIATR2H/jnrUPSAcsmYgBqnYzqu6+T7ygJPm+wsJS3Z4RFKLAdDXaJ446Hn o6LlYuKuaKJAk8EAAEIADkWIQSCdBjE9KxY53IwxHM0dh/4561D0gUCap2M6hsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQNHYf+OetQ9JP4xAAi1LAZhadIsbkrEyaO1Ov9n9QoVSQOwW wD4xbm6qiViBtokWNRL4/sDm69q5g63ktU7c2IWCDZdRx/KNgbHNBDAudtZuHmw5+AY6Kmvi9SV HuIvaWtVaQ/1KXcYN2HaE2bHctn4yq9r+fqy4N9xlsjW+HjyZlR8okB39fPyVDjaLxODlWZmp7v Pb2leGIImsP1m8gHNWRjTGs//H4cgWqmNY4LPSC8w7Grkfg+G+h84ncFPty/YpR5IYgwExkKW50 U3dfz62zydfthWGU6CZvS5GOaTXr3EPiIiQ7mSWI4rDNczds9gGkDGEyucLLwlkFkYfik/+ZJZO ZiUsJ0Gds2zofgsXfpJmnenqL1miouPwigHl/tvye0OBYXSlhDd/V8pHlGkWE2vMdwfVKEuAr31 byRVrEm9F4GwTAOXQw2YbLTwOdBoNN4c83c33j3mj59NKOJheehkNUoK/4OkUCXVfot90+8m9Wo ogDbn5fVOAkGXVhMPADWvmDWkWFCiRv563M1d32zw/Arkzs5dkHXeEU1lAtHv8DThDmCl8g56iB ud1T8fSPa/VuX556xxkqjEoc0IhtByqzGRe5vrc7xvertfdS8eCgnkCcTbeC97UcaK5nzapeRf9 IqPL9gls3ZYs6KUjYxKftQuHs+zNmdfZMOdUxVtPUKGKnblplv9g= X-Developer-Key: i=markus.probst@posteo.de; a=openpgp; fpr=827418C4F4AC58E77230C47334761FF8E7AD43D2 Autocrypt: addr=markus.probst@posteo.de; prefer-encrypt=mutual; keydata=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 aBeNN4ijKZchBXHPgVx+YtWRHfcm4l8= OpenPGP: url=https://posteo.de/keys/markus.probst@posteo.de.asc; preference=encrypt These functions will be used to simply the serdev rust abstraction. It also contributes to the fixing of 2 race conditions in the serdev rust abstraction. Signed-off-by: Markus Probst --- drivers/tty/serdev/core.c | 50 +++++++++++++++++++++++++++++++++= +++- drivers/tty/serdev/serdev-ttyport.c | 32 ++++++++++++++++++++++++ include/linux/serdev.h | 6 +++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index 7500efcdfc21..7d24f16710cb 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -187,6 +187,51 @@ void serdev_device_close(struct serdev_device *serdev) } EXPORT_SYMBOL_GPL(serdev_device_close); =20 +/** + * serdev_device_pause_rx() - pause data receive + * @serdev: serdev device + * + * Pause calls to receive_buf. + * + * The caller must guarantee that this does not run concurrently with + * `serdev_device_open` or `serdev_device_close`. + * + * Note that if a call to receive_buf is currently executed, the function = will + * sleep until it has finished. + */ +void serdev_device_pause_rx(struct serdev_device *serdev) +{ + struct serdev_controller *ctrl =3D serdev->ctrl; + + if (!ctrl || !ctrl->ops->pause_rx) + return; + + ctrl->ops->pause_rx(ctrl); +} +EXPORT_SYMBOL_GPL(serdev_device_pause_rx); + +/** + * serdev_device_resume_rx() - resume data receive + * @serdev: serdev device + * + * Resume calls to receive_buf. + * + * The caller must guarantee that this does not run concurrently with + * `serdev_device_open` or `serdev_device_close`. + * + * This can be called even if not paused to ensure data receive is active. + */ +void serdev_device_resume_rx(struct serdev_device *serdev) +{ + struct serdev_controller *ctrl =3D serdev->ctrl; + + if (!ctrl || !ctrl->ops->resume_rx) + return; + + ctrl->ops->resume_rx(ctrl); +} +EXPORT_SYMBOL_GPL(serdev_device_resume_rx); + static void devm_serdev_device_close(void *serdev) { serdev_device_close(serdev); @@ -398,6 +443,7 @@ EXPORT_SYMBOL_GPL(serdev_device_break_ctl); static int serdev_drv_probe(struct device *dev) { const struct serdev_device_driver *sdrv =3D to_serdev_device_driver(dev->= driver); + struct serdev_device *sdev =3D to_serdev_device(dev); int ret; =20 ret =3D dev_pm_domain_attach(dev, PD_FLAG_ATTACH_POWER_ON | @@ -405,7 +451,9 @@ static int serdev_drv_probe(struct device *dev) if (ret) return ret; =20 - return sdrv->probe(to_serdev_device(dev)); + serdev_device_resume_rx(sdev); + + return sdrv->probe(sdev); } =20 static void serdev_drv_remove(struct device *dev) diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serde= v-ttyport.c index bab1b143b8a6..85ab454c2f13 100644 --- a/drivers/tty/serdev/serdev-ttyport.c +++ b/drivers/tty/serdev/serdev-ttyport.c @@ -6,9 +6,11 @@ #include #include #include +#include #include =20 #define SERPORT_ACTIVE 1 +#define SERPORT_PAUSE_RX 2 =20 struct serport { struct tty_port *port; @@ -32,6 +34,9 @@ static size_t ttyport_receive_buf(struct tty_port *port, = const u8 *cp, if (!test_bit(SERPORT_ACTIVE, &serport->flags)) return 0; =20 + if (test_bit(SERPORT_PAUSE_RX, &serport->flags)) + return 0; + ret =3D serdev_controller_receive_buf(ctrl, cp, count); =20 dev_WARN_ONCE(&ctrl->dev, ret > count, @@ -156,6 +161,31 @@ static void ttyport_close(struct serdev_controller *ct= rl) tty_release_struct(tty, serport->tty_idx); } =20 +static void ttyport_pause_rx(struct serdev_controller *ctrl) +{ + struct serport *serport =3D serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty =3D serport->tty; + + if (test_bit(SERPORT_ACTIVE, &serport->flags)) + tty_buffer_lock_exclusive(tty->port); + + set_bit(SERPORT_PAUSE_RX, &serport->flags); + + if (test_bit(SERPORT_ACTIVE, &serport->flags)) + tty_buffer_unlock_exclusive(tty->port); +} + +static void ttyport_resume_rx(struct serdev_controller *ctrl) +{ + struct serport *serport =3D serdev_controller_get_drvdata(ctrl); + struct tty_struct *tty =3D serport->tty; + + clear_bit(SERPORT_PAUSE_RX, &serport->flags); + + if (test_bit(SERPORT_ACTIVE, &serport->flags)) + tty_flip_buffer_push(tty->port); +} + static unsigned int ttyport_set_baudrate(struct serdev_controller *ctrl, u= nsigned int speed) { struct serport *serport =3D serdev_controller_get_drvdata(ctrl); @@ -260,6 +290,8 @@ static const struct serdev_controller_ops ctrl_ops =3D { .get_tiocm =3D ttyport_get_tiocm, .set_tiocm =3D ttyport_set_tiocm, .break_ctl =3D ttyport_break_ctl, + .pause_rx =3D ttyport_pause_rx, + .resume_rx =3D ttyport_resume_rx, }; =20 struct device *serdev_tty_port_register(struct tty_port *port, diff --git a/include/linux/serdev.h b/include/linux/serdev.h index b6c3d957ec15..5cf05df17ddf 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -89,6 +89,8 @@ struct serdev_controller_ops { int (*get_tiocm)(struct serdev_controller *); int (*set_tiocm)(struct serdev_controller *, unsigned int, unsigned int); int (*break_ctl)(struct serdev_controller *ctrl, unsigned int break_state= ); + void (*pause_rx)(struct serdev_controller *ctrl); + void (*resume_rx)(struct serdev_controller *ctrl); }; =20 /** @@ -194,6 +196,8 @@ static inline size_t serdev_controller_receive_buf(stru= ct serdev_controller *ctr int serdev_device_open(struct serdev_device *); void serdev_device_close(struct serdev_device *); int devm_serdev_device_open(struct device *, struct serdev_device *); +void serdev_device_pause_rx(struct serdev_device *serdev); +void serdev_device_resume_rx(struct serdev_device *serdev); unsigned int serdev_device_set_baudrate(struct serdev_device *, unsigned i= nt); void serdev_device_set_flow_control(struct serdev_device *, bool); int serdev_device_write_buf(struct serdev_device *, const u8 *, size_t); @@ -233,6 +237,8 @@ static inline int serdev_device_open(struct serdev_devi= ce *sdev) return -ENODEV; } static inline void serdev_device_close(struct serdev_device *sdev) {} +static inline void serdev_device_pause_rx(struct serdev_device *serdev) {} +static inline void serdev_device_resume_rx(struct serdev_device *serdev) {} static inline unsigned int serdev_device_set_baudrate(struct serdev_device= *sdev, unsigned int baudrate) { return 0; --=20 2.55.0 From nobody Sat Sep 26 01:04:58 2026 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C968D336EC9 for ; Sun, 6 Sep 2026 15:55:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.67.36.66 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710136; cv=none; b=fQ+ZaVnNRAE0jkOg8XwFfk+ldquk0pnOUDQuZ31bJQxykJv+Fuk2Beq3b4W/9m3KSJPqicm1gCUn9AX/50vue4ws0tU6Uq5nbFHr3GbUrWlSrwczNY2yPCybH2bKDfdNIg3TCUC7uzwp8e1VQ5PejLGZfdA+jEOkJNws0VKJNLY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710136; c=relaxed/simple; bh=xmTFRFw7V/HU3JXIe69biF6uXSYP9tKIxk/FBu1sWo0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Mc6W+0gq/iYePhXECzSXMdQ0pIoU8o6I7DKrPasbBwAUPZ4340/Ok50iA4k4JjQJ1Fdx1I6SsEnLwVDDTehGeAJJruxohL4gqKJDPz3v50Vi/Faxjz3KrPO8C4eEF0ddo0ZL2ZgyS8KQIG7bo6plcb1oT4KukzMt3hDlugL4f8E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de; spf=pass smtp.mailfrom=posteo.de; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b=XH7qOOBp; arc=none smtp.client-ip=185.67.36.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=posteo.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b="XH7qOOBp" Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id C3D86240104 for ; Sun, 6 Sep 2026 17:55:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.de; s=1984.8680eb; t=1788710132; bh=UTm4yQVbwMpMizb1S87Kb2YZ7hCkc36LgIfvhH/1KKk=; h=From:Date:Subject:MIME-Version:Content-Type: Content-Transfer-Encoding:Message-Id:To:Cc:Autocrypt:OpenPGP:From; b=XH7qOOBpC/NsVJIV/1lslRF+cZu0Qgqh5zY5c0rr6/hKg1GBqqCgMOD/o5FMMjrLf Dg85S9T1QlZLYV/vE30BX3xjKL82ZVhC5wpSXqDZD4JxbCCB1pP3UEt7+BgJY68keQ maS54hrLJaHrjtoJDuAUuLzExy9ciJTtoAUOm33R+g7omu67wfsbpMMfoTvpNG5MYR Hp/0brIiJZNFEvmxa6SmxyZkyADNCz1YKPCnvQz4qkKqoUPGf2gHJQKOJd0CUXd/qi jImfzKsUGs6XicIBQFsii1Cpj2E/irtDENRSPgJjFSGlSoGXxQKHulRgRXYHokQ1L8 qzDitlh8g/EEA== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4hdFCh4dtpz6v3h; Sun, 6 Sep 2026 17:55:28 +0200 (CEST) From: Markus Probst Date: Sun, 06 Sep 2026 15:55:30 +0000 Subject: [PATCH 2/5] rust: serdev: Replace `active` mutex with receive pause Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260906-rust_serdev_probe_refactor-v1-2-69cdae0074ec@posteo.de> References: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> In-Reply-To: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> To: Ayush Singh , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Eric Biggers , Ard Biesheuvel , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Jiri Slaby , "Rafael J. Wysocki" Cc: greybus-dev@lists.linaro.org, linux-serial@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, Markus Probst , Sashiko Bot X-Developer-Signature: v=1; a=openpgp-sha256; l=6499; i=markus.probst@posteo.de; h=from:subject:message-id; bh=xmTFRFw7V/HU3JXIe69biF6uXSYP9tKIxk/FBu1sWo0=; b=owEBiQJ2/ZANAwAIATR2H/jnrUPSAcsmYgBqnYzqmas2+Lg+oqHbSUW0zD7px/TGT5hvRpANM zGexL3WQhuJAk8EAAEIADkWIQSCdBjE9KxY53IwxHM0dh/4561D0gUCap2M6hsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQNHYf+OetQ9Ileg//dOrkcD6wllXJnVtCsKWLO6xbGHv9tq6 zRNa4+WZP9GI9bPEoiAF37X2fP/4F7vOHjLt+hJTe8XHvlMI8vq1AGHS72HmTFMNYcI4Tnw648Q kJ5ywnBWCLePtvrQrY6CGQ629k9HSl55jtAIXfvLE4A65cBfBfdu0KnU542TKasxRWAyzD0sNY8 CqIsCpJoVSxFcfnaXuFVqn1yWP3+XEUcRVj9IJ4ZK4tqzJJWMRn/GJcQMg+BTOoRA6RVxOaEurQ jWR8e+8i7rmFulKnn0q/gndK0vRFp/uiKRqnFDGaASRqQ3S0eYcbAHbI1MqxETeku7UH/hdLdeL FmE0oLEs5R7bPyp/jlWKm5qgxjMcAuYVAjt2/zzjrwP3sdXwSUhEen6jgWtlQUZmqRkilSBxOfl Th2jCtd3ffn/YApEkMBlYUfMXztAbnQCn8fMQlHyR7meYIPt1Fm8FCiEV5FFK5m0IfiL55xji2P RbXb7yj0DsEyX6KTKZDc89zmUQJ2eee11YS/tHi/zjuuiFFr2ItSfj5w3tyjU9+sC44IQTKHnAD DBzF7xeLBGrnH+3W8mlZxVANx2W02rsr9aukwX/UkF0SpmtjH4dmRVbXw2lKN6XRCGtchXsRInj ayKCOTsoILiL/mAxXzdU+hKI7W/raHrX/8BKK0sx/qkBHzDVsZ4o= X-Developer-Key: i=markus.probst@posteo.de; a=openpgp; fpr=827418C4F4AC58E77230C47334761FF8E7AD43D2 Autocrypt: addr=markus.probst@posteo.de; prefer-encrypt=mutual; keydata=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 aBeNN4ijKZchBXHPgVx+YtWRHfcm4l8= OpenPGP: url=https://posteo.de/keys/markus.probst@posteo.de.asc; preference=encrypt There are currently 2 race conditions: - in probe if `Driver::probe` returns Err - in unbind . In those cases the driver data will be set to NULL before the serdev device was closed. If data is received while the driver data is dropped, the `receive_buf_callback` might try to access the `active` mutex on a null pointer. Removing the need for `receive_buf_callback` to lock the `active` mutex fixes these. Fixes: 99f59aa82341 ("rust: add basic serial device bus abstractions") Reported-by: Sashiko Bot Closes: https://lore.kernel.org/linux-serial/20260905000836.C8FC91F00A3D@sm= tp.kernel.org/ Closes: https://lore.kernel.org/linux-serial/20260903222159.70A911F000E9@sm= tp.kernel.org/ Signed-off-by: Markus Probst --- rust/kernel/serdev.rs | 60 ++++++++++++-----------------------------------= ---- 1 file changed, 14 insertions(+), 46 deletions(-) diff --git a/rust/kernel/serdev.rs b/rust/kernel/serdev.rs index 17ca504b7f8d..c16d6593a8d2 100644 --- a/rust/kernel/serdev.rs +++ b/rust/kernel/serdev.rs @@ -13,13 +13,9 @@ to_result, VTABLE_DEFAULT_ERROR, // }, - new_mutex, of, prelude::*, - sync::{ - aref::AlwaysRefCounted, - Mutex, // - }, + sync::aref::AlwaysRefCounted, time::Jiffies, types::{ Opaque, @@ -103,40 +99,11 @@ pub struct PrivateData<'bound, T: Driver> { #[pin] driver: UnsafeCell>>, open: UnsafeCell, - /// Whether `receive_buf_callback` is allowed to call `Driver::receive= `. - /// - /// If locked, the receive_buf_callback will be blocked on data recept= ion. - /// This is the case while the driver is being probed or while [`Priva= teData`] is being dropped. - /// This is necessary, because we need to open the serdev device befor= e the driver has been - /// probed in order to allow it to be configured, which allows `receiv= e_buf_callback` to be - /// called. Thus we need to block data until probe completes and the d= river data becomes - /// initialized. - /// - /// If unlocked and true, the receive_buf_callback will forward the da= ta to - /// `Driver::receive`. This is the normal state of operation. - /// - /// If unlocked and false, the receive_buf_callback will throw away th= e data. - /// This is only the case, if the serdev device is open and - /// - the driver returned an error in probe - /// or - /// - the driver data already has been dropped, because it was unbound. - #[pin] - active: Mutex, } =20 #[pinned_drop] impl PinnedDrop for PrivateData<'_, T> { fn drop(self: Pin<&mut Self>) { - let mut active =3D self.active.lock(); - if *active { - // SAFETY: - // - We have exclusive access to `self.driver`. - // - `self.driver` is guaranteed to be initialized. - unsafe { (*self.driver.get()).assume_init_drop() }; - *active =3D false; - } - drop(active); - // SAFETY: We have exclusive access to `self.open`. if unsafe { *self.open.get() } { // SAFETY: `self.sdev.as_raw()` is guaranteed to be a pointer = to a valid @@ -170,7 +137,6 @@ extern "C" fn probe_callback(sdev: *mut bindings::serde= v_device) -> kernel::ffi: sdev: &**sdev, driver: MaybeUninit::>::zeroed().into(), open: false.into(), - active <- new_mutex!(false), }))?; // SAFETY: We just set drvdata to `PrivateData<'_, T>`. let private_data =3D unsafe { sdev.as_ref().drvdata_borrow::>() }; @@ -178,11 +144,12 @@ extern "C" fn probe_callback(sdev: *mut bindings::ser= dev_device) -> kernel::ffi: // SAFETY: We just set drvdata to `PrivateData<'_, T>`. drop(unsafe { sdev.as_ref().drvdata_obtain::>() }); }); - let mut active =3D private_data.active.lock(); - // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer= to `serdev_device`. unsafe { bindings::serdev_device_set_client_ops(sdev.as_raw(),= Self::OPS) }; =20 + // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer= to `serdev_device`. + unsafe { bindings::serdev_device_pause_rx(sdev.as_raw()) }; + // SAFETY: The serial device bus only ever calls the probe cal= lback with a valid pointer // to a `serdev_device`. to_result(unsafe { bindings::serdev_device_open(sdev.as_raw())= })?; @@ -199,12 +166,12 @@ extern "C" fn probe_callback(sdev: *mut bindings::ser= dev_device) -> kernel::ffi: // - `private_data.driver` is pinned. let result =3D unsafe { pin_init::raw_try_init(driver.as_mut_p= tr(), data) }; =20 - *active =3D result.is_ok(); - - drop(active); - result.map(|()| { private_data.dismiss(); + + // SAFETY: `sdev.as_raw()` is guaranteed to be a valid poi= nter to `serdev_device`. + unsafe { bindings::serdev_device_resume_rx(sdev.as_raw()) = }; + 0 }) }) @@ -231,6 +198,12 @@ extern "C" fn remove_callback(sdev: *mut bindings::ser= dev_device) { let data_pinned =3D unsafe { Pin::new_unchecked(data.assume_init_r= ef()) }; =20 T::unbind(sdev, data_pinned); + + // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer to = `serdev_device`. + unsafe { bindings::serdev_device_pause_rx(sdev.as_raw()) }; + + // SAFETY: We already established that `data` is guaranteed to be = initialized. + unsafe { data.assume_init_drop() }; } =20 extern "C" fn receive_buf_callback( @@ -248,11 +221,6 @@ extern "C" fn receive_buf_callback( // `probe_callback`, hence it's guaranteed that `Device::set_drvda= ta()` has been called // and stored a `Pin>>`. let private_data =3D unsafe { sdev.as_ref().drvdata_borrow::>() }; - let active =3D private_data.active.lock(); - - if !*active { - return length; - } =20 // SAFETY: No one has exclusive access to `private_data.driver`. let data =3D unsafe { &*private_data.driver.get() }; --=20 2.55.0 From nobody Sat Sep 26 01:04:58 2026 Received: from mout01.posteo.de (mout01.posteo.de [185.67.36.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81CB037C108 for ; Sun, 6 Sep 2026 15:55:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.67.36.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710146; cv=none; b=hXxwc8NGLaC5PevWTEi/BzDjrb5CbVd+hDHOUsUpFazov09pDQYOhUJh50iOO9qt33CLhQCdW1iBRa/BdCwPgDij1MiuVqDyWon2JsiSYyzFuahrYkysp0K/iLpDXM2pa5S16F2PlleIDidKxQLzhYMIt0KApmaC+1VCG9ANNJw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710146; c=relaxed/simple; bh=jBV8d2R4sxQ10o9qb0yB9q25+j/FxeZzKdd3XBcwv2o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MOmFrgzVz2kOVzG3NGkx6lhpo7G/3qXXEhbs2GSqkDC7Zzny1OiHHPhexX1gR3q/U8Z/zPtwcltQQ61p3Sh3F0ISHF+pGz1GpVzofeHv4apfJs9EHcZG+qVTTmz0nFFHdKz51ywITA1nS62Wf9YZwnLnbTS2/hnaFOm0gkSzIGY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de; spf=pass smtp.mailfrom=posteo.de; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b=GzeKU+fX; arc=none smtp.client-ip=185.67.36.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=posteo.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b="GzeKU+fX" Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 5D36C24002D for ; Sun, 6 Sep 2026 17:55:34 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.de; s=1984.8680eb; t=1788710134; bh=wLU0eqn9X5HLi+VXCI4NhPcCo53w8NpuI/rKYlEpPz0=; h=From:Date:Subject:MIME-Version:Content-Type: Content-Transfer-Encoding:Message-Id:To:Cc:Autocrypt:OpenPGP:From; b=GzeKU+fXMxgup6jyDlGz7fnjjY0wMI9LW4YrFGbWxlhvWoWXyuevcvNlF6FovztTP sjM1RD+BzJ5AjgR9aFHPDTyGxDG+8N/c7JiZXbDJ9819M5VjDmUrhLUGAyFvyj7Jg3 fsH6n176NPhyW+cVhobNticjels1B+XWLFCoAH2L3rnraNj5pTz7J7CdpbAsJs6hJ+ Q6KaLUolWZUFGMVLZxATD365GLvZL9hqxoIGtyuYPdayYhPiVRGd8kNULxVFfH1B+G 3KCc+hmtnZ79uAscLIg/+weTuam4l88PPzWnzhtzwDP2OjBaCtrqZBAXZ8a0dHrY5R I9Bd3ppyk9bYg== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4hdFCl0MKBz6twb; Sun, 6 Sep 2026 17:55:31 +0200 (CEST) From: Markus Probst Date: Sun, 06 Sep 2026 15:55:32 +0000 Subject: [PATCH 3/5] rust: serdev: Simplify callbacks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260906-rust_serdev_probe_refactor-v1-3-69cdae0074ec@posteo.de> References: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> In-Reply-To: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> To: Ayush Singh , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Eric Biggers , Ard Biesheuvel , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Jiri Slaby , "Rafael J. Wysocki" Cc: greybus-dev@lists.linaro.org, linux-serial@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, Markus Probst X-Developer-Signature: v=1; a=openpgp-sha256; l=8332; i=markus.probst@posteo.de; h=from:subject:message-id; bh=jBV8d2R4sxQ10o9qb0yB9q25+j/FxeZzKdd3XBcwv2o=; b=owEBiQJ2/ZANAwAIATR2H/jnrUPSAcsmYgBqnYzqb1S5xgfTHcITIHmxbfiQycqM/kUk+0hBb emwposY5EKJAk8EAAEIADkWIQSCdBjE9KxY53IwxHM0dh/4561D0gUCap2M6hsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQNHYf+OetQ9IaIRAAu8qpQWM8M2Lq1vJ7+NfMlhfGZvX3aZ3 oi5d+1t6uf+eEJFM0xC+SKs50wH/cP//WouzzqHnmQLyukm0e+ZwUktsgzn8jc1Q4rtg64CCht9 Ih18zIosLWojAd4k/Krf/dTeRxKNtUfxof1dOcnflvnq4OGpx8A1vE8Ep6npfLlT2hXNCPybdsu DfHKHtlaIa9uftMrL9Q5Zx1kjsxQ561Uyh7IwmqppdFvbo/n3miuF0fEfAwB3Yp3RXRc6fwzsLn BKNSwMYWimkCeGc9ecV2nregb6xnftUnSt+Kjd1Tu1kic7HodAivH85LHvzcmLul1qLXpDr1eiw iym+wm+uT8rLN7vWPeX+FdqUPMHQBGSCBzXUbDYQS6GpNaIaOpQzuap9aZzhGMSdXyLoT5/4iLH s/qw45yASbt8A1K1AvEA0dfmPcXHFiveWsu36ZinCilt0UMeVhvMOjBGmX5pI1DThjuG+SS/PB2 1RbPNH2g/j+Hznl9t7yXeUhVMgTasICpyd5DrW2x9LMUSz0GWxQyZtOnVlOPHT1MIlbOxeLwScY HqH97Kn6Uwp2FVYwy+IQRYfFeg+Lvh50SoFp0BaHzS1F1n8OwmA1Jl5UI835kjCJvi18sYACoWf uk5+D1bDstvNwSSAIrK1T6f3l4Om4HZIOjH3xzSE+5HZmTcmiJ8I= X-Developer-Key: i=markus.probst@posteo.de; a=openpgp; fpr=827418C4F4AC58E77230C47334761FF8E7AD43D2 Autocrypt: addr=markus.probst@posteo.de; prefer-encrypt=mutual; keydata=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 aBeNN4ijKZchBXHPgVx+YtWRHfcm4l8= OpenPGP: url=https://posteo.de/keys/markus.probst@posteo.de.asc; preference=encrypt Initialize the driver's private data directly on `PrivateData`. Introduce `OpenGuard` for resource cleanup. Signed-off-by: Markus Probst --- rust/kernel/serdev.rs | 130 ++++++++++++++++++++--------------------------= ---- 1 file changed, 51 insertions(+), 79 deletions(-) diff --git a/rust/kernel/serdev.rs b/rust/kernel/serdev.rs index c16d6593a8d2..66543108ec2f 100644 --- a/rust/kernel/serdev.rs +++ b/rust/kernel/serdev.rs @@ -17,16 +17,12 @@ prelude::*, sync::aref::AlwaysRefCounted, time::Jiffies, - types::{ - Opaque, - ScopeGuard, // - }, // + types::Opaque, // }; =20 use core::{ - cell::UnsafeCell, marker::PhantomData, - mem::{offset_of, MaybeUninit}, + mem::offset_of, ptr::NonNull, // }; =20 @@ -92,24 +88,35 @@ unsafe fn unregister(sdrv: &Opaque) { } } =20 +struct OpenGuard<'bound> { + sdev: &'bound Device, +} + +impl Drop for OpenGuard<'_> { + fn drop(&mut self) { + // SAFETY: + // - `self.sdev.as_raw()` is guaranteed to be a pointer to a valid + // `struct serdev_device`. + // - The existence of self proves that the device is open. + unsafe { bindings::serdev_device_close(self.sdev.as_raw()) }; + } +} + #[doc(hidden)] -#[pin_data(PinnedDrop)] +#[pin_data] pub struct PrivateData<'bound, T: Driver> { - sdev: &'bound Device, #[pin] - driver: UnsafeCell>>, - open: UnsafeCell, + driver: T::Data<'bound>, + open: OpenGuard<'bound>, } =20 -#[pinned_drop] -impl PinnedDrop for PrivateData<'_, T> { - fn drop(self: Pin<&mut Self>) { - // SAFETY: We have exclusive access to `self.open`. - if unsafe { *self.open.get() } { - // SAFETY: `self.sdev.as_raw()` is guaranteed to be a pointer = to a valid - // `struct serdev_device`. - unsafe { bindings::serdev_device_close(self.sdev.as_raw()) }; - } +impl<'bound, T: Driver> PrivateData<'bound, T> { + fn driver_data(self: Pin<&Self>) -> Pin<&T::Data<'bound>> { + // SAFETY: We treat the result as pinned. + let inner =3D unsafe { Pin::into_inner_unchecked(self) }; + + // SAFETY: `self.driver` is pinned. + unsafe { Pin::new_unchecked(&inner.driver) } } } =20 @@ -134,46 +141,30 @@ extern "C" fn probe_callback(sdev: *mut bindings::ser= dev_device) -> kernel::ffi: =20 from_result(|| { sdev.as_ref().set_drvdata(try_pin_init!(PrivateData:: { - sdev: &**sdev, - driver: MaybeUninit::>::zeroed().into(), - open: false.into(), + open: { + // SAFETY: + // - `sdev.as_raw()` is guaranteed to be a valid point= er to + // `serdev_device`. + // - It is safe to call before open. + unsafe { bindings::serdev_device_set_client_ops(sdev.a= s_raw(), Self::OPS) }; + + // SAFETY: `sdev.as_raw()` is guaranteed to be a valid= pointer to + // `serdev_device`. + unsafe { bindings::serdev_device_pause_rx(sdev.as_raw(= )) }; + + // SAFETY: `sdev.as_raw()` is guaranteed to be a valid= pointer to + // `serdev_device`. + to_result(unsafe { bindings::serdev_device_open(sdev.a= s_raw()) })?; + + OpenGuard { sdev } + }, + driver <- T::probe(sdev, info), }))?; - // SAFETY: We just set drvdata to `PrivateData<'_, T>`. - let private_data =3D unsafe { sdev.as_ref().drvdata_borrow::>() }; - let private_data =3D ScopeGuard::new_with_data(private_data, |= _| { - // SAFETY: We just set drvdata to `PrivateData<'_, T>`. - drop(unsafe { sdev.as_ref().drvdata_obtain::>() }); - }); - // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer= to `serdev_device`. - unsafe { bindings::serdev_device_set_client_ops(sdev.as_raw(),= Self::OPS) }; =20 // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer= to `serdev_device`. - unsafe { bindings::serdev_device_pause_rx(sdev.as_raw()) }; - - // SAFETY: The serial device bus only ever calls the probe cal= lback with a valid pointer - // to a `serdev_device`. - to_result(unsafe { bindings::serdev_device_open(sdev.as_raw())= })?; - - // SAFETY: We have exclusive access to `private_data.open`. - unsafe { *private_data.open.get() =3D true }; - - let data =3D T::probe(sdev, info); + unsafe { bindings::serdev_device_resume_rx(sdev.as_raw()) }; =20 - // SAFETY: We have exclusive access to `private_data.driver`. - let driver =3D unsafe { &mut *private_data.driver.get() }; - // SAFETY: - // - `driver.as_mut_ptr()` is a valid pointer to uninitialized= data. - // - `private_data.driver` is pinned. - let result =3D unsafe { pin_init::raw_try_init(driver.as_mut_p= tr(), data) }; - - result.map(|()| { - private_data.dismiss(); - - // SAFETY: `sdev.as_raw()` is guaranteed to be a valid poi= nter to `serdev_device`. - unsafe { bindings::serdev_device_resume_rx(sdev.as_raw()) = }; - - 0 - }) + Ok(0) }) } =20 @@ -189,21 +180,10 @@ extern "C" fn remove_callback(sdev: *mut bindings::se= rdev_device) { // and stored a `Pin>>`. let private_data =3D unsafe { sdev.as_ref().drvdata_borrow::>() }; =20 - // SAFETY: No one has exclusive access to `private_data.driver`. - let data =3D unsafe { &*private_data.driver.get() }; - // SAFETY: - // - `private_data.driver` is pinned. - // - `remove_callback` is only ever called after a successful call= to `probe_callback`, - // hence it's guaranteed that `private_data.driver` was initiali= zed. - let data_pinned =3D unsafe { Pin::new_unchecked(data.assume_init_r= ef()) }; - - T::unbind(sdev, data_pinned); + T::unbind(sdev, private_data.driver_data()); =20 // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer to = `serdev_device`. unsafe { bindings::serdev_device_pause_rx(sdev.as_raw()) }; - - // SAFETY: We already established that `data` is guaranteed to be = initialized. - unsafe { data.assume_init_drop() }; } =20 extern "C" fn receive_buf_callback( @@ -211,6 +191,9 @@ extern "C" fn receive_buf_callback( buf: *const u8, length: usize, ) -> usize { + // SAFETY: `buf` is guaranteed to be non-null and has the size of = `length`. + let buf =3D unsafe { core::slice::from_raw_parts(buf, length) }; + // SAFETY: The serial device bus only ever calls the receive buf c= allback with a valid // pointer to a `struct serdev_device`. // @@ -222,18 +205,7 @@ extern "C" fn receive_buf_callback( // and stored a `Pin>>`. let private_data =3D unsafe { sdev.as_ref().drvdata_borrow::>() }; =20 - // SAFETY: No one has exclusive access to `private_data.driver`. - let data =3D unsafe { &*private_data.driver.get() }; - // SAFETY: - // - `private_data.driver` is pinned. - // - `receive_buf_callback` is only ever called after a successful= call to `probe_callback`, - // hence it's guaranteed that `private_data.driver` was initiali= zed. - let data_pinned =3D unsafe { Pin::new_unchecked(data.assume_init_r= ef()) }; - - // SAFETY: `buf` is guaranteed to be non-null and has the size of = `length`. - let buf =3D unsafe { core::slice::from_raw_parts(buf, length) }; - - T::receive(sdev, data_pinned, buf) + T::receive(sdev, private_data.driver_data(), buf) } } =20 --=20 2.55.0 From nobody Sat Sep 26 01:04:58 2026 Received: from mout01.posteo.de (mout01.posteo.de [185.67.36.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 52B0637AA94 for ; Sun, 6 Sep 2026 15:55:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.67.36.65 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710143; cv=none; b=c1Bqs55nvuaX9sXuDVyUUL3R8NBnB3s01NMDCU3s4fCyR3BH5NbgHDFTJL0B5wHtxx19Q1BRqigA74dhtb+IK+8jfUVzOz8EPfuSTZHiFEo0g4s3l1QfBggx5HKVz/6UUuR09NzJo7xq+kHCR3CyQJuUUhKy0jq/tPlCDkWDEiM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710143; c=relaxed/simple; bh=fyxFTMFAa80FsZG990F6QCIaClCrAw8kFJBc4LVqL/U=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=u4k8K1Kc+TEhAIO4Sjw3XR64qR7Ii/M5XF1iy509xzlspgNXn/AHa+xRxSXFADj8q1XKHfg6Tvpck2Htg1lJjQurz+WslughehMnIbkcsk7w28mae4bm13cnvpgkDv+ng7m/taxNNzgAizlnigDV7VqXtQdbwKORcP7TGKVvRRo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de; spf=pass smtp.mailfrom=posteo.de; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b=kO+B91wH; arc=none smtp.client-ip=185.67.36.65 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=posteo.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b="kO+B91wH" Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id 1000724002A for ; Sun, 6 Sep 2026 17:55:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.de; s=1984.8680eb; t=1788710136; bh=zVRusiE8chJT35Hfseh5oBKBImpt0sKZ2uzSGkt9OGc=; h=From:Date:Subject:MIME-Version:Content-Type: Content-Transfer-Encoding:Message-Id:To:Cc:Autocrypt:OpenPGP:From; b=kO+B91wHwCAfT3+lkYkQoxF4JKdrYPSzR4uwzq92smxIdWfOLlzCX8BNN+Fmj468A 2zCuUIlB0GeExqDOPgHrmSeEpGyBTDb4ti4YaNWH3VwqKXQM83hilInP2eBvsJIwHv kfHcpW3nPy735z/GBcA2RDZJoXK9oPyiE0CWabfXvhokmkyANG7TUowbMVoVShhlRr UNyf0kLy+cFusiZB5qQmNbMxVghDB5BML+RZtyq3VMW2N0AE1v5toMB2fDiupyaRRa MiwIeQaCdFJhPeGggxr42GaCMWXx7Y6ImJgVdhddJ+mM+PnMpy5zhbG8SlDKaTivk3 knhN5FqYoUTow== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4hdFCm55ffz6twR; Sun, 6 Sep 2026 17:55:32 +0200 (CEST) From: Markus Probst Date: Sun, 06 Sep 2026 15:55:34 +0000 Subject: [PATCH 4/5] rust: Add `Device::drvdata_borrow_mut` Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260906-rust_serdev_probe_refactor-v1-4-69cdae0074ec@posteo.de> References: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> In-Reply-To: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> To: Ayush Singh , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Eric Biggers , Ard Biesheuvel , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Jiri Slaby , "Rafael J. Wysocki" Cc: greybus-dev@lists.linaro.org, linux-serial@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, Markus Probst X-Developer-Signature: v=1; a=openpgp-sha256; l=1958; i=markus.probst@posteo.de; h=from:subject:message-id; bh=fyxFTMFAa80FsZG990F6QCIaClCrAw8kFJBc4LVqL/U=; b=owEBiQJ2/ZANAwAIATR2H/jnrUPSAcsmYgBqnYzqGuYE7hlifjnRlFzrGG5vOPR4yMeyxbAU+ 0i8m7OcniyJAk8EAAEIADkWIQSCdBjE9KxY53IwxHM0dh/4561D0gUCap2M6hsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQNHYf+OetQ9LgEw//VPYTzw5GSkY7fZEowBvE6bbFFAFB2JY rD16A1i/zIC7Pnq6aiNW0WvI4HnY0gts1kdfpCGsdYPlaAw9VPAZZeu5KYSJ6xrLYuYBphPyUn8 xKL03SBKFwO03evBruOjZfYY/gK5C5tlk7hIQW827AaMlVZ42B6n8Wkyhjafw70v7u9L8PuJrN8 jCDvQJd10oNuGwIBdarTfGak0dM62UKAZDjJ8rSwMcLuXI+DZQpaZJ3MWlpnPLz9DAq57cgf2D+ T/peA0LG04oazFFj0a7myew9ZMrZrKOKjT1YN1JCynlAivk/BPShcqXg8wIDZniJPx7Jv0RNFVK 47StNUbog6jDzD9oYoYFTpgOLpOr6L81PIjL2Cjqh7EfLOtg758pBrnmJTnL9jhaxGLI+6YxvFv iLT9nxmG/UG/LC8aZ7X5WG3AeDMNk3XdrgQX9i550cDyKk0pHBzW+AHPcHoAwetKBjoRb2uf3Ug 2AXb5LdsEbZ6B57uVX5v/kESa7Noq24kONmGccd8X9g1f98wGJ+shEnN79znmu8pfGuJwpKtcIr E/gVjV9vly/iHoVdtvlgXZycbxNTjtVZK4q5LlTRctf5/Kx/Js3zqjDebqee6aUwODG/AxHhRy+ nrlupKFTkFxPTahL5fQJT4EdIo8w/42g6xpig+v1WKh5dtAdbBak= X-Developer-Key: i=markus.probst@posteo.de; a=openpgp; fpr=827418C4F4AC58E77230C47334761FF8E7AD43D2 Autocrypt: addr=markus.probst@posteo.de; prefer-encrypt=mutual; keydata=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 aBeNN4ijKZchBXHPgVx+YtWRHfcm4l8= OpenPGP: url=https://posteo.de/keys/markus.probst@posteo.de.asc; preference=encrypt This function allows the caller to obtain a mutable reference to the driver's private data if he has exclusive access. This will be used in serdev to provide mutable references in callbacks. Signed-off-by: Markus Probst --- rust/kernel/device.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs index 2291d85b6849..aa2d87c6f4d3 100644 --- a/rust/kernel/device.rs +++ b/rust/kernel/device.rs @@ -258,6 +258,30 @@ pub unsafe fn drvdata_borrow(&self) -> Pin<&T> { // in `into_foreign()`. unsafe { Pin::>::borrow(ptr.cast()) } } + + /// Borrow the driver's private data bound to this [`Device`] mutable. + /// + /// # Safety + /// + /// - Must only be called after a preceding call to [`Device::set_drvd= ata`] and before the + /// device is fully unbound. + /// - The type `T` must match the type of the `ForeignOwnable` previou= sly stored by + /// [`Device::set_drvdata`]. + /// - The caller must have exclusive access to `T`. + #[expect(clippy::mut_from_ref)] + pub unsafe fn drvdata_borrow_mut(&self) -> Pin<&mut T> { + // SAFETY: By the type invariants, `self.as_raw()` is a valid poin= ter to a `struct device`. + let ptr =3D unsafe { bindings::dev_get_drvdata(self.as_raw()) }; + + // SAFETY: + // - By the safety requirements of this function, `ptr` comes from= a previous call to + // `into_foreign()`. + // - `dev_get_drvdata()` guarantees to return the same pointer giv= en to `dev_set_drvdata()` + // in `into_foreign()`. + // - By the safety requirements of this function, `borrow` and `bo= rrow_mut` do not overlap + // on the same object. + unsafe { Pin::>::borrow_mut(ptr.cast()) } + } } =20 impl Device { --=20 2.55.0 From nobody Sat Sep 26 01:04:58 2026 Received: from mout02.posteo.de (mout02.posteo.de [185.67.36.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8AAAB37BE96 for ; Sun, 6 Sep 2026 15:55:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.67.36.66 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710141; cv=none; b=Bt7rVlA5FIzqMY3QUhCHCUujH+LlPg8sDI9d0PC9C0/O0GIEWuLTGSxuFk9K94MpBI6q4dejXg8hYZl3rqmPmclY0Xy8QNt89fyc4JPADdDXQBqZQ9q8IytfxfRpEO5hcVyAHlahONY9xoRm2QuktwswJ3AonAdmsHDMBWE3Yts= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788710141; c=relaxed/simple; bh=wWGgnov65ZJqhT9zXloo5ac7Dq5BL+le5LUIaHFssg4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=rDeshGerh72Klo4LGWg3FMMz+teCsfFWJtbEe6vBL2jZ6XFh2I3u6iqhqzdX4jlNgFOr0Py/iiJnKb+MfxywiaR7iOvDGjfgLaIMD8keuhQMaZqQiWr5jt71uYiJHYdAt6a/ESYHnuqJYib/j4+vog03wV8N9/ai6IeIMMtvywU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de; spf=pass smtp.mailfrom=posteo.de; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b=bgm+55n9; arc=none smtp.client-ip=185.67.36.66 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=posteo.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=posteo.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=posteo.de header.i=@posteo.de header.b="bgm+55n9" Received: from submission (posteo.de [185.67.36.169]) by mout02.posteo.de (Postfix) with ESMTPS id EDCDB240106 for ; Sun, 6 Sep 2026 17:55:37 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=posteo.de; s=1984.8680eb; t=1788710137; bh=H1usViq0rGSlCgRtIfdfxljYpLCz0O0luhM/wP/Mhdg=; h=From:Date:Subject:MIME-Version:Content-Type: Content-Transfer-Encoding:Message-Id:To:Cc:Autocrypt:OpenPGP:From; b=bgm+55n9kH9LwMUb/2gVuBS6Nn5vemQZL3dUWYX+J5kLqKKd1tYg8tqpLbIddwNs9 7yDqOl2iQobEsrK5jdMkhx62P8RxG9I6gt44V1tq66C1K2tsiNqOMhSmyerwNGO2Vx fAjpQcG0RyEHV1LUfV7iPO29Xao64Ba/nimX47Kq9A93S0aWaAT1rq/w5VTom69zLZ Q302V5Ok33dP0AjGD6DkQyDDbLQkzfOuXiczSNsQibbFbYGqvkLebHAvprre8FBXaV /c29nkWeAtWiCLcQcjXjQ3ZTSCiVPe8IDzrx16iXzBXuoiR0crn7hQsOmp/RoIsjTQ R2rP++8ZwMwUQ== Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4hdFCp2bqdz6tsg; Sun, 6 Sep 2026 17:55:34 +0200 (CEST) From: Markus Probst Date: Sun, 06 Sep 2026 15:55:35 +0000 Subject: [PATCH 5/5] rust: serdev: Pause receive callback before calling unbind Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260906-rust_serdev_probe_refactor-v1-5-69cdae0074ec@posteo.de> References: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> In-Reply-To: <20260906-rust_serdev_probe_refactor-v1-0-69cdae0074ec@posteo.de> To: Ayush Singh , Johan Hovold , Alex Elder , Greg Kroah-Hartman , Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , Daniel Almeida , Tamir Duberstein , Alexandre Courbot , =?utf-8?q?Onur_=C3=96zkan?= , Eric Biggers , Ard Biesheuvel , Lorenzo Stoakes , Vlastimil Babka , "Liam R. Howlett" , Uladzislau Rezki , Jiri Slaby , "Rafael J. Wysocki" Cc: greybus-dev@lists.linaro.org, linux-serial@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, driver-core@lists.linux.dev, Markus Probst X-Developer-Signature: v=1; a=openpgp-sha256; l=5586; i=markus.probst@posteo.de; h=from:subject:message-id; bh=wWGgnov65ZJqhT9zXloo5ac7Dq5BL+le5LUIaHFssg4=; b=owEBiQJ2/ZANAwAIATR2H/jnrUPSAcsmYgBqnYzqL9li5x5gN5EmZDfiI0wa3kL6wZcVpyvy8 juxF/4VPwqJAk8EAAEIADkWIQSCdBjE9KxY53IwxHM0dh/4561D0gUCap2M6hsUgAAAAAAEAA5t YW51MiwyLjUrMS4xMiwyLDIACgkQNHYf+OetQ9LwtA//UxEEr+R22CvNQ3VHemKSdgP9TSGAQkO q0Fu8+es04maTv2GQDc4cEJUvpg+slftg49jOL2z2hzQixFpWgQMyf71F027p3uyRKbAFId5cNo QgP9fRgr8U7vDm9FVQi0YNMUpYlCvf8sQIH+unPw5x1cMeEyF1KYmG4Ry+IOVjrGEhiwzsCg7Hp 5cbNXKIjT+UiHAzgmHwM/4mpJE9aMSIxx8FNeE6sEb665hwifvBfGsbZB+hF5+2bX/Q3zXldTik v/0pVNV97HuR6QJf1wGSOJP1sol5HskQNlWjMZ9hqNlQ88EPNsbMsCQ9ExHNBCzvos8xytgCJVs rhk4uQXof5i4lbtaoSuYnImIfyhDM4H3aG3wzU1hHQFoxhvsFaR/sqjoEDWHdphCvT9YX+kPFyk RKfFJszptzwz6A/eN6Tv9L4TgUfP+uRBbP+tqOlunSSsMl/XlYyzb7iL+jzkJd8yzVhjlOGdPLV R/UhzBgX/k72IDh1g0UwuOsja907ZhDOFq8ruzCVnFJDrsVizhddQZiGyUjxDmDiNgo2rzwZPTX nBblJ/7sUkkkijuzDJwnO9ZjRHVQDR5crDQayVp7uabUtvgL3Ls9r6iKOIZSudtWv3rUuWTcXYM s88TsqVKJ729ZnEvubvLfeCoUwOtjhAMZyuZxW53GLUCI6OqqizQ= X-Developer-Key: i=markus.probst@posteo.de; a=openpgp; fpr=827418C4F4AC58E77230C47334761FF8E7AD43D2 Autocrypt: addr=markus.probst@posteo.de; prefer-encrypt=mutual; keydata=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 aBeNN4ijKZchBXHPgVx+YtWRHfcm4l8= OpenPGP: url=https://posteo.de/keys/markus.probst@posteo.de.asc; preference=encrypt The receive callback and unbind callback now have exclusive access to the drivers private data. Provide mutable references in callbacks to avoid the need for locks in the private data. Remove the Sync requirement. Signed-off-by: Markus Probst --- rust/kernel/serdev.rs | 39 ++++++++++++++++++++++------------= ---- samples/rust/rust_driver_serdev.rs | 2 +- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/rust/kernel/serdev.rs b/rust/kernel/serdev.rs index 66543108ec2f..7d47d91e3bc3 100644 --- a/rust/kernel/serdev.rs +++ b/rust/kernel/serdev.rs @@ -111,12 +111,12 @@ pub struct PrivateData<'bound, T: Driver> { } =20 impl<'bound, T: Driver> PrivateData<'bound, T> { - fn driver_data(self: Pin<&Self>) -> Pin<&T::Data<'bound>> { + fn driver_data(self: Pin<&mut Self>) -> Pin<&mut T::Data<'bound>> { // SAFETY: We treat the result as pinned. let inner =3D unsafe { Pin::into_inner_unchecked(self) }; =20 // SAFETY: `self.driver` is pinned. - unsafe { Pin::new_unchecked(&inner.driver) } + unsafe { Pin::new_unchecked(&mut inner.driver) } } } =20 @@ -175,15 +175,18 @@ extern "C" fn remove_callback(sdev: *mut bindings::se= rdev_device) { // INVARIANT: `sdev` is valid for the duration of `remove_callback= ()`. let sdev =3D unsafe { &*sdev.cast::>>() }; =20 - // SAFETY: `remove_callback` is only ever called after a successfu= l call to - // `probe_callback`, hence it's guaranteed that `Device::set_drvda= ta()` has been called - // and stored a `Pin>>`. - let private_data =3D unsafe { sdev.as_ref().drvdata_borrow::>() }; - - T::unbind(sdev, private_data.driver_data()); - // SAFETY: `sdev.as_raw()` is guaranteed to be a valid pointer to = `serdev_device`. unsafe { bindings::serdev_device_pause_rx(sdev.as_raw()) }; + + // SAFETY: + // - `remove_callback` is only ever called after a successful call= to `probe_callback`, + // hence it's guaranteed that `Device::set_drvdata()` has been c= alled and stored a + // `Pin>>`. + // - The call to `serdev_device_pause_rx` above guarantees that we= do not overlap with + // `receive_buf_callback`, thus it is guaranteed that we have ex= clusive access. + let private_data =3D unsafe { sdev.as_ref().drvdata_borrow_mut::>() }; + + T::unbind(sdev, private_data.driver_data()); } =20 extern "C" fn receive_buf_callback( @@ -200,10 +203,14 @@ extern "C" fn receive_buf_callback( // INVARIANT: `sdev` is valid for the duration of `receive_buf_cal= lback()`. let sdev =3D unsafe { &*sdev.cast::>= () }; =20 - // SAFETY: `receive_buf_callback` is only ever called after a succ= essful call to - // `probe_callback`, hence it's guaranteed that `Device::set_drvda= ta()` has been called - // and stored a `Pin>>`. - let private_data =3D unsafe { sdev.as_ref().drvdata_borrow::>() }; + // SAFETY: + // - `receive_buf_callback` is only ever called after a successful= call to `probe_callback`, + // hence it's guaranteed that `Device::set_drvdata()` has been c= alled and stored a + // `Pin>>`. + // - `unbind_callback` calls `serdev_device_pause_rx` before acces= sing the driver data, + // which guarantees that this function will not overlap with it.= Thus we have exclusive + // access. + let private_data =3D unsafe { sdev.as_ref().drvdata_borrow_mut::>() }; =20 T::receive(sdev, private_data.driver_data(), buf) } @@ -305,7 +312,7 @@ pub trait Driver { type IdInfo: 'static; =20 /// The type of the driver's bus device private data. - type Data<'bound>: Send + Sync + 'bound; + type Data<'bound>: Send + 'bound; =20 /// The table of OF device ids supported by the driver. const OF_ID_TABLE: Option> =3D None; @@ -331,7 +338,7 @@ fn probe<'bound>( /// `&Device` or `&Device` reference. For instance. /// /// Otherwise, release operations for driver resources should be perfo= rmed in `Drop`. - fn unbind<'bound>(sdev: &'bound Device>, this: Pin<&S= elf::Data<'bound>>) { + fn unbind<'bound>(sdev: &'bound Device>, this: Pin<&m= ut Self::Data<'bound>>) { let _ =3D (sdev, this); } =20 @@ -342,7 +349,7 @@ fn unbind<'bound>(sdev: &'bound Device= >, this: Pin<&Self::Data< /// Returns the number of bytes accepted. fn receive<'bound>( sdev: &'bound Device, - this: Pin<&Self::Data<'bound>>, + this: Pin<&mut Self::Data<'bound>>, data: &[u8], ) -> usize { let _ =3D (sdev, this, data); diff --git a/samples/rust/rust_driver_serdev.rs b/samples/rust/rust_driver_= serdev.rs index 51b4898cd855..d00d547234c8 100644 --- a/samples/rust/rust_driver_serdev.rs +++ b/samples/rust/rust_driver_serdev.rs @@ -63,7 +63,7 @@ fn probe<'bound>( =20 fn receive<'bound>( sdev: &'bound serdev::Device, - _this: Pin<&Self>, + _this: Pin<&mut Self>, data: &[u8], ) -> usize { sdev.write(data).unwrap_or_default() as usize --=20 2.55.0