Browse Source

Bugfix: opencl: Move ADL fanspeed warning messages to a new thread to get around summary-update deadlocking

gpu_fanpercent is called from opencl_api.get_statline_before, where the console lock is already held for updates to the summary area
Therefore, it cannot use applog since that requires locking the console itself

This fixes the hang reported in issue #103
Luke Dashjr 13 years ago
parent
commit
ccf77ca1ca
1 changed files with 28 additions and 8 deletions
  1. 28 8
      adl.c

+ 28 - 8
adl.c

@@ -678,6 +678,29 @@ static int __gpu_fanpercent(struct gpu_adl *ga)
 	return ga->lpFanSpeedValue.iFanSpeed;
 }
 
+/* Failure log messages are handled by another (new) thread, since
+ * gpu_fanpercent is called inside a curses UI update (which holds
+ * the console lock, and would deadlock if we tried to log from
+ * within) */
+static void *gpu_fanpercent_failure(void *userdata)
+{
+	int *data = userdata;
+	bool had_twin = data[0];
+	int gpu = data[1];
+
+	applog(LOG_WARNING, "GPU %d stopped reporting fanspeed due to driver corruption", gpu);
+	if (opt_restart) {
+		applog(LOG_WARNING, "Restart enabled, will attempt to restart BFGMiner");
+		applog(LOG_WARNING, "You can disable this with the --no-restart option");
+		app_restart();
+	}
+	applog(LOG_WARNING, "Disabling fanspeed monitoring on this device");
+	if (had_twin) {
+		applog(LOG_WARNING, "Disabling fanspeed linking on GPU twins");
+	}
+	return NULL;
+}
+
 int gpu_fanpercent(int gpu)
 {
 	struct gpu_adl *ga;
@@ -691,19 +714,16 @@ int gpu_fanpercent(int gpu)
 	ret = __gpu_fanpercent(ga);
 	unlock_adl();
 	if (unlikely(ga->has_fanspeed && ret == -1)) {
-		applog(LOG_WARNING, "GPU %d stopped reporting fanspeed due to driver corruption", gpu);
-		if (opt_restart) {
-			applog(LOG_WARNING, "Restart enabled, will attempt to restart BFGMiner");
-			applog(LOG_WARNING, "You can disable this with the --no-restart option");
-			app_restart();
-		}
-		applog(LOG_WARNING, "Disabling fanspeed monitoring on this device");
+		pthread_t thr;
+		int *data = malloc(sizeof(int) * 2);
+		data[0] = ga->twin ? 1 : 0;
+		data[1] = gpu;
 		ga->has_fanspeed = false;
 		if (ga->twin) {
-			applog(LOG_WARNING, "Disabling fanspeed linking on GPU twins");
 			ga->twin->twin = NULL;;
 			ga->twin = NULL;
 		}
+		pthread_create(&thr, NULL, gpu_fanpercent_failure, data);
 	}
 	return ret;
 }