Re: [PATCH RFC 12/20] ctlv: Add device and operation dispatch

From: Jiri Pirko

Date: Fri Oct 23 2026 - 08:59:58 EST


Thu, Oct 22, 2026 at 08:43:13PM +0200, jgg@xxxxxxxx wrote:
>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)

Er, the driver would call attestation_create() which will be a wrapper
of ctvl_create. The reason is inheritance chain and each parent being
passed info to and doing its own init()


>
>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