Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use device_create to ensure /dev nodes are created correctly. #1

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion kernel-open/nvidia-drm/nvidia-drm-crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -685,14 +685,17 @@ static inline void __nv_drm_plane_atomic_destroy_state(
struct drm_plane *plane,
struct drm_plane_state *state)
{
#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
struct nv_drm_plane_state *nv_drm_plane_state;
#endif
#if defined(NV_DRM_ATOMIC_HELPER_PLANE_DESTROY_STATE_HAS_PLANE_ARG)
__drm_atomic_helper_plane_destroy_state(plane, state);
#else
__drm_atomic_helper_plane_destroy_state(state);
#endif

#if defined(NV_DRM_HAS_HDR_OUTPUT_METADATA)
struct nv_drm_plane_state *nv_drm_plane_state =
nv_drm_plane_state =
to_nv_drm_plane_state(state);
drm_property_blob_put(nv_drm_plane_state->hdr_output_metadata);
#endif
Expand Down
35 changes: 34 additions & 1 deletion kernel-open/nvidia-uvm/uvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@
#include "uvm_kvmalloc.h"

#define NVIDIA_UVM_DEVICE_NAME "nvidia-uvm"
#define NVIDIA_UVM_TOOLS_DEVICE_NAME "nvidia-uvm-tools"

static dev_t g_uvm_base_dev;
static struct cdev g_uvm_cdev;
static const struct file_operations uvm_fops;
static struct class *g_uvm_class;

bool uvm_file_is_nvidia_uvm(struct file *filp)
{
Expand Down Expand Up @@ -1093,9 +1095,19 @@ static void uvm_test_unload_state_exit(void)
}
}

static char *uvm_devnode(struct device *dev, umode_t *mode)
{
if (mode) {
*mode = 0666;
}
return NULL;
}

