Message ID | 20221016104126.1259809-1-gregkh@linuxfoundation.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp964304wrs; Sun, 16 Oct 2022 03:44:46 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6Do/sJkVCh6BuC25VT5qUuldP5TJtncyzodjRlBXyiMWfP7XT2lbZHaGzTz5r4+8OyXvdI X-Received: by 2002:a05:6402:5190:b0:45c:fca7:e07b with SMTP id q16-20020a056402519000b0045cfca7e07bmr5671768edd.327.1665917086005; Sun, 16 Oct 2022 03:44:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1665917086; cv=none; d=google.com; s=arc-20160816; b=mdJyS/d8bI33dh5R8VbfP7F1wjTlUfrKUr5qAzBtP4UrQq041s0ppEc/IHD+3CMP5c YZu9c8DTSA8USBmlszWaC0EyBsYDN3EEzq9+yL7N1VLqzQ2JEAifv8HWnqhY3Dt4ldGe j5uzVNV9kcnZtB9dBbo0oCP7fhth/qvUesAv7FXrQ+MKcexMYYiPbLDxGuTa7BfZcMdy 0NaoQvm1gAsS5BMJso6FVB4ufqSxnkeM3iL4LQdJdMifYKz8zme6UBUaWT5/hbEYA05Z /0i7j1VpV4R7tSyxpjTN2yx9cmiKvdr2/WTh3wtLwi4rn3tsyBjGZnCFBPmWZJ3rgAHi oTcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=Kj4eihMBsQz2lo/Oa/F35dckUdjYI8WmBODJckM10Ek=; b=iivBv0zVjgKPDdCdA5LlJ2fCZtoxZ7HfUehmjUsD/0CwvdyDCKpU5Nw9oRImyy4MH+ YoZyca3QTCnUOSO0CzkTPirYcJ0Y6vHCxjuSfy4bFfcY0j6k/DAUsAOkU6ykGsABlRUc sR5BQnpXLqkBGrO3OI1FfFZ//TJSmYQzjM7Soa3XDJr+G4ffAQEHOOaNbLrQTLA+pA5L kE8hyawcq9ES0baaZuqCYfcmBqqCkk1a6zg0Wf/ZtqPhoecvJijkb/0HYFJTc3vJhpn0 M5/uFQMe89C7R63bUpmWUJQ/frsYw34qJn3HOX/5Af4XSkAQd30KvnhMOD7nYDBRsOFU q+VQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=z8tC+p31; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id u8-20020a056402064800b00458cdba7a90si5568791edx.471.2022.10.16.03.44.21; Sun, 16 Oct 2022 03:44:45 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=z8tC+p31; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229655AbiJPKkz (ORCPT <rfc822;ouuuleilei@gmail.com> + 99 others); Sun, 16 Oct 2022 06:40:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47056 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229461AbiJPKkv (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Sun, 16 Oct 2022 06:40:51 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4F0137F9A for <linux-kernel@vger.kernel.org>; Sun, 16 Oct 2022 03:40:50 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 94C7560B20 for <linux-kernel@vger.kernel.org>; Sun, 16 Oct 2022 10:40:42 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5D24EC433C1; Sun, 16 Oct 2022 10:40:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1665916841; bh=e0P2NFf3gxuHj6cGe5/EsaIYMZCrodGLfYaOSNYuXrU=; h=From:To:Cc:Subject:Date:From; b=z8tC+p31miYKSR87ubnPmuXV52cp6ttPKPdEBJ93vsvAuGzIoHW8sBm5RZU9S13Nr Y1mv991c7jlZsTIJdwhkMtp7OS2wsftqVI6+17cLX5H1NxsDYEV2A5Dg1irCKFcS16 Q7i1rrQyp6Gghd8kYbe936GNtap/GDtFHDz0OST0= From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sakari Ailus <sakari.ailus@linux.intel.com>, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, "Rafael J. Wysocki" <rafael@kernel.org> Subject: [PATCH v2] driver core: allow kobj_to_dev() to take a const pointer Date: Sun, 16 Oct 2022 12:41:26 +0200 Message-Id: <20221016104126.1259809-1-gregkh@linuxfoundation.org> X-Mailer: git-send-email 2.38.0 MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2094; i=gregkh@linuxfoundation.org; h=from:subject; bh=e0P2NFf3gxuHj6cGe5/EsaIYMZCrodGLfYaOSNYuXrU=; b=owGbwMvMwCRo6H6F97bub03G02pJDMne9y+85V0cufbR9h6OHMH9rJNuGcq8nlTn1ZK4W8JMOiM/ /V1FRywLgyATg6yYIsuXbTxH91ccUvQytD0NM4eVCWQIAxenAExEeTLDgs1Tf17/8fKmxwaZinNr5y w5If53HzfDPCVP/nqBz3ckN+9kW7aXYbeTfd1vbQA= X-Developer-Key: i=gregkh@linuxfoundation.org; a=openpgp; fpr=F4B60CC5BF78C2214A313DCB3147D40DDB2DFB29 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1746840674318062047?= X-GMAIL-MSGID: =?utf-8?q?1746840674318062047?= |
Series |
[v2] driver core: allow kobj_to_dev() to take a const pointer
|
|
Commit Message
Greg KH
Oct. 16, 2022, 10:41 a.m. UTC
If a const * to a kobject is passed to kobj_to_dev(), we want to return
back a const * to a device as the driver core shouldn't be modifying a
constant structure. But when dealing with container_of() the pointer
const attribute is cast away, so we need to manually handle this by
determining the type of the pointer passed in to know the type of the
pointer to pass out.
Luckily _Generic can do this type of magic, and as the kernel now
supports C11 it is availble to us to handle this type of build-time type
detection.
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
v2 - use _Generic() to make this type safe as pointed out by Sakari
include/linux/device.h | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
Comments
Hi Greg, On Sun, Oct 16, 2022 at 12:41:26PM +0200, Greg Kroah-Hartman wrote: > If a const * to a kobject is passed to kobj_to_dev(), we want to return > back a const * to a device as the driver core shouldn't be modifying a > constant structure. But when dealing with container_of() the pointer > const attribute is cast away, so we need to manually handle this by > determining the type of the pointer passed in to know the type of the > pointer to pass out. Alternatively container_of() could be fixed, but that will likely produce lots of warnings currently. > > Luckily _Generic can do this type of magic, and as the kernel now > supports C11 it is availble to us to handle this type of build-time type > detection. > > Cc: Sakari Ailus <sakari.ailus@linux.intel.com> > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > Cc: "Rafael J. Wysocki" <rafael@kernel.org> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > --- > v2 - use _Generic() to make this type safe as pointed out by Sakari > > include/linux/device.h | 18 +++++++++++++++++- > 1 file changed, 17 insertions(+), 1 deletion(-) > > diff --git a/include/linux/device.h b/include/linux/device.h > index 424b55df0272..023ea50b1916 100644 > --- a/include/linux/device.h > +++ b/include/linux/device.h > @@ -680,11 +680,27 @@ struct device_link { > bool supplier_preactivated; /* Owned by consumer probe. */ > }; > > -static inline struct device *kobj_to_dev(struct kobject *kobj) > +static inline struct device *__kobj_to_dev(struct kobject *kobj) > { > return container_of(kobj, struct device, kobj); > } > > +static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj) > +{ > + return container_of(kobj, const struct device, kobj); > +} > + > +/* > + * container_of() will happily take a const * and spit back a non-const * as it > + * is just doing pointer math. But we want to be a bit more careful in the > + * driver code, so manually force any const * of a kobject to also be a const * > + * to a device. > + */ container_of() documentation has (probably?) never warned about this. Wouldn't such a comment be more appropriate there? Albeit it wouldn't be needed if container_of() were fixed. > +#define kobj_to_dev(kobj) \ > + _Generic((kobj), \ > + const struct kobject *: __kobj_to_dev_const, \ > + struct kobject *: __kobj_to_dev)(kobj) > + > /** > * device_iommu_mapped - Returns true when the device DMA is translated > * by an IOMMU
On Mon, Oct 17, 2022 at 07:54:52AM +0000, Sakari Ailus wrote: > Hi Greg, > > On Sun, Oct 16, 2022 at 12:41:26PM +0200, Greg Kroah-Hartman wrote: > > If a const * to a kobject is passed to kobj_to_dev(), we want to return > > back a const * to a device as the driver core shouldn't be modifying a > > constant structure. But when dealing with container_of() the pointer > > const attribute is cast away, so we need to manually handle this by > > determining the type of the pointer passed in to know the type of the > > pointer to pass out. > > Alternatively container_of() could be fixed, but that will likely produce > lots of warnings currently. Yeah, we can not do that because, as you found out, there's just too many warnings that it would cause. Let's work on the individual subsystems to clean them all up first before worrying about the core container_of() macro as that should fix the majority of the build warnings. > > Luckily _Generic can do this type of magic, and as the kernel now > > supports C11 it is availble to us to handle this type of build-time type > > detection. > > > > Cc: Sakari Ailus <sakari.ailus@linux.intel.com> > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > > Cc: "Rafael J. Wysocki" <rafael@kernel.org> > > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > > --- > > v2 - use _Generic() to make this type safe as pointed out by Sakari > > > > include/linux/device.h | 18 +++++++++++++++++- > > 1 file changed, 17 insertions(+), 1 deletion(-) > > > > diff --git a/include/linux/device.h b/include/linux/device.h > > index 424b55df0272..023ea50b1916 100644 > > --- a/include/linux/device.h > > +++ b/include/linux/device.h > > @@ -680,11 +680,27 @@ struct device_link { > > bool supplier_preactivated; /* Owned by consumer probe. */ > > }; > > > > -static inline struct device *kobj_to_dev(struct kobject *kobj) > > +static inline struct device *__kobj_to_dev(struct kobject *kobj) > > { > > return container_of(kobj, struct device, kobj); > > } > > > > +static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj) > > +{ > > + return container_of(kobj, const struct device, kobj); > > +} > > + > > +/* > > + * container_of() will happily take a const * and spit back a non-const * as it > > + * is just doing pointer math. But we want to be a bit more careful in the > > + * driver code, so manually force any const * of a kobject to also be a const * > > + * to a device. > > + */ > > container_of() documentation has (probably?) never warned about this. We never thought of it before :( > Wouldn't such a comment be more appropriate there? Albeit it wouldn't be > needed if container_of() were fixed. Some comment added to container_of() would be great, but that does not remove the need to keep this one. thanks, greg k-h
On Sun, Oct 16, 2022 at 12:41:26PM +0200, Greg Kroah-Hartman wrote: > If a const * to a kobject is passed to kobj_to_dev(), we want to return > back a const * to a device as the driver core shouldn't be modifying a > constant structure. But when dealing with container_of() the pointer > const attribute is cast away, so we need to manually handle this by > determining the type of the pointer passed in to know the type of the > pointer to pass out. > > Luckily _Generic can do this type of magic, and as the kernel now > supports C11 it is availble to us to handle this type of build-time type > detection. I was following this in your branch and I find it good, Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > Cc: Sakari Ailus <sakari.ailus@linux.intel.com> > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > Cc: "Rafael J. Wysocki" <rafael@kernel.org> > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > --- > v2 - use _Generic() to make this type safe as pointed out by Sakari > > include/linux/device.h | 18 +++++++++++++++++- > 1 file changed, 17 insertions(+), 1 deletion(-) > > diff --git a/include/linux/device.h b/include/linux/device.h > index 424b55df0272..023ea50b1916 100644 > --- a/include/linux/device.h > +++ b/include/linux/device.h > @@ -680,11 +680,27 @@ struct device_link { > bool supplier_preactivated; /* Owned by consumer probe. */ > }; > > -static inline struct device *kobj_to_dev(struct kobject *kobj) > +static inline struct device *__kobj_to_dev(struct kobject *kobj) > { > return container_of(kobj, struct device, kobj); > } > > +static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj) > +{ > + return container_of(kobj, const struct device, kobj); > +} > + > +/* > + * container_of() will happily take a const * and spit back a non-const * as it > + * is just doing pointer math. But we want to be a bit more careful in the > + * driver code, so manually force any const * of a kobject to also be a const * > + * to a device. > + */ > +#define kobj_to_dev(kobj) \ > + _Generic((kobj), \ > + const struct kobject *: __kobj_to_dev_const, \ > + struct kobject *: __kobj_to_dev)(kobj) > + > /** > * device_iommu_mapped - Returns true when the device DMA is translated > * by an IOMMU > -- > 2.38.0 >
Hi Greg, On Mon, Oct 17, 2022 at 10:04:14AM +0200, Greg Kroah-Hartman wrote: > On Mon, Oct 17, 2022 at 07:54:52AM +0000, Sakari Ailus wrote: > > Hi Greg, > > > > On Sun, Oct 16, 2022 at 12:41:26PM +0200, Greg Kroah-Hartman wrote: > > > If a const * to a kobject is passed to kobj_to_dev(), we want to return > > > back a const * to a device as the driver core shouldn't be modifying a > > > constant structure. But when dealing with container_of() the pointer > > > const attribute is cast away, so we need to manually handle this by > > > determining the type of the pointer passed in to know the type of the > > > pointer to pass out. > > > > Alternatively container_of() could be fixed, but that will likely produce > > lots of warnings currently. > > Yeah, we can not do that because, as you found out, there's just too > many warnings that it would cause. Let's work on the individual > subsystems to clean them all up first before worrying about the core > container_of() macro as that should fix the majority of the build > warnings. Sounds reasonable. > > > > Luckily _Generic can do this type of magic, and as the kernel now > > > supports C11 it is availble to us to handle this type of build-time type > > > detection. > > > > > > Cc: Sakari Ailus <sakari.ailus@linux.intel.com> > > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> > > > Cc: "Rafael J. Wysocki" <rafael@kernel.org> > > > Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > > > --- > > > v2 - use _Generic() to make this type safe as pointed out by Sakari > > > > > > include/linux/device.h | 18 +++++++++++++++++- > > > 1 file changed, 17 insertions(+), 1 deletion(-) > > > > > > diff --git a/include/linux/device.h b/include/linux/device.h > > > index 424b55df0272..023ea50b1916 100644 > > > --- a/include/linux/device.h > > > +++ b/include/linux/device.h > > > @@ -680,11 +680,27 @@ struct device_link { > > > bool supplier_preactivated; /* Owned by consumer probe. */ > > > }; > > > > > > -static inline struct device *kobj_to_dev(struct kobject *kobj) > > > +static inline struct device *__kobj_to_dev(struct kobject *kobj) > > > { > > > return container_of(kobj, struct device, kobj); > > > } > > > > > > +static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj) > > > +{ > > > + return container_of(kobj, const struct device, kobj); > > > +} > > > + > > > +/* > > > + * container_of() will happily take a const * and spit back a non-const * as it > > > + * is just doing pointer math. But we want to be a bit more careful in the > > > + * driver code, so manually force any const * of a kobject to also be a const * > > > + * to a device. > > > + */ > > > > container_of() documentation has (probably?) never warned about this. > > We never thought of it before :( > > > Wouldn't such a comment be more appropriate there? Albeit it wouldn't be > > needed if container_of() were fixed. > > Some comment added to container_of() would be great, but that does not > remove the need to keep this one. I can send a patch for that. For this one: Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
From: Greg Kroah-Hartman > Sent: 17 October 2022 09:04 > > On Mon, Oct 17, 2022 at 07:54:52AM +0000, Sakari Ailus wrote: > > Hi Greg, > > > > On Sun, Oct 16, 2022 at 12:41:26PM +0200, Greg Kroah-Hartman wrote: > > > If a const * to a kobject is passed to kobj_to_dev(), we want to return > > > back a const * to a device as the driver core shouldn't be modifying a > > > constant structure. But when dealing with container_of() the pointer > > > const attribute is cast away, so we need to manually handle this by > > > determining the type of the pointer passed in to know the type of the > > > pointer to pass out. > > > > Alternatively container_of() could be fixed, but that will likely produce > > lots of warnings currently. > > Yeah, we can not do that because, as you found out, there's just too > many warnings that it would cause. Let's work on the individual > subsystems to clean them all up first before worrying about the core > container_of() macro as that should fix the majority of the build > warnings. Is it possible to generate a fixed container_of() with a different name and then use that to clean up the subsystems? Then finally rename it back? That you probably be a lot less churn. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
On Mon, Oct 17, 2022 at 11:24:26AM +0000, David Laight wrote: > From: Greg Kroah-Hartman > > Sent: 17 October 2022 09:04 > > > > On Mon, Oct 17, 2022 at 07:54:52AM +0000, Sakari Ailus wrote: > > > Hi Greg, > > > > > > On Sun, Oct 16, 2022 at 12:41:26PM +0200, Greg Kroah-Hartman wrote: > > > > If a const * to a kobject is passed to kobj_to_dev(), we want to return > > > > back a const * to a device as the driver core shouldn't be modifying a > > > > constant structure. But when dealing with container_of() the pointer > > > > const attribute is cast away, so we need to manually handle this by > > > > determining the type of the pointer passed in to know the type of the > > > > pointer to pass out. > > > > > > Alternatively container_of() could be fixed, but that will likely produce > > > lots of warnings currently. > > > > Yeah, we can not do that because, as you found out, there's just too > > many warnings that it would cause. Let's work on the individual > > subsystems to clean them all up first before worrying about the core > > container_of() macro as that should fix the majority of the build > > warnings. > > Is it possible to generate a fixed container_of() with a > different name and then use that to clean up the subsystems? > Then finally rename it back? > > That you probably be a lot less churn. That's the identical churn.
diff --git a/include/linux/device.h b/include/linux/device.h index 424b55df0272..023ea50b1916 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -680,11 +680,27 @@ struct device_link { bool supplier_preactivated; /* Owned by consumer probe. */ }; -static inline struct device *kobj_to_dev(struct kobject *kobj) +static inline struct device *__kobj_to_dev(struct kobject *kobj) { return container_of(kobj, struct device, kobj); } +static inline const struct device *__kobj_to_dev_const(const struct kobject *kobj) +{ + return container_of(kobj, const struct device, kobj); +} + +/* + * container_of() will happily take a const * and spit back a non-const * as it + * is just doing pointer math. But we want to be a bit more careful in the + * driver code, so manually force any const * of a kobject to also be a const * + * to a device. + */ +#define kobj_to_dev(kobj) \ + _Generic((kobj), \ + const struct kobject *: __kobj_to_dev_const, \ + struct kobject *: __kobj_to_dev)(kobj) + /** * device_iommu_mapped - Returns true when the device DMA is translated * by an IOMMU