From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: Kurt Borja <kuurtb@gmail.com>
Cc: platform-driver-x86@vger.kernel.org,
"Rafael J. Wysocki" <rafael@kernel.org>,
Len Brown <lenb@kernel.org>,
linux-acpi@vger.kernel.org, LKML <linux-kernel@vger.kernel.org>,
Mario Limonciello <mario.limonciello@amd.com>,
Armin Wolf <W_Armin@gmx.de>,
Joshua Grisham <josh@joshuagrisham.com>,
"Derek J. Clark" <derekjohn.clark@gmail.com>,
Hans de Goede <hdegoede@redhat.com>,
Maximilian Luz <luzmaximilian@gmail.com>,
"Lee, Chun-Yi" <jlee@suse.com>,
Shyam Sundar S K <Shyam-sundar.S-k@amd.com>,
Corentin Chary <corentin.chary@gmail.com>,
"Luke D. Jones" <luke@ljones.dev>,
Lyndon Sanche <lsanche@lyndeno.ca>,
Ike Panhc <ike.pan@canonical.com>,
Henrique de Moraes Holschuh <hmh@hmh.eng.br>,
Mark Pearson <mpearson-lenovo@squebb.ca>,
Alexis Belmonte <alexbelm48@gmail.com>,
Ai Chao <aichao@kylinos.cn>, Gergo Koteles <soyer@irl.hu>,
Dell.Client.Kernel@dell.com,
ibm-acpi-devel@lists.sourceforge.net
Subject: Re: [PATCH v2 15/18] ACPI: platform_profile: Remove platform_profile_handler from exported symbols
Date: Tue, 14 Jan 2025 19:55:53 +0200 (EET) [thread overview]
Message-ID: <6a132155-b6a4-b326-5d5e-c9fcc6670265@linux.intel.com> (raw)
In-Reply-To: <i6wubniwg77joijwqo7jg3q4tv3oit7tehv5uxhgkcnwqukuom@ethn7feuyrah>
[-- Attachment #1: Type: text/plain, Size: 5174 bytes --]
On Tue, 14 Jan 2025, Kurt Borja wrote:
> On Tue, Jan 14, 2025 at 06:55:34PM +0200, Ilpo Järvinen wrote:
> > On Tue, 14 Jan 2025, Kurt Borja wrote:
> >
> > > In order to protect the platform_profile_handler from API consumers,
> > > allocate it in platform_profile_register() and modify it's signature
> > > accordingly.
> > >
> > > Remove the platform_profile_handler from all consumer drivers and
> > > replace them with a pointer to the class device, which is
> > > now returned from platform_profile_register().
> > >
> > > Replace *pprof with a pointer to the class device in the rest of
> > > exported symbols.
> > >
> > > Signed-off-by: Kurt Borja <kuurtb@gmail.com>
> > > ---
> > > -int platform_profile_register(struct platform_profile_handler *pprof, void *drvdata)
> > > +struct device *platform_profile_register(struct device *dev, const char *name,
> > > + void *drvdata,
> > > + const struct platform_profile_ops *ops)
> > > {
> > > + int minor;
> > > int err;
> > >
> > > - /* Sanity check the profile handler */
> > > - if (!pprof || !pprof->ops->profile_set || !pprof->ops->profile_get ||
> > > - !pprof->ops->probe) {
> > > + /* Sanity check */
> > > + if (!dev || !name || !ops || !ops->profile_get ||
> > > + !ops->profile_set || !ops->probe) {
> > > pr_err("platform_profile: handler is invalid\n");
> > > - return -EINVAL;
> > > + return ERR_PTR(-EINVAL);
> > > }
> > >
> > > - err = pprof->ops->probe(drvdata, pprof->choices);
> > > + struct platform_profile_handler *pprof __free(kfree) = kzalloc(
> > > + sizeof(*pprof), GFP_KERNEL);
> > > + if (!pprof)
> > > + return ERR_PTR(-ENOMEM);
> > > +
> > > + err = ops->probe(drvdata, pprof->choices);
> > > if (err < 0)
> > > - return err;
> > > + return ERR_PTR(err);
> > >
> > > if (bitmap_empty(pprof->choices, PLATFORM_PROFILE_LAST)) {
> > > pr_err("platform_profile: no available profiles\n");
> > > - return -EINVAL;
> > > + return ERR_PTR(-EINVAL);
> > > }
> > >
> > > guard(mutex)(&profile_lock);
> > >
> > > /* create class interface for individual handler */
> > > - pprof->minor = ida_alloc(&platform_profile_ida, GFP_KERNEL);
> > > - if (pprof->minor < 0)
> > > - return pprof->minor;
> > > + minor = ida_alloc(&platform_profile_ida, GFP_KERNEL);
> > > + if (minor < 0)
> > > + return ERR_PTR(minor);
> > >
> > > + pprof->name = name;
> > > + pprof->ops = ops;
> > > + pprof->minor = minor;
> > > pprof->class_dev.class = &platform_profile_class;
> > > - pprof->class_dev.parent = pprof->dev;
> > > + pprof->class_dev.parent = dev;
> > > dev_set_drvdata(&pprof->class_dev, drvdata);
> > > dev_set_name(&pprof->class_dev, "platform-profile-%d", pprof->minor);
> > > err = device_register(&pprof->class_dev);
> > > if (err) {
> > > - put_device(&pprof->class_dev);
> > > + put_device(&no_free_ptr(pprof)->class_dev);
> > > goto cleanup_ida;
> > > }
> > >
> > > @@ -504,20 +524,21 @@ int platform_profile_register(struct platform_profile_handler *pprof, void *drvd
> > > if (err)
> > > goto cleanup_cur;
> > >
> > > - return 0;
> > > + return &no_free_ptr(pprof)->class_dev;
> > >
> > > cleanup_cur:
> > > - device_unregister(&pprof->class_dev);
> > > + device_unregister(&no_free_ptr(pprof)->class_dev);
> >
> > I don't like how this is architected.
> >
> > IMO, no_free_ptr() should not appear on error/rollback paths. The pointer
> > is going to be freed despite the code just told it's not going to be
> > freed, which sends conflicting signals. Obviously, it is because this
> > function has relinquished its ownership of the pointer but as is it seems
> > a dangerous/confusing pattern.
>
> Makes sense.
>
> Quick fix would be to replace `goto cleanup_cur` with
>
> device_unregister(&no_free_ptr(pprof)->class_dev);
> goto cleanup_ida;
>
> and add a comment about ownership. Similar to the put_device() call
> above. Is this ok? If not I will think of a better way of writing this.
I think it would still be on the error path which is undesirable. While a
comment would make it understandable, it would be more logical to call
no_free_ptr() near device_register() which is when the ownership
gets transferred.
The trouble with that approach then is that no_free_ptr(pprof) will set
the pprof to NULL because of how the internal cleanup magic prevents
automatic freeing of pprof (Don't ask me how I know about that trap :-D).
I suppose you could take pointer of the pprof->class_dev into a local
variable before making the device_register() call since that is all you
need after that point?
So my suggestion is along the lines of:
/* device_register() takes the ownership of the pointer */
class_dev = &no_free_ptr(pprof)->class_dev;
err = device_register(class_dev);
...
> > > cleanup_ida:
> > > - ida_free(&platform_profile_ida, pprof->minor);
> > > + ida_free(&platform_profile_ida, minor);
> > >
> > > - return err;
> > > + return ERR_PTR(err);
> > > }
> > > EXPORT_SYMBOL_GPL(platform_profile_register);
--
i.
next prev parent reply other threads:[~2025-01-14 17:56 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-14 15:37 [PATCH v2 00/18] Hide platform_profile_handler from consumers Kurt Borja
2025-01-14 15:37 ` [PATCH v2 01/18] ACPI: platform_profile: Replace *class_dev member with class_dev Kurt Borja
2025-01-14 15:37 ` [PATCH v2 02/18] ACPI: platform_profile: Let drivers set drvdata to the class device Kurt Borja
2025-01-14 15:37 ` [PATCH v2 03/18] ACPI: platform_profile: Remove platform_profile_handler from callbacks Kurt Borja
2025-01-14 15:59 ` Mario Limonciello
2025-01-14 15:37 ` [PATCH v2 04/18] ACPI: platform_profile: Add `ops` member to handlers Kurt Borja
2025-01-14 15:37 ` [PATCH v2 05/18] ACPI: platform_profile: Add `probe` to platform_profile_ops Kurt Borja
2025-01-14 16:20 ` Mario Limonciello
2025-01-14 16:31 ` Kurt Borja
2025-01-14 16:36 ` Mario Limonciello
2025-01-14 15:37 ` [PATCH v2 06/18] platform/surface: surface_platform_profile: Use devm_platform_profile_register() Kurt Borja
2025-01-14 15:37 ` [PATCH v2 07/18] platform/x86: acer-wmi: " Kurt Borja
2025-01-14 15:37 ` [PATCH v2 08/18] platform/x86: amd: pmf: sps: " Kurt Borja
2025-01-14 15:37 ` [PATCH v2 09/18] platform/x86: asus-wmi: " Kurt Borja
2025-01-14 15:37 ` [PATCH v2 10/18] platform/x86: dell-pc: " Kurt Borja
2025-01-14 15:37 ` [PATCH v2 11/18] platform/x86: ideapad-laptop: " Kurt Borja
2025-01-14 15:37 ` [PATCH v2 12/18] platform/x86: hp-wmi: " Kurt Borja
2025-01-14 15:37 ` [PATCH v2 13/18] platform/x86: inspur_platform_profile: " Kurt Borja
2025-01-14 15:37 ` [PATCH v2 14/18] platform/x86: thinkpad_acpi: " Kurt Borja
2025-01-14 15:37 ` [PATCH v2 15/18] ACPI: platform_profile: Remove platform_profile_handler from exported symbols Kurt Borja
2025-01-14 16:22 ` Mario Limonciello
2025-01-14 16:55 ` Ilpo Järvinen
2025-01-14 17:13 ` Rafael J. Wysocki
2025-01-14 17:26 ` Kurt Borja
2025-01-14 17:55 ` Ilpo Järvinen [this message]
2025-01-15 2:45 ` Kurt Borja
2025-01-14 15:37 ` [PATCH v2 16/18] ACPI: platform_profile: Move platform_profile_handler Kurt Borja
2025-01-14 15:37 ` [PATCH v2 17/18] ACPI: platform_profile: Clean platform_profile_handler Kurt Borja
2025-01-14 15:37 ` [PATCH v2 18/18] ACPI: platform_profile: Add documentation Kurt Borja
2025-01-14 16:24 ` Mario Limonciello
2025-01-14 16:57 ` Ilpo Järvinen
2025-01-14 17:27 ` Kurt Borja
2025-01-14 17:15 ` [PATCH v2 00/18] Hide platform_profile_handler from consumers Rafael J. Wysocki
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=6a132155-b6a4-b326-5d5e-c9fcc6670265@linux.intel.com \
--to=ilpo.jarvinen@linux.intel.com \
--cc=Dell.Client.Kernel@dell.com \
--cc=Shyam-sundar.S-k@amd.com \
--cc=W_Armin@gmx.de \
--cc=aichao@kylinos.cn \
--cc=alexbelm48@gmail.com \
--cc=corentin.chary@gmail.com \
--cc=derekjohn.clark@gmail.com \
--cc=hdegoede@redhat.com \
--cc=hmh@hmh.eng.br \
--cc=ibm-acpi-devel@lists.sourceforge.net \
--cc=ike.pan@canonical.com \
--cc=jlee@suse.com \
--cc=josh@joshuagrisham.com \
--cc=kuurtb@gmail.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lsanche@lyndeno.ca \
--cc=luke@ljones.dev \
--cc=luzmaximilian@gmail.com \
--cc=mario.limonciello@amd.com \
--cc=mpearson-lenovo@squebb.ca \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=soyer@irl.hu \
/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.