Go Back   nV News Forums > Linux Support Forums > NVIDIA Linux

Newegg Daily Deals

Reply
 
Thread Tools
Old 10-14-06, 01:57 PM   #1
Couscous
Registered User
 
Join Date: Oct 2006
Posts: 2
Post [PATCH] fix PAT restoration on ACPI resume with SMP

Current PAT restoration code assume that when the acpi resume fonction is called, every processor are up. This is wrong, only the first processor is running. So PAT registers are not restored correctly on all cpu, leading to major performence loss when the process accessing the card is not on cpu 0.

Moreover the current code doesn't restore/enable PAT when a cpu is offlined/onlined while the system is running ( think about /sys/devices/system/cpu/cpuX/online ).

Here is a patch to fix this bug, it's tested on my dualcore x86_64:

Code:
--- nv.c        2006-08-02 07:21:28.000000000 +0200
+++ nv.c        2006-10-14 20:17:44.000000000 +0200
@@ -904,6 +904,10 @@
 {
     unsigned long pat1, pat2, cr4;
     unsigned long eflags;
+    long cpu = (long) info;
+
+    if(cpu && cpu != smp_processor_id())
+           return;

     NV_SAVE_FLAGS(eflags);
     NV_CLI();
@@ -924,6 +928,10 @@
 {
     unsigned long cr4;
     unsigned long eflags;
+    long cpu = (long) info;
+
+    if(cpu && cpu != smp_processor_id())
+           return;

     NV_SAVE_FLAGS(eflags);
     NV_CLI();
@@ -1222,11 +1230,44 @@
     return retval;
 }

+static int nvidia_cpu_notifier(struct notifier_block * nt, unsigned long action, void * hcpu) {
+#if defined(NV_BUILD_NV_PAT_SUPPORT)
+       long cpu = (long)hcpu;
+       switch (action) {
+               case CPU_ONLINE:
+               case CPU_DOWN_FAILED:
+                       if (!nv_pat_enabled)
+                               break;
+                       if(get_cpu() == cpu)
+                               __nv_setup_pat_entries(NULL);
+                       else
+                               smp_call_function(__nv_setup_pat_entries, hcpu, 1, 1);
+                       put_cpu();
+                       break;
+               case CPU_DOWN_PREPARE:
+                       if (!nv_pat_enabled)
+                               break;
+                       if(get_cpu() == cpu)
+                               __nv_restore_pat_entries(NULL);
+                       else
+                               smp_call_function(__nv_restore_pat_entries, hcpu, 1, 1);
+                       put_cpu();
+                       break;
+       };
+#endif
+       return NOTIFY_OK;
+}
+

 /***
  *** EXPORTS to Linux Kernel
  ***/

+static struct notifier_block nvidia_cpu_notifier_s = {
+        .notifier_call = nvidia_cpu_notifier,
+        .priority = 0
+};
+
 static int __init nvidia_init_module(void)
 {
     int rc;
@@ -1326,7 +1367,12 @@
         nv_printf(NV_DBG_ERRORS, "NVRM: pte cache allocation failed\n");
         goto failed;
     }
-
+
+    if(!register_cpu_notifier(&nvidia_cpu_notifier_s)) {
+           nv_printf(NV_DBG_ERRORS, "NVRM: unable to register cpu hotplug notifier\n");
+           goto failed;
+    }
+
     // Init the resource manager
     if (!rm_init_rm())
     {
@@ -1461,7 +1507,7 @@
                                NV_PCI_RESOURCE_SIZE(dev, NV_GPU_BAR_INDEX_REGS));
         }
     }
-
+    unregister_cpu_notifier(&nvidia_cpu_notifier_s);
     pci_unregister_driver(&nv_pci_driver);
     return rc;
 }
@@ -1491,7 +1537,7 @@
                                NV_PCI_RESOURCE_SIZE(dev, NV_GPU_BAR_INDEX_REGS));
         }
     }
-
+
     pci_unregister_driver(&nv_pci_driver);

     /* remove /proc/driver/nvidia */
@@ -1560,6 +1606,8 @@
     }
 #endif

+    unregister_cpu_notifier(&nvidia_cpu_notifier_s);
+
 #if defined(NV_ENABLE_MEM_TRACKING)
     nv_list_mem(vm_list);
     nv_list_mem(km_list);

--- nv-linux.h  2006-08-02 07:21:28.000000000 +0200
+++ nv-linux.h  2006-10-14 19:52:52.000000000 +0200
@@ -65,6 +65,9 @@
 #include <linux/poll.h>             /* poll_wait                        */
 #include <linux/delay.h>            /* mdelay, udelay                   */

+#include <linux/cpu.h>             /* cpu hotplug support              */
+#include <linux/notifier.h>        /* notifier, used by cpu hotplug    */
+
 #ifdef KERNEL_2_6
 #include <linux/sched.h>            /* suser(), capable() replacement   */
 #include <linux/moduleparam.h>      /* module_param()                   */
I don't know if I'm 100% correct with the get_cpu()/put_cpu(), and I don't know if the code compile on every kernel, but nvidia has much more testing capacity than me so ....

BTW, PAT code has an another bug with orig_pat1 and orig_pat2 which assume that there is only one cpu.
Couscous is offline   Reply With Quote
Old 10-18-06, 06:47 PM   #2
Couscous
Registered User
 
Join Date: Oct 2006
Posts: 2
Default Re: [PATCH] fix PAT restoration on ACPI resume with SMP

Any news on this ?
Couscous is offline   Reply With Quote
Old 10-30-06, 06:07 PM   #3
zander
NVIDIA Corporation
 
zander's Avatar
 
Join Date: Aug 2002
Posts: 3,740
Default Re: [PATCH] fix PAT restoration on ACPI resume with SMP

@Couscous: thank you for your report, we'll investigate.
zander is offline   Reply With Quote
Reply


Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 12:27 AM.


Powered by vBulletin® Version 3.7.1
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Copyright 1998 - 2014, nV News.