1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
diff --git a/conf/bumblebee.conf.in b/conf/bumblebee.conf.in
index a4d0717..80f861d 100644
--- a/conf/bumblebee.conf.in
+++ b/conf/bumblebee.conf.in
@@ -54,6 +54,8 @@ AllowFallbackToIGC=@CONF_FALLBACKSTART@
# Module name to load, defaults to Driver if empty or unset
KernelDriver=@CONF_DRIVER_MODULE_NVIDIA@
PMMethod=@CONF_PM_METHOD@
+# toggle kernel driver forced unloading on idle
+AlwaysUnloadKernelDriver=true
# colon-separated path to the nvidia libraries
LibraryPath=@CONF_LDPATH_NVIDIA@
# comma-separated path of the directory containing nvidia_drv.so and the
@@ -65,5 +67,7 @@ XorgConfFile=@BBCONFDIR@/xorg.conf.nvidia
[driver-nouveau]
KernelDriver=nouveau
PMMethod=@CONF_PM_METHOD@
+# toggle kernel driver forced unloading on idle
+AlwaysUnloadKernelDriver=true
XorgConfFile=@BBCONFDIR@/xorg.conf.nouveau
diff --git a/src/bbconfig.c b/src/bbconfig.c
index 1dff5e0..00c0193 100644
--- a/src/bbconfig.c
+++ b/src/bbconfig.c
@@ -458,6 +458,10 @@ void bbconfig_parse_conf_driver(GKeyFile *bbcfg, char *driver) {
g_free(module_name);
}
}
+ key = "AlwaysUnloadKernelDriver";
+ if (g_key_file_has_key(bbcfg, section, key, NULL)) {
+ bb_config.force_driver_unload = g_key_file_get_boolean(bbcfg, section, key, NULL);
+ }
key = "LibraryPath";
if (g_key_file_has_key(bbcfg, section, key, NULL)) {
free_and_set_value(&bb_config.ld_path, g_key_file_get_string(bbcfg, section, key, NULL));
diff --git a/src/bbconfig.h b/src/bbconfig.h
index 5596b64..2519c19 100644
--- a/src/bbconfig.h
+++ b/src/bbconfig.h
@@ -142,6 +142,7 @@ struct bb_config_struct {
char * module_name; /* Kernel module to be loaded for the driver.
* If empty, driver will be used. This is
* for Ubuntu which uses nvidia-current */
+ int force_driver_unload; /* Force driver unload, even without active PM method */
int card_shutdown_state;
#ifdef WITH_PIDFILE
char *pid_file; /* pid file for storing the daemons PID */
diff --git a/src/bbsecondary.c b/src/bbsecondary.c
index 71a6b73..9378b07 100644
--- a/src/bbsecondary.c
+++ b/src/bbsecondary.c
@@ -217,24 +217,31 @@ bool start_secondary(bool need_secondary) {
static void switch_and_unload(void)
{
char driver[BUFFER_SIZE];
+ int unload_driver = 0;
- if (bb_config.pm_method == PM_DISABLED && bb_status.runmode != BB_RUN_EXIT) {
+ if (bb_config.pm_method == PM_DISABLED && !bb_config.force_driver_unload && bb_status.runmode != BB_RUN_EXIT) {
/* do not disable the card if PM is disabled unless exiting */
return;
}
//if card is on and can be switched, switch it off
+ if (switcher && switcher->need_driver_unloaded) {
+ /* do not unload the drivers nor disable the card if the card is not on */
+ if (switcher->status() != SWITCH_ON) {
+ return;
+ }
+ unload_driver = 1;
+ }
+
+ if (unload_driver || bb_config.force_driver_unload) {
+ /* unload the driver loaded by the graphica card */
+ if (pci_get_driver(driver, pci_bus_id_discrete, sizeof driver)) {
+ module_unload(driver);
+ }
+ }
+
if (switcher) {
if (switcher->need_driver_unloaded) {
- /* do not unload the drivers nor disable the card if the card is not on */
- if (switcher->status() != SWITCH_ON) {
- return;
- }
- /* unload the driver loaded by the graphica card */
- if (pci_get_driver(driver, pci_bus_id_discrete, sizeof driver)) {
- module_unload(driver);
- }
-
//only turn card off if no drivers are loaded
if (pci_get_driver(NULL, pci_bus_id_discrete, 0)) {
bb_log(LOG_DEBUG, "Drivers are still loaded, unable to disable card\n");
|