Re: [PATCH RFC 12/20] ctlv: Add device and operation dispatch
From: Jason Gunthorpe
Date: Thu Oct 22 2026 - 14:43:33 EST
On Wed, Oct 21, 2026 at 02:25:05AM +0100, Jonathan Cameron wrote:
> > +struct ctlv_device *ctlv_create(struct device *parent_dev, const struct ctlv_family *family,
> > + const void *init_info)
> > +{
> > + struct ctlv_device *ctlvdev;
> > + int devnum, ret;
> > +
> > + if (!parent_dev || !family)
> > + return ERR_PTR(-EINVAL);
> > +
> > + ctlvdev = kzalloc_obj(*ctlvdev, GFP_KERNEL);
> > + if (!ctlvdev)
> > + return ERR_PTR(-ENOMEM);
> > + ctlvdev->family = family;
> > + init_rwsem(&ctlvdev->registration_lock);
> > + spin_lock_init(&ctlvdev->transition_lock);
> > + ctlv_event_device_init(ctlvdev);
> > +
> > + /* Before anything reads the schema through this device. */
> > + ret = ctlv_op_resolution_init(ctlvdev, family);
> > + if (ret)
> > + goto err_free;
> > + /* What this family's events need of every queue opened on it. */
> > + ret = ctlv_event_sizes(ctlvdev);
> > + if (ret)
> > + goto err_free;
> > + /* Before a minor is spent on a device that could not be announced. */
> > + ret = ctlv_device_uevent_check(family);
> > + if (ret)
> > + goto err_free;
> > + if (ctlvdev->dynamic_ops_count) {
> > + ctlvdev->disabled = bitmap_zalloc(ctlvdev->dynamic_ops_count, GFP_KERNEL);
> > + if (!ctlvdev->disabled) {
> > + ret = -ENOMEM;
> > + goto err_free;
> > + }
> > + }
> > + devnum = ida_alloc_max(&ctlv_device_ids, CTLV_MAX_DEVICES - 1, GFP_KERNEL);
> > + if (devnum < 0) {
> > + ret = devnum;
> > + goto err_free;
> > + }
> > +
> > + ctlvdev->dev.devt = ctlv_device_number + devnum;
> > + ctlvdev->dev.class = &ctlv_device_class;
> > + ctlvdev->dev.parent = parent_dev;
> > + device_initialize(&ctlvdev->dev);
> > + /*
> > + * The core owns the file operations, so an open holds the core module
> > + * and not the family's, which may unload while readers remain.
> > + */
> > + cdev_init(&ctlvdev->cdev, &ctlv_file_operations);
> > + ctlvdev->cdev.owner = THIS_MODULE;
> > +
> > + ret = dev_set_name(&ctlvdev->dev, "ctlv%d", devnum);
> > + if (ret)
> > + goto err_put;
> > + ret = ctlv_family_claim_add(family->schema);
> > + if (ret)
> > + goto err_put;
> > + ret = ctlv_family_privs_pre_init(ctlvdev, init_info);
> > + if (ret)
> > + goto err_put;
> > + ret = ctlv_family_privs_init(ctlvdev);
> > + if (ret)
> > + goto err_put;
> > + ctlv_op_publish_all(ctlvdev);
> > + ctlv_event_contexts_start(ctlvdev);
> > + ret = ctlv_family_privs_post_init(ctlvdev);
> > + if (ret)
> > + goto err_fini;
> > + scoped_guard(rwsem_write, &ctlvdev->registration_lock) {
> > + ret = ctlv_device_add(ctlvdev);
> > + if (!ret)
> > + ctlvdev->registered = true;
> > + }
> > + if (ret)
> > + goto err_fini;
> > + return ctlvdev;
> > +
> > +err_fini:
> > + ctlv_device_fini(ctlvdev);
> > +err_put:
> > + put_device(&ctlvdev->dev);
> > + return ERR_PTR(ret);
>
> Jason did some nice handling in the fwctl stuff for
> device alloc and hand over after device_initialize()
> (I've copied it into a few places recently :)
>
> I'd like to see something similar here as it made
> it easier to follow lifetimes etc.
This is really at the wrong layer.. Attestation subsystem is the lead
subsystem, it should be allocating the struct device memory and the
driver should see the typical
struct attestation_dev *adev;
adev = attestation_alloc()
[..]
attestation_register(adev)
Sequence in its probe function
We need the subsystem refcounted memory to exist if we are ever going
to create a kapi and common functions
Jason