From f11ca4c30032a39cacc48653685c496a65ee217e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konsta=20H=C3=B6ltt=C3=A4?= Date: Wed, 23 Feb 2022 12:09:39 +0200 Subject: [PATCH] gpu: nvgpu: expose device creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow gk20a_create_device() to happen outside the main ioctl logic and rename it to have the modern nvgpu_ prefix. Add a separate function to do cdev allocation and refactor the existing two callers slightly to avoid repetition on the cdev struct initialization. As a side effect, this modification fixes the error path that used to not return an error if adding a device fails and also leaked the allocated cdev memory. Jira NVGPU-6788 Change-Id: Ia1f018b88d78fafdfcf4e95f6aa66e2368e58974 Signed-off-by: Konsta Hölttä Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2674426 Reviewed-by: Alex Waterman GVS: Gerrit_Virtual_Submit --- drivers/gpu/nvgpu/os/linux/ioctl.c | 73 +++++++++++++++++------------- drivers/gpu/nvgpu/os/linux/ioctl.h | 6 +++ 2 files changed, 48 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl.c b/drivers/gpu/nvgpu/os/linux/ioctl.c index 02b0b08de..adb8602d6 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl.c @@ -251,11 +251,10 @@ static char *nvgpu_mig_fgpu_devnode(struct device *dev, umode_t *mode) priv_data->minor_instance_id, dev_name(dev)); } -static int gk20a_create_device( +int nvgpu_create_device( struct device *dev, int devno, const char *cdev_name, struct cdev *cdev, struct device **out, - const struct file_operations *ops, struct nvgpu_class *class) { struct device *subdev; @@ -265,9 +264,6 @@ static int gk20a_create_device( nvgpu_log_fn(g, " "); - cdev_init(cdev, ops); - cdev->owner = THIS_MODULE; - err = cdev_add(cdev, devno, 1); if (err) { dev_err(dev, "failed to add %s cdev\n", cdev_name); @@ -297,6 +293,45 @@ static int gk20a_create_device( return 0; } +static int nvgpu_alloc_and_create_device( + struct device *dev, int devno, + const char *cdev_name, + const struct file_operations *ops, + struct nvgpu_class *class) +{ + struct gk20a *g = gk20a_from_dev(dev); + struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); + struct nvgpu_cdev *cdev; + int err; + + cdev = nvgpu_kzalloc(g, sizeof(*cdev)); + if (cdev == NULL) { + dev_err(dev, "failed to allocate cdev\n"); + err = -ENOMEM; + goto out; + } + + cdev_init(&cdev->cdev, ops); + cdev->cdev.owner = THIS_MODULE; + + err = nvgpu_create_device(dev, devno, cdev_name, + &cdev->cdev, &cdev->node, class); + if (err) { + goto free_cdev; + } + + cdev->class = class; + nvgpu_init_list_node(&cdev->list_entry); + nvgpu_list_add(&cdev->list_entry, &l->cdev_list_head); + + return 0; + +free_cdev: + nvgpu_kfree(g, cdev); +out: + return err; +} + void gk20a_remove_devices_and_classes(struct gk20a *g, bool power_node) { struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); @@ -568,7 +603,6 @@ int gk20a_power_node_init(struct device *dev) struct nvgpu_class *class; u32 total_cdevs; u32 num_classes; - struct nvgpu_cdev *cdev; if (!l->cdev_list_init_done) { nvgpu_init_list_node(&l->cdev_list_head); @@ -591,28 +625,17 @@ int gk20a_power_node_init(struct device *dev) l->power_cdev_region = devno; nvgpu_list_for_each_entry(class, &l->class_list_head, nvgpu_class, list_entry) { - cdev = nvgpu_kzalloc(g, sizeof(*cdev)); - if (cdev == NULL) { - dev_err(dev, "failed to allocate cdev\n"); - goto fail; - } - /* * dev_node_list[0] is the power node to issue * power-on to the GPU. */ - err = gk20a_create_device(dev, devno++, + err = nvgpu_alloc_and_create_device(dev, devno++, dev_node_list[0].name, - &cdev->cdev, &cdev->node, dev_node_list[0].fops, class); if (err) { goto fail; } - - cdev->class = class; - nvgpu_init_list_node(&cdev->list_entry); - nvgpu_list_add(&cdev->list_entry, &l->cdev_list_head); } l->power_cdevs = total_cdevs; @@ -632,7 +655,6 @@ int gk20a_user_nodes_init(struct device *dev) struct nvgpu_class *class; u32 num_cdevs, total_cdevs; u32 num_classes; - struct nvgpu_cdev *cdev; u32 cdev_index; if (!l->cdev_list_init_done) { @@ -683,24 +705,13 @@ int gk20a_user_nodes_init(struct device *dev) continue; } - cdev = nvgpu_kzalloc(g, sizeof(*cdev)); - if (cdev == NULL) { - dev_err(dev, "failed to allocate cdev\n"); - goto fail; - } - - err = gk20a_create_device(dev, devno++, + err = nvgpu_alloc_and_create_device(dev, devno++, dev_node_list[cdev_index].name, - &cdev->cdev, &cdev->node, dev_node_list[cdev_index].fops, class); if (err) { goto fail; } - - cdev->class = class; - nvgpu_init_list_node(&cdev->list_entry); - nvgpu_list_add(&cdev->list_entry, &l->cdev_list_head); } } diff --git a/drivers/gpu/nvgpu/os/linux/ioctl.h b/drivers/gpu/nvgpu/os/linux/ioctl.h index 9805a7d8d..b39d84b50 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl.h +++ b/drivers/gpu/nvgpu/os/linux/ioctl.h @@ -75,4 +75,10 @@ unsigned int nvgpu_allocate_cdev_minor(struct gk20a *g); struct gk20a *nvgpu_get_gk20a_from_cdev(struct nvgpu_cdev *cdev); u32 nvgpu_get_gpu_instance_id_from_cdev(struct gk20a *g, struct nvgpu_cdev *cdev); +int nvgpu_create_device( + struct device *dev, int devno, + const char *cdev_name, + struct cdev *cdev, struct device **out, + struct nvgpu_class *class); + #endif