gpu: nvgpu: expose device creation

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ä <kholtta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2674426
Reviewed-by: Alex Waterman <alexw@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Konsta Hölttä
2022-02-23 12:09:39 +02:00
committed by mobile promotions
parent 82df5b0219
commit f11ca4c300
2 changed files with 48 additions and 31 deletions

View File

@@ -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);
}
}

View File

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