やるきなし

2016/12/20 11:54 / nvidia-kernel-dkms 340.96-1 on Linux 4.9

nvidia-kernel-dkms 340.96-1 (Debian GNU/Linux stable) を Linux 4.9 で compile しようとすると以下のようにコケる.

/usr/src/nvidia-current-340.96/os-mlock.c:XX:XX: error: too many arguments to function ‘get_user_pages_remote’

https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=9beae1ea89305a9667ceaab6d0bf46a045ad71e7 の影響の様なので os-mlock.c の

ret = get_user_pages_remote(current, mm, (unsigned long)address,
                            page_count, write, force, user_pages, NULL);

の箇所を以下のように変更.

{
    unsigned int flags = 0;
    if(write) flags |= FOLL_WRITE;
    if(force) flags |= FOLL_FORCE;
    ret = get_user_pages_remote(current, mm, (unsigned long)address,
                                page_count, flags, user_pages, NULL);
}

実際は write=1, force=0 なので,

ret = get_user_pages_remote(current, mm, (unsigned long)address,
                            page_count, FOLL_WRITE, user_pages, NULL);

でもOKなはず.ただし compile は通るが

NVRM: failed to register procfs!
NVRM: request_mem_region failed for 16M @ 0xfa000000. This can
NVRM: occur when a driver such as rivatv is loaded and claims
NVRM: ownership of the device's registers.
NVRM: DRM init failed
NVRM: NVIDIA init module failed!

という感じで modprobe に失敗する.かつ /proc/driver/nvidia/ だけが残されて,再度 modprobe する際は

proc_dir_entry 'driver/nvidia' already registered

とか怒られたり ls /proc/driver/nvidia/ とかすると固まったりする...Linux 4.9 を諦めるか,340.96-1 ではなく backports の 367.57-2~bpo8+1を使うか...

追記(2016/12/27)

/proc/driver/nvidia/ (procfs) の部分については単に nvidia-kernel-dkms 340.96-1 の bug らしい(error handling が抜けている).以下でなんとかなる.

--- a/nv.c
+++ b/nv.c
@@ -809,13 +809,17 @@ int __init nvidia_init_module(void)
     /* create /proc/driver/nvidia/... */
     rc = nv_register_procfs();
     if (rc < 0)
+    {
         nv_printf(NV_DBG_ERRORS, "NVRM: failed to register procfs!\n");
+        rc = -ENODEV;
+        goto failed5;
+    }
 
     if (pci_register_driver(&nv_pci_driver) < 0)
     {
         rc = -ENODEV;
         nv_printf(NV_DBG_ERRORS, "NVRM: No NVIDIA graphics adapter found!\n");
-        goto failed4;
+        goto failed35;
     }
 
     if (nv_drm_init(&nv_pci_driver) < 0)
@@ -1040,6 +1044,9 @@ failed3:
 
     pci_unregister_driver(&nv_pci_driver);
 
+failed35:
+    nv_unregister_procfs();
+
 failed5:
     rm_shutdown_rm(sp);
 
 

goto failed4 の箇所は普通に goto 先を間違っているような気がする.

追記(2016/12/27)

https://devtalk.nvidia.com/default/topic/981852/linux/resolution-patch-attached-for-nvidia-linux-driver-340-98-x86_64-using-linux-kernel-4-9/ から辿れる http://pastebin.com/raw/0XE0e8Wx にある以下のパッチをあてたらうまく動くようになった.

--- kernel/nv-drm.c
+++ kernel/nv-drm.c
@@ -115,7 +115,11 @@ static const struct file_operations nv_drm_fops = {
 };

 static struct drm_driver nv_drm_driver = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
+    .driver_features = DRIVER_GEM | DRIVER_PRIME | DRIVER_LEGACY,
+#else
     .driver_features = DRIVER_GEM | DRIVER_PRIME,
+#endif
     .load = nv_drm_load,
     .unload = nv_drm_unload,
     .fops = &nv_drm_fops,

https://patchwork.freedesktop.org/patch/102820/https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=3cbf6a5deb2f4a469de7a90a3cc169e8fcba95e2 によると,drm について比較的新しい driver は DRIVER_MODESET というフラグが用いられているが,実際にこれは「DRIVER_MODERN」(新しい driver)の意味であって super confusing だから古いタイプの driver に DRIVER_LEGACY というフラグを付けることにしたらしい.

Related articles