static int uvm_chardev_create(void)
{
dev_t uvm_dev;
dev_t tools_dev;
struct device *device;

int ret = alloc_chrdev_region(&g_uvm_base_dev,
0,
Expand All @@ -1105,9 +1117,24 @@ static int uvm_chardev_create(void)
UVM_ERR_PRINT("alloc_chrdev_region failed: %d\n", ret);
return ret;
}
uvm_dev = MKDEV(MAJOR(g_uvm_base_dev), NVIDIA_UVM_PRIMARY_MINOR_NUMBER);

uvm_dev = MKDEV(MAJOR(g_uvm_base_dev), NVIDIA_UVM_PRIMARY_MINOR_NUMBER);
uvm_init_character_device(&g_uvm_cdev, &uvm_fops);

g_uvm_class = class_create(THIS_MODULE, NVIDIA_UVM_DEVICE_NAME);
g_uvm_class->devnode = uvm_devnode;
device = device_create(g_uvm_class, NULL, uvm_dev, NULL, NVIDIA_UVM_DEVICE_NAME, NULL);
if (IS_ERR(device)) {
ret = PTR_ERR(device);
printk(KERN_WARNING "Error %d while trying to create %s", ret, NVIDIA_UVM_DEVICE_NAME);
}
tools_dev = MKDEV(MAJOR(g_uvm_base_dev), NVIDIA_UVM_TOOLS_MINOR_NUMBER);
device = device_create(g_uvm_class, NULL, tools_dev, NULL, NVIDIA_UVM_TOOLS_DEVICE_NAME, NULL);
if (IS_ERR(device)) {
ret = PTR_ERR(device);
printk(KERN_WARNING "Error %d while trying to create %s", ret, NVIDIA_UVM_TOOLS_DEVICE_NAME);
}

ret = cdev_add(&g_uvm_cdev, uvm_dev, 1);
if (ret != 0) {
UVM_ERR_PRINT("cdev_add (major %u, minor %u) failed: %d\n", MAJOR(uvm_dev), MINOR(uvm_dev), ret);
Expand All @@ -1121,6 +1148,12 @@ static int uvm_chardev_create(void)
static void uvm_chardev_exit(void)
{
cdev_del(&g_uvm_cdev);
if (g_uvm_class) {
device_destroy(g_uvm_class, MKDEV(MAJOR(g_uvm_base_dev), NVIDIA_UVM_PRIMARY_MINOR_NUMBER));
device_destroy(g_uvm_class, MKDEV(MAJOR(g_uvm_base_dev), NVIDIA_UVM_TOOLS_MINOR_NUMBER));
class_destroy(g_uvm_class);
g_uvm_class = 0;
}
unregister_chrdev_region(g_uvm_base_dev, NVIDIA_UVM_NUM_MINOR_DEVICES);
}

Expand Down
75 changes: 73 additions & 2 deletions kernel-open/nvidia/nv-frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ static struct file_operations nv_frontend_fops = {
.release = nvidia_frontend_close,
};

static struct class *g_frontend_class;

/* Helper functions */

static int add_device(nvidia_module_t *module, nv_linux_state_t *device, NvBool all)
Expand Down Expand Up @@ -120,6 +122,9 @@ static int remove_device(nvidia_module_t *module, nv_linux_state_t *device)
// remove this device from minor_number table
if ((device != NULL) && (nv_minor_num_table[device->minor_num] != NULL))
{
if (g_frontend_class) {
device_destroy(g_frontend_class, MKDEV(NV_MAJOR_DEVICE_NUMBER, device->minor_num));
}
nv_minor_num_table[device->minor_num] = NULL;
device->minor_num = 0;
rc = 0;
Expand All @@ -146,6 +151,15 @@ int nvidia_register_module(nvidia_module_t *module)
ctrl_minor_num = NV_FRONTEND_CONTROL_DEVICE_MINOR_MAX - module->instance;
nv_minor_num_table[ctrl_minor_num] = module;
nv_num_instances++;
if (g_frontend_class) {
const char *name = module->module_name;
dev_t ctl_dev = MKDEV(NV_MAJOR_DEVICE_NUMBER, ctrl_minor_num);
struct device *created = device_create(g_frontend_class, NULL, ctl_dev, NULL, name, NULL);
if (IS_ERR(created)) {
int err = PTR_ERR(created);
printk(KERN_WARNING "Error %d while trying to create %s\n", err, name, NULL);
}
}
done:
up(&nv_module_table_lock);

Expand All @@ -169,6 +183,9 @@ int nvidia_unregister_module(nvidia_module_t *module)
}
else
{
if (g_frontend_class) {
device_destroy(g_frontend_class, MKDEV(NV_MAJOR_DEVICE_NUMBER, ctrl_minor_num));
}
nv_minor_num_table[ctrl_minor_num] = NULL;
nv_num_instances--;
}
Expand Down Expand Up @@ -350,9 +367,20 @@ int nvidia_frontend_mmap(
return rc;
}

static char *frontend_devnode(struct device *dev, umode_t *mode)
{
if (mode) {
*mode = 0666;
}
return NULL;
}

static int __init nvidia_frontend_init_module(void)
{
int status = 0;
dev_t ctl_dev = MKDEV(NV_MAJOR_DEVICE_NUMBER, NV_FRONTEND_CONTROL_DEVICE_MINOR_MAX);
struct device *created;
int i, err;

// initialise nvidia module table;
nv_num_instances = 0;
Expand All @@ -366,13 +394,44 @@ static int __init nvidia_frontend_init_module(void)
}

// register char device
status = register_chrdev(NV_MAJOR_DEVICE_NUMBER, "nvidia-frontend", &nv_frontend_fops);
status = register_chrdev(NV_MAJOR_DEVICE_NUMBER, NV_FRONTEND_MODULE_NAME, &nv_frontend_fops);
if (status < 0)
{
printk("NVRM: register_chrdev() failed!\n");
nvidia_exit_module();
}

g_frontend_class = class_create(THIS_MODULE, NV_FRONTEND_MODULE_NAME);
g_frontend_class->devnode = frontend_devnode;
created = device_create(g_frontend_class, NULL, ctl_dev, NULL, NV_CONTROL_DEVICE_NAME, NULL);
if (IS_ERR(created)) {
err = PTR_ERR(created);
printk(KERN_WARNING "Error %d while trying to create %s\n", err, NV_CONTROL_DEVICE_NAME, NULL);
}
for (i = 0; i <= NV_FRONTEND_CONTROL_DEVICE_MINOR_MIN; i++)
{
if (nv_minor_num_table[i] != NULL) {
dev_t gpu_dev = MKDEV(NV_MAJOR_DEVICE_NUMBER, i);
created = device_create(g_frontend_class, NULL, gpu_dev, NULL, "nvidia%d", i, NULL);
if (IS_ERR(created)) {
int err = PTR_ERR(created);
printk(KERN_WARNING "Error %d while trying to create nvidia%d\n", err, i, NULL);
}
}
}
for (i = NV_FRONTEND_CONTROL_DEVICE_MINOR_MIN + 1; i < NV_FRONTEND_CONTROL_DEVICE_MINOR_MAX; i++)
{
const nvidia_module_t * module = nv_minor_num_table[i];
if (module != NULL) {
const char *name = module->module_name;
dev_t ctl_dev = MKDEV(NV_MAJOR_DEVICE_NUMBER, i);
struct device *created = device_create(g_frontend_class, NULL, ctl_dev, NULL, name, NULL);
if (IS_ERR(created)) {
int err = PTR_ERR(created);
printk(KERN_WARNING "Error %d while trying to create %s\n", err, name, NULL);
}
}
}
return status;
}

Expand All @@ -384,7 +443,19 @@ static void __exit nvidia_frontend_exit_module(void)
*/
if (nv_num_instances == 1)
{
unregister_chrdev(NV_MAJOR_DEVICE_NUMBER, "nvidia-frontend");
if (g_frontend_class) {
int i;
device_destroy(g_frontend_class, MKDEV(NV_MAJOR_DEVICE_NUMBER, NV_FRONTEND_CONTROL_DEVICE_MINOR_MAX));
for (i = 0; i < NV_FRONTEND_CONTROL_DEVICE_MINOR_MAX; i++)
{
if (nv_minor_num_table[i] != NULL) {
device_destroy(g_frontend_class, MKDEV(NV_MAJOR_DEVICE_NUMBER, i));
}
}
class_destroy(g_frontend_class);
g_frontend_class = NULL;
}
unregister_chrdev(NV_MAJOR_DEVICE_NUMBER, NV_FRONTEND_MODULE_NAME);
}

nvidia_exit_module();
Expand Down
3 changes: 3 additions & 0 deletions kernel-open/nvidia/nv-frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
#include "nv-linux.h"
#include "nv-register-module.h"

#define NV_FRONTEND_MODULE_NAME "nvidia-frontend"
#define NV_CONTROL_DEVICE_NAME "nvidiactl"

#define NV_MAX_MODULE_INSTANCES 8

#define NV_FRONTEND_MINOR_NUMBER(x) minor((x)->i_rdev)
Expand Down