Browse Source

kncasic: avoid duplicate nonces to be reported

Vitalii Demianets 11 years ago
parent
commit
6454ae7e3d
1 changed files with 55 additions and 43 deletions
  1. 55 43
      driver-kncasic.c

+ 55 - 43
driver-kncasic.c

@@ -72,6 +72,7 @@ struct knc_core_state {
 		int slot;
 		int slot;
 		uint32_t nonce;
 		uint32_t nonce;
 	} last_nonce;
 	} last_nonce;
+	uint32_t last_nonce_verified;
 	uint32_t works;
 	uint32_t works;
 	uint32_t shares;
 	uint32_t shares;
 	uint32_t errors;
 	uint32_t errors;
@@ -633,7 +634,7 @@ static void knc_core_failure(struct knc_core_state *core)
 }
 }
 
 
 static
 static
-void knc_core_handle_nonce(struct thr_info *thr, struct knc_core_state *core, int slot, uint32_t nonce)
+void knc_core_handle_nonce(struct thr_info *thr, struct knc_core_state *core, int slot, uint32_t nonce, bool comm_errors)
 {
 {
 	int i;
 	int i;
 	if (!slot)
 	if (!slot)
@@ -646,17 +647,23 @@ void knc_core_handle_nonce(struct thr_info *thr, struct knc_core_state *core, in
 		if (slot == core->workslot[i].slot && core->workslot[i].work) {
 		if (slot == core->workslot[i].slot && core->workslot[i].work) {
 			struct cgpu_info * const proc = core->die->proc;
 			struct cgpu_info * const proc = core->die->proc;
 			struct thr_info * const corethr = proc->thr[0];
 			struct thr_info * const corethr = proc->thr[0];
-			
-			applog(LOG_INFO, "%"PRIpreprv"[%d] found nonce %08x", proc->proc_repr, core->core, nonce);
+			char *comm_err_str = comm_errors ? " (comm error)" : "";
+
+			applog(LOG_INFO, "%"PRIpreprv"[%d] found nonce %08x%s", proc->proc_repr, core->core, nonce, comm_err_str);
 			if (submit_nonce(corethr, core->workslot[i].work, nonce)) {
 			if (submit_nonce(corethr, core->workslot[i].work, nonce)) {
-				/* Good share */
-				core->shares++;
-				core->die->knc->shares++;
-				hashes_done2(corethr, 0x100000000, NULL);
+				if (nonce != core->last_nonce_verified) {
+					/* Good share */
+					core->shares++;
+					core->die->knc->shares++;
+					hashes_done2(corethr, 0x100000000, NULL);
+					core->last_nonce_verified = nonce;
+				} else {
+					applog(LOG_INFO, "%"PRIpreprv"[%d] duplicate nonce %08x%s", proc->proc_repr, core->core, nonce, comm_err_str);
+				}
 				/* This core is useful. Ignore any errors */
 				/* This core is useful. Ignore any errors */
 				core->errors_now = 0;
 				core->errors_now = 0;
 			} else {
 			} else {
-				applog(LOG_INFO, "%"PRIpreprv"[%d] hwerror nonce %08x", proc->proc_repr, core->core, nonce);
+				applog(LOG_INFO, "%"PRIpreprv"[%d] hwerror nonce %08x%s", proc->proc_repr, core->core, nonce, comm_err_str);
 				/* Bad share */
 				/* Bad share */
 				knc_core_failure(core);
 				knc_core_failure(core);
 			}
 			}
@@ -664,7 +671,7 @@ void knc_core_handle_nonce(struct thr_info *thr, struct knc_core_state *core, in
 	}
 	}
 }
 }
 
 
-static int knc_core_process_report(struct thr_info *thr, struct knc_core_state *core, uint8_t *response)
+static int knc_core_process_report(struct thr_info *thr, struct knc_core_state *core, uint8_t *response, bool comm_errors)
 {
 {
 	struct cgpu_info * const proc = core->die->proc;
 	struct cgpu_info * const proc = core->die->proc;
 	struct knc_report *report = &core->report;
 	struct knc_report *report = &core->report;
@@ -680,45 +687,47 @@ static int knc_core_process_report(struct thr_info *thr, struct knc_core_state *
 			break;
 			break;
 	}
 	}
 	while(n-- > 0) {
 	while(n-- > 0) {
-		knc_core_handle_nonce(thr, core, report->nonce[n].slot, report->nonce[n].nonce);
+		knc_core_handle_nonce(thr, core, report->nonce[n].slot, report->nonce[n].nonce, comm_errors);
 	}
 	}
 
 
-	if (report->active_slot && core->workslot[0].slot != report->active_slot) {
-		had_event = true;
-		applog(LOG_INFO, "%"PRIpreprv"[%d]: New work %d %d / %d %d %d", proc->proc_repr, core->core, report->active_slot, report->next_slot, core->workslot[0].slot, core->workslot[1].slot, core->workslot[2].slot);
-		/* Core switched to next work */
-		if (core->workslot[0].work) {
-			core->die->knc->completed++;
-			core->completed++;
-			applog(LOG_INFO, "%"PRIpreprv"[%d]: Work completed!", proc->proc_repr, core->core);
-			KNC_FREE_WORK(core->workslot[0].work);
-		}
-		core->workslot[0] = core->workslot[1];
-		core->workslot[1].work = NULL;
-		core->workslot[1].slot = -1;
-
-		/* or did it switch directly to pending work? */
-		if (report->active_slot == core->workslot[2].slot) {
-			applog(LOG_INFO, "%"PRIpreprv"[%d]: New work %d %d %d %d (pending)", proc->proc_repr, core->core, report->active_slot, core->workslot[0].slot, core->workslot[1].slot, core->workslot[2].slot);
-			if (core->workslot[0].work)
+	if (!comm_errors) {
+		if (report->active_slot && core->workslot[0].slot != report->active_slot) {
+			had_event = true;
+			applog(LOG_INFO, "%"PRIpreprv"[%d]: New work %d %d / %d %d %d", proc->proc_repr, core->core, report->active_slot, report->next_slot, core->workslot[0].slot, core->workslot[1].slot, core->workslot[2].slot);
+			/* Core switched to next work */
+			if (core->workslot[0].work) {
+				core->die->knc->completed++;
+				core->completed++;
+				applog(LOG_INFO, "%"PRIpreprv"[%d]: Work completed!", proc->proc_repr, core->core);
 				KNC_FREE_WORK(core->workslot[0].work);
 				KNC_FREE_WORK(core->workslot[0].work);
-			core->workslot[0] = core->workslot[2];
+			}
+			core->workslot[0] = core->workslot[1];
+			core->workslot[1].work = NULL;
+			core->workslot[1].slot = -1;
+
+			/* or did it switch directly to pending work? */
+			if (report->active_slot == core->workslot[2].slot) {
+				applog(LOG_INFO, "%"PRIpreprv"[%d]: New work %d %d %d %d (pending)", proc->proc_repr, core->core, report->active_slot, core->workslot[0].slot, core->workslot[1].slot, core->workslot[2].slot);
+				if (core->workslot[0].work)
+					KNC_FREE_WORK(core->workslot[0].work);
+				core->workslot[0] = core->workslot[2];
+				core->workslot[2].work = NULL;
+				core->workslot[2].slot = -1;
+			}
+		}
+
+		if (report->next_state && core->workslot[2].slot > 0 && (core->workslot[2].slot == report->next_slot  || report->next_slot == -1)) {
+			had_event = true;
+			applog(LOG_INFO, "%"PRIpreprv"[%d]: Accepted work %d %d %d %d (pending)", proc->proc_repr, core->core, report->active_slot, core->workslot[0].slot, core->workslot[1].slot, core->workslot[2].slot);
+			/* core accepted next work */
+			if (core->workslot[1].work)
+				KNC_FREE_WORK(core->workslot[1].work);
+			core->workslot[1] = core->workslot[2];
 			core->workslot[2].work = NULL;
 			core->workslot[2].work = NULL;
 			core->workslot[2].slot = -1;
 			core->workslot[2].slot = -1;
 		}
 		}
 	}
 	}
 
 
-	if (report->next_state && core->workslot[2].slot > 0 && (core->workslot[2].slot == report->next_slot  || report->next_slot == -1)) {
-		had_event = true;
-		applog(LOG_INFO, "%"PRIpreprv"[%d]: Accepted work %d %d %d %d (pending)", proc->proc_repr, core->core, report->active_slot, core->workslot[0].slot, core->workslot[1].slot, core->workslot[2].slot);
-		/* core accepted next work */
-		if (core->workslot[1].work)
-			KNC_FREE_WORK(core->workslot[1].work);
-		core->workslot[1] = core->workslot[2];
-		core->workslot[2].work = NULL;
-		core->workslot[2].slot = -1;
-	}
-
 	if (core->workslot[2].work && knc_transfer_completed(core->die->knc, core->transfer_stamp)) {
 	if (core->workslot[2].work && knc_transfer_completed(core->die->knc, core->transfer_stamp)) {
 		had_event = true;
 		had_event = true;
 		applog(LOG_INFO, "%"PRIpreprv"[%d]: Setwork failed?", proc->proc_repr, core->core);
 		applog(LOG_INFO, "%"PRIpreprv"[%d]: Setwork failed?", proc->proc_repr, core->core);
@@ -750,11 +759,14 @@ static void knc_process_responses(struct thr_info *thr)
 			/* Invert KNC_ACCEPTED to simplify logics below */
 			/* Invert KNC_ACCEPTED to simplify logics below */
 			if (response_info->type == KNC_SETWORK && !KNC_IS_ERROR(status))
 			if (response_info->type == KNC_SETWORK && !KNC_IS_ERROR(status))
 				status ^= KNC_ACCEPTED;
 				status ^= KNC_ACCEPTED;
+			bool comm_errors = false;
 			if (core->die->version != KNC_VERSION_JUPITER && status != 0) {
 			if (core->die->version != KNC_VERSION_JUPITER && status != 0) {
-				applog(LOG_INFO, "%"PRIpreprv"[%d]: Communication error (%x / %d)", proc->proc_repr, core->core, status, i);
-				if (status == KNC_ACCEPTED) {
+				if (response_info->type == KNC_SETWORK && status == KNC_ACCEPTED) {
 					/* Core refused our work vector. Likely out of sync. Reset it */
 					/* Core refused our work vector. Likely out of sync. Reset it */
 					core->inuse = false;
 					core->inuse = false;
+				} else {
+					applog(LOG_INFO, "%"PRIpreprv"[%d]: Communication error (%x / %d)", proc->proc_repr, core->core, status, i);
+					comm_errors = true;
 				}
 				}
 				knc_core_failure(core);
 				knc_core_failure(core);
 			}
 			}
@@ -762,7 +774,7 @@ static void knc_process_responses(struct thr_info *thr)
 			case KNC_REPORT:
 			case KNC_REPORT:
 			case KNC_SETWORK:
 			case KNC_SETWORK:
 				/* Should we care about failed SETWORK explicit? Or simply handle it by next state not loaded indication in reports?  */
 				/* Should we care about failed SETWORK explicit? Or simply handle it by next state not loaded indication in reports?  */
-				knc_core_process_report(thr, core, rxbuf);
+				knc_core_process_report(thr, core, rxbuf, comm_errors);
 				break;
 				break;
 			default:
 			default:
 				break;
 				break;