From: Jonathan Cameron <Jonathan.Cameron@Huawei.com>
To: Jason Gunthorpe <jgg@nvidia.com>
Cc: Jonathan Corbet <corbet@lwn.net>,
Itay Avraham <itayavr@nvidia.com>,
Jakub Kicinski <kuba@kernel.org>,
Leon Romanovsky <leon@kernel.org>, <linux-doc@vger.kernel.org>,
<linux-rdma@vger.kernel.org>, <netdev@vger.kernel.org>,
Paolo Abeni <pabeni@redhat.com>,
Saeed Mahameed <saeedm@nvidia.com>,
Tariq Toukan <tariqt@nvidia.com>,
Andy Gospodarek <andrew.gospodarek@broadcom.com>,
Aron Silverton <aron.silverton@oracle.com>,
Dan Williams <dan.j.williams@intel.com>,
David Ahern <dsahern@kernel.org>,
Christoph Hellwig <hch@infradead.org>,
Jiri Pirko <jiri@nvidia.com>, Leonid Bloch <lbloch@nvidia.com>,
"Leon Romanovsky" <leonro@nvidia.com>,
<linux-cxl@vger.kernel.org>, <patches@lists.linux.dev>
Subject: Re: [PATCH v2 1/8] fwctl: Add basic structure for a class subsystem with a cdev
Date: Fri, 26 Jul 2024 15:30:42 +0100 [thread overview]
Message-ID: <20240726153042.00002749@Huawei.com> (raw)
In-Reply-To: <1-v2-940e479ceba9+3821-fwctl_jgg@nvidia.com>
On Mon, 24 Jun 2024 19:47:25 -0300
Jason Gunthorpe <jgg@nvidia.com> wrote:
> Create the class, character device and functions for a fwctl driver to
> un/register to the subsystem.
>
> A typical fwctl driver has a sysfs presence like:
>
> $ ls -l /dev/fwctl/fwctl0
> crw------- 1 root root 250, 0 Apr 25 19:16 /dev/fwctl/fwctl0
>
> $ ls /sys/class/fwctl/fwctl0
> dev device power subsystem uevent
>
> $ ls /sys/class/fwctl/fwctl0/device/infiniband/
> ibp0s10f0
>
> $ ls /sys/class/infiniband/ibp0s10f0/device/fwctl/
> fwctl0/
>
> $ ls /sys/devices/pci0000:00/0000:00:0a.0/fwctl/fwctl0
> dev device power subsystem uevent
>
> Which allows userspace to link all the multi-subsystem driver components
> together and learn the subsystem specific names for the device's
> components.
>
> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Hi Jason,
Mostly looking at this to get my head around what the details are,
but whilst I'm reading might as well offer some review comments.
I'm not a fan of too many mini patches as it makes it harder
to review rather than easier, but meh, I know others prefer
it this way. If you are going to do it though, comments
need to be carefully tracking what they are talking about.
Jonathan
...
> diff --git a/drivers/fwctl/main.c b/drivers/fwctl/main.c
> new file mode 100644
> index 00000000000000..6e9bf15c743b5c
> --- /dev/null
> +++ b/drivers/fwctl/main.c
> @@ -0,0 +1,177 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES
> + */
> +#define pr_fmt(fmt) "fwctl: " fmt
> +#include <linux/fwctl.h>
> +#include <linux/module.h>
> +#include <linux/slab.h>
> +#include <linux/container_of.h>
> +#include <linux/fs.h>
Trivial: Pick an ordering scheme perhaps as then we know where you'd
like new headers to be added.
> +
> +enum {
> + FWCTL_MAX_DEVICES = 256,
> +};
> +static dev_t fwctl_dev;
> +static DEFINE_IDA(fwctl_ida);
> +static struct fwctl_device *
> +_alloc_device(struct device *parent, const struct fwctl_ops *ops, size_t size)
> +{
> + struct fwctl_device *fwctl __free(kfree) = kzalloc(size, GFP_KERNEL);
> + int devnum;
> +
> + if (!fwctl)
> + return NULL;
I'd put a blank line here.
> + fwctl->dev.class = &fwctl_class;
> + fwctl->dev.parent = parent;
> +
> + devnum = ida_alloc_max(&fwctl_ida, FWCTL_MAX_DEVICES - 1, GFP_KERNEL);
> + if (devnum < 0)
> + return NULL;
> + fwctl->dev.devt = fwctl_dev + devnum;
> +
> + device_initialize(&fwctl->dev);
> + return_ptr(fwctl);
> +}
> +
> +/* Drivers use the fwctl_alloc_device() wrapper */
> +struct fwctl_device *_fwctl_alloc_device(struct device *parent,
> + const struct fwctl_ops *ops,
> + size_t size)
> +{
> + struct fwctl_device *fwctl __free(fwctl) =
> + _alloc_device(parent, ops, size);
> +
> + if (!fwctl)
> + return NULL;
> +
> + cdev_init(&fwctl->cdev, &fwctl_fops);
> + fwctl->cdev.owner = THIS_MODULE;
Owned by fwctl core, not the parent driver? Perhaps a comment on why.
I guess related to the lifetime being independent of parent driver.
> +
> + if (dev_set_name(&fwctl->dev, "fwctl%d", fwctl->dev.devt - fwctl_dev))
> + return NULL;
> +
> + fwctl->ops = ops;
> + return_ptr(fwctl);
> +}
> +EXPORT_SYMBOL_NS_GPL(_fwctl_alloc_device, FWCTL);
> +
> +/**
> + * fwctl_register - Register a new device to the subsystem
> + * @fwctl: Previously allocated fwctl_device
> + *
> + * On return the device is visible through sysfs and /dev, driver ops may be
> + * called.
> + */
> +int fwctl_register(struct fwctl_device *fwctl)
> +{
> + int ret;
> +
> + ret = cdev_device_add(&fwctl->cdev, &fwctl->dev);
> + if (ret)
> + return ret;
> + return 0;
Doesn't look like this ever gets more complex so
return cdev_device_add(...)
If you expect to see more here in near future maybe fair enough
to keep the handling as is.
> +}
> +EXPORT_SYMBOL_NS_GPL(fwctl_register, FWCTL);
> +
> +/**
> + * fwctl_unregister - Unregister a device from the subsystem
> + * @fwctl: Previously allocated and registered fwctl_device
> + *
> + * Undoes fwctl_register(). On return no driver ops will be called. The
> + * caller must still call fwctl_put() to free the fwctl.
> + *
> + * Unregister will return even if userspace still has file descriptors open.
> + * This will call ops->close_uctx() on any open FDs and after return no driver
> + * op will be called. The FDs remain open but all fops will return -ENODEV.
Perhaps bring the docs in with the support? I got (briefly) confused
by the lack of a path to close_uctx() in here.
> + *
> + * The design of fwctl allows this sort of disassociation of the driver from the
> + * subsystem primarily by keeping memory allocations owned by the core subsytem.
> + * The fwctl_device and fwctl_uctx can both be freed without requiring a driver
> + * callback. This allows the module to remain unlocked while FDs are open.
> + */
> +void fwctl_unregister(struct fwctl_device *fwctl)
> +{
> + cdev_device_del(&fwctl->cdev, &fwctl->dev);
> +
> + /*
> + * The driver module may unload after this returns, the op pointer will
> + * not be valid.
> + */
> + fwctl->ops = NULL;
I'd bring that in with the logic doing close_uctx() etc as then it will align
with the comments that I'd also suggest only adding there (patch 2 I think).
> +}
> +EXPORT_SYMBOL_NS_GPL(fwctl_unregister, FWCTL);
> diff --git a/include/linux/fwctl.h b/include/linux/fwctl.h
> new file mode 100644
> index 00000000000000..ef4eaa87c945e4
> --- /dev/null
> +++ b/include/linux/fwctl.h
> @@ -0,0 +1,68 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES
> + */
> +#ifndef __LINUX_FWCTL_H
> +#define __LINUX_FWCTL_H
> +#include <linux/device.h>
> +#include <linux/cdev.h>
> +#include <linux/cleanup.h>
> +
> +struct fwctl_device;
> +struct fwctl_uctx;
> +
> +struct fwctl_ops {
> +};
> +
> +/**
> + * struct fwctl_device - Per-driver registration struct
> + * @dev: The sysfs (class/fwctl/fwctlXX) device
> + *
> + * Each driver instance will have one of these structs with the driver
> + * private data following immeidately after. This struct is refcounted,
immediately
> + * it is freed by calling fwctl_put().
> + */
> +struct fwctl_device {
> + struct device dev;
> + /* private: */
> + struct cdev cdev;
> + const struct fwctl_ops *ops;
> +};
> +
> +struct fwctl_device *_fwctl_alloc_device(struct device *parent,
> + const struct fwctl_ops *ops,
> + size_t size);
> +/**
> + * fwctl_alloc_device - Allocate a fwctl
> + * @parent: Physical device that provides the FW interface
> + * @ops: Driver ops to register
> + * @drv_struct: 'struct driver_fwctl' that holds the struct fwctl_device
> + * @member: Name of the struct fwctl_device in @drv_struct
> + *
> + * This allocates and initializes the fwctl_device embedded in the drv_struct.
> + * Upon success the pointer must be freed via fwctl_put(). Returns NULL on
> + * failure. Returns a 'drv_struct *' on success, NULL on error.
> + */
> +#define fwctl_alloc_device(parent, ops, drv_struct, member) \
> + container_of(_fwctl_alloc_device( \
> + parent, ops, \
> + sizeof(drv_struct) + \
> + BUILD_BUG_ON_ZERO( \
> + offsetof(drv_struct, member))), \
Doesn't that fire a build_bug when the member is at the start of drv_struct?
Or do I have that backwards?
Does container_of() safely handle a NULL?
I'm staring at the definition and can't spot code to do that in 6.10
> + drv_struct, member)
> +
next prev parent reply other threads:[~2024-07-26 14:30 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-24 22:47 [PATCH v2 0/8] Introduce fwctl subystem Jason Gunthorpe
2024-06-24 22:47 ` [PATCH v2 1/8] fwctl: Add basic structure for a class subsystem with a cdev Jason Gunthorpe
2024-06-25 4:47 ` Bagas Sanjaya
2024-07-22 16:04 ` Jason Gunthorpe
2024-07-26 14:30 ` Jonathan Cameron [this message]
2024-07-29 17:30 ` Jason Gunthorpe
2024-07-30 17:15 ` Jonathan Cameron
2024-06-24 22:47 ` [PATCH v2 2/8] fwctl: Basic ioctl dispatch for the character device Jason Gunthorpe
2024-07-26 15:01 ` Jonathan Cameron
2024-07-29 17:05 ` Jason Gunthorpe
2024-07-30 17:28 ` Jonathan Cameron
2024-08-01 13:05 ` Jason Gunthorpe
2024-08-06 7:36 ` Daniel Vetter
2024-08-08 12:34 ` Jason Gunthorpe
2024-06-24 22:47 ` [PATCH v2 3/8] fwctl: FWCTL_INFO to return basic information about the device Jason Gunthorpe
2024-07-26 15:15 ` Jonathan Cameron
2024-07-29 16:35 ` Jason Gunthorpe
2024-07-30 17:34 ` Jonathan Cameron
2024-08-01 13:11 ` Jason Gunthorpe
2024-06-24 22:47 ` [PATCH v2 4/8] taint: Add TAINT_FWCTL Jason Gunthorpe
2024-06-25 19:03 ` Randy Dunlap
2024-07-10 16:04 ` Jason Gunthorpe
2024-06-24 22:47 ` [PATCH v2 5/8] fwctl: FWCTL_RPC to execute a Remote Procedure Call to device firmware Jason Gunthorpe
2024-07-26 15:30 ` Jonathan Cameron
2024-07-29 16:28 ` Jason Gunthorpe
2024-07-30 8:00 ` Leon Romanovsky
2024-08-01 12:58 ` Jason Gunthorpe
2024-08-01 17:26 ` Leon Romanovsky
2024-08-02 13:59 ` Jonathan Cameron
2024-08-02 15:57 ` Leon Romanovsky
2024-08-07 7:44 ` Oded Gabbay
2024-08-08 11:46 ` Jason Gunthorpe
2024-06-24 22:47 ` [PATCH v2 6/8] fwctl: Add documentation Jason Gunthorpe
2024-06-25 22:04 ` Randy Dunlap
2024-07-22 16:18 ` Jason Gunthorpe
2024-07-22 20:40 ` Randy Dunlap
2024-07-26 15:50 ` Jonathan Cameron
2024-07-29 16:11 ` Jason Gunthorpe
2024-08-06 8:03 ` Daniel Vetter
2024-08-08 12:24 ` Jason Gunthorpe
2024-08-09 9:21 ` Daniel Vetter
2024-06-24 22:47 ` [PATCH v2 7/8] fwctl/mlx5: Support for communicating with mlx5 fw Jason Gunthorpe
2024-07-26 16:10 ` Jonathan Cameron
2024-07-29 16:22 ` Jason Gunthorpe
2024-07-31 11:52 ` Jonathan Cameron
2024-08-01 13:25 ` Jason Gunthorpe
2024-06-24 22:47 ` [PATCH v2 8/8] mlx5: Create an auxiliary device for fwctl_mlx5 Jason Gunthorpe
2024-06-24 23:18 ` [PATCH v2 0/8] Introduce fwctl subystem Jakub Kicinski
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=20240726153042.00002749@Huawei.com \
--to=jonathan.cameron@huawei.com \
--cc=andrew.gospodarek@broadcom.com \
--cc=aron.silverton@oracle.com \
--cc=corbet@lwn.net \
--cc=dan.j.williams@intel.com \
--cc=dsahern@kernel.org \
--cc=hch@infradead.org \
--cc=itayavr@nvidia.com \
--cc=jgg@nvidia.com \
--cc=jiri@nvidia.com \
--cc=kuba@kernel.org \
--cc=lbloch@nvidia.com \
--cc=leon@kernel.org \
--cc=leonro@nvidia.com \
--cc=linux-cxl@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-rdma@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=patches@lists.linux.dev \
--cc=saeedm@nvidia.com \
--cc=tariqt@nvidia.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.