From 407be574009b5ae51132144c045a1239425fd754 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Wed, 16 May 2012 16:26:05 -0700 Subject: [PATCH 01/38] Change write_config so that pools are saved in priority order. --- cgminer.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/cgminer.c b/cgminer.c index d8b8e6f0..14dfdaa5 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2618,15 +2618,22 @@ void remove_pool(struct pool *pool) void write_config(FILE *fcfg) { - int i; + int i = 0; + int j = 0; - /* Write pool values */ + /* Write pool values in priority order */ fputs("{\n\"pools\" : [", fcfg); - for(i = 0; i < total_pools; i++) { - fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); - fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); - fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", pools[i]->rpc_pass); - } + while(j < total_pools) { + if(pools[i]->prio == j) { + fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); + fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); + fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", pools[i]->rpc_pass); + j++; + i=0; + } + else + i++; + } fputs("\n]\n", fcfg); if (nDevs) { From 4d3cc0bc6de3e8be454851e84a6cce70b4aa9ac2 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Fri, 18 May 2012 10:57:19 -0700 Subject: [PATCH 02/38] Add check to 'i' (could be considered safer) --- cgminer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index 14dfdaa5..4e9e26b8 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2623,7 +2623,7 @@ void write_config(FILE *fcfg) /* Write pool values in priority order */ fputs("{\n\"pools\" : [", fcfg); - while(j < total_pools) { + while((j < total_pools) && (i < total_pools)) { if(pools[i]->prio == j) { fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); From 4db47aa57a3dd13f43b28fd649eb75bbe6d5d165 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Fri, 18 May 2012 17:41:18 -0700 Subject: [PATCH 03/38] Return error if BFL take longer then 10s --- driver-bitforce.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index a59338cd..13a7a9db 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -329,7 +329,7 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 usleep(4500000); i = 4500; - while (1) { + while (i < 10000) { BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { @@ -341,6 +341,12 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 usleep(10000); i += 10; } + + if (i >= 10000) { + applog(LOG_DEBUG, "BitForce took longer than 10s"); + return 0; + } + applog(LOG_DEBUG, "BitForce waited %dms until %s\n", i, pdevbuf); work->blk.nonce = 0xffffffff; if (pdevbuf[2] == '-') From cebd647f5085bbb96fc34abcabf3aea9a2f7c008 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Tue, 22 May 2012 08:10:00 -0700 Subject: [PATCH 04/38] Messing with BFL code --- api.c | 10 ++--- cgminer.c | 5 ++- driver-bitforce.c | 106 +++++++++++++++++++++++++++++++--------------- miner.h | 1 + 4 files changed, 82 insertions(+), 40 deletions(-) diff --git a/api.c b/api.c index a0c2e560..cfdd0984 100644 --- a/api.c +++ b/api.c @@ -158,7 +158,7 @@ static const char SEPARATOR = '|'; #define SEPSTR "|" static const char GPUSEP = ','; -static const char *APIVERSION = "1.10"; +static const char *APIVERSION = "1.11"; static const char *DEAD = "Dead"; static const char *SICK = "Sick"; static const char *NOSTART = "NoStart"; @@ -876,7 +876,7 @@ static void pgastatus(int pga, bool isjson) cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; - if (cgpu->deven != DEV_DISABLED) + if (cgpu->deven == DEV_ENABLED) enabled = (char *)YES; else enabled = (char *)NO; @@ -1089,7 +1089,7 @@ static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven != DEV_DISABLED) { + if (cgpu->deven == DEV_ENABLED) { strcpy(io_buffer, message(MSG_PGALRENA, id, NULL, isjson)); return; } @@ -1140,12 +1140,12 @@ static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven == DEV_DISABLED) { + if (cgpu->deven != DEV_ENABLED) { strcpy(io_buffer, message(MSG_PGALRDIS, id, NULL, isjson)); return; } - cgpu->deven = DEV_DISABLED; + cgpu->deven = DEV_IDLE; strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson)); } diff --git a/cgminer.c b/cgminer.c index 4e9e26b8..5542ed64 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3893,7 +3893,7 @@ void *miner_thread(void *userdata) tv_lastupdate = tv_end; } - if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED)) { + if (unlikely(mythr->pause || cgpu->deven == DEV_DISABLED || cgpu->deven == DEV_RECOVER)) { applog(LOG_WARNING, "Thread %d being disabled", thr_id); disabled: mythr->rolling = mythr->cgpu->rolling = 0; @@ -5130,6 +5130,9 @@ begin_bench: quit(1, "thread %d create failed", thr->id); cgpu->thread = thr; + + /* delay each start by 100ms */ + usleep(100000); } } diff --git a/driver-bitforce.c b/driver-bitforce.c index 13a7a9db..e9745e61 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -264,17 +264,41 @@ static bool bitforce_thread_prepare(struct thr_info *thr) return true; } -static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) +static uint64_t bitforce_get_temp(struct cgpu_info *bitforce) { - struct cgpu_info *bitforce = thr->cgpu; int fdDev = bitforce->device_fd; + char pdevbuf[0x100]; + char *s; + BFwrite(fdDev, "ZLX", 3); + BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + if (unlikely(!pdevbuf[0])) { + applog(LOG_ERR, "Error reading from BitForce (ZKX)"); + return 0; + } + if ((!strncasecmp(pdevbuf, "TEMP", 4)) && (s = strchr(pdevbuf + 4, ':'))) { + float temp = strtof(s + 1, NULL); + if (temp > 0) { + bitforce->temp = temp; + if (temp > bitforce->cutofftemp) { + applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id); + bitforce->deven = DEV_RECOVER; + + bitforce->device_last_not_well = time(NULL); + bitforce->device_not_well_reason = REASON_DEV_THERMAL_CUTOFF; + bitforce->dev_thermal_cutoff_count++; + } + } + } +} + + +static uint64_t bitforce_send_work(struct cgpu_info *bitforce, struct work *work) +{ + int fdDev = bitforce->device_fd; char pdevbuf[0x100]; unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>"; - int i; - char *pnoncebuf; char *s; - uint32_t nonce; BFwrite(fdDev, "ZDX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); @@ -305,30 +329,19 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 applog(LOG_ERR, "BitForce block data reports: %s", pdevbuf); return 0; } +} - BFwrite(fdDev, "ZLX", 3); - BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (ZKX)"); - return 0; - } - if ((!strncasecmp(pdevbuf, "TEMP", 4)) && (s = strchr(pdevbuf + 4, ':'))) { - float temp = strtof(s + 1, NULL); - if (temp > 0) { - bitforce->temp = temp; - if (temp > bitforce->cutofftemp) { - applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id); - bitforce->deven = DEV_RECOVER; +static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) +{ + struct cgpu_info *bitforce = thr->cgpu; + int fdDev = bitforce->device_fd; - bitforce->device_last_not_well = time(NULL); - bitforce->device_not_well_reason = REASON_DEV_THERMAL_CUTOFF; - bitforce->dev_thermal_cutoff_count++; - } - } - } + char pdevbuf[0x100]; + int i; + char *pnoncebuf; + uint32_t nonce; - usleep(4500000); - i = 4500; + i = 5000; while (i < 10000) { BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); @@ -342,15 +355,17 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 i += 10; } - if (i >= 10000) { - applog(LOG_DEBUG, "BitForce took longer than 10s"); - return 0; - } + if (i >= 10000) { + applog(LOG_DEBUG, "BitForce took longer than 10s"); + return 0; + } applog(LOG_DEBUG, "BitForce waited %dms until %s\n", i, pdevbuf); work->blk.nonce = 0xffffffff; - if (pdevbuf[2] == '-') - return 0xffffffff; + if (pdevbuf[2] == '-') + return 0xffffffff; /* No valid nonce found */ + else if (pdevbuf[0] == 'I') + return 0x1; /* Device idle */ else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) { applog(LOG_ERR, "BitForce result reports: %s", pdevbuf); return 0; @@ -363,14 +378,37 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 #ifndef __BIG_ENDIAN__ nonce = swab32(nonce); #endif - submit_nonce(thr, work, nonce); if (pnoncebuf[8] != ',') break; pnoncebuf += 9; } + + return 0xffffffff; +} - return 0xffffffff; +static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) +{ + struct cgpu_info *bitforce = thr->cgpu; + + if (bitforce->deven == DEV_ENABLED) { + if (!bitforce_send_work(bitforce, work)) + return 0; + } + + if (!bitforce_get_temp(bitforce)) + return 0; + + usleep(5000000); + +// if (bitforce->deven == DEV_IDLE) +// applog(LOG_ERR, "BitForce idle mode"); + + if (bitforce->deven == DEV_ENABLED) + return bitforce_get_result(thr, work); + else + return 0x1; + } struct device_api bitforce_api = { diff --git a/miner.h b/miner.h index 186eb9f8..8d4ea1a0 100644 --- a/miner.h +++ b/miner.h @@ -250,6 +250,7 @@ enum dev_enable { DEV_ENABLED, DEV_DISABLED, DEV_RECOVER, + DEV_IDLE, }; enum cl_kernels { From 8d2936730b5620344cf46e4e7b09a1f91d76f5ab Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Tue, 22 May 2012 15:35:10 -0700 Subject: [PATCH 05/38] Fix return values --- driver-bitforce.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/driver-bitforce.c b/driver-bitforce.c index e9745e61..52b2ffa9 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -290,6 +290,7 @@ static uint64_t bitforce_get_temp(struct cgpu_info *bitforce) } } } + return 1; } @@ -329,6 +330,7 @@ static uint64_t bitforce_send_work(struct cgpu_info *bitforce, struct work *work applog(LOG_ERR, "BitForce block data reports: %s", pdevbuf); return 0; } + return 1; } static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) From 652326c2a1e7b412c07d2532b3a5a17ba68a075e Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sat, 9 Jun 2012 19:08:10 -0700 Subject: [PATCH 06/38] Scanhash split into separate functions Some adjustment of log reporting --- driver-bitforce.c | 137 ++++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 54 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 13a7a9db..5d4c0bbe 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -37,6 +37,8 @@ #include "elist.h" #include "miner.h" +#define BITFORCE_SLEEP_US 4500000 +#define BITFORCE_SLEEP_MS (BITFORCE_SLEEP_US/1000) struct device_api bitforce_api; @@ -103,7 +105,7 @@ static bool bitforce_detect_one(const char *devpath) int fdDev = BFopen(devpath); if (unlikely(fdDev == -1)) { - applog(LOG_DEBUG, "BitForce Detect: Failed to open %s", devpath); + applog(LOG_ERR, "BitForce Detect: Failed to open %s", devpath); return false; } BFwrite(fdDev, "ZGX", 3); @@ -114,7 +116,7 @@ static bool bitforce_detect_one(const char *devpath) } BFclose(fdDev); if (unlikely(!strstr(pdevbuf, "SHA256"))) { - applog(LOG_DEBUG, "BitForce Detect: Didn't recognise BitForce on %s", devpath); + applog(LOG_ERR, "BitForce Detect: Didn't recognise BitForce on %s", devpath); return false; } @@ -264,53 +266,17 @@ static bool bitforce_thread_prepare(struct thr_info *thr) return true; } -static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) +static bool bitforce_get_temp(struct cgpu_info *bitforce) { - struct cgpu_info *bitforce = thr->cgpu; int fdDev = bitforce->device_fd; - char pdevbuf[0x100]; - unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>"; - int i; - char *pnoncebuf; char *s; - uint32_t nonce; - - BFwrite(fdDev, "ZDX", 3); - BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (ZDX)"); - return 0; - } - if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { - applog(LOG_ERR, "BitForce ZDX reports: %s", pdevbuf); - return 0; - } - - memcpy(ob + 8, work->midstate, 32); - memcpy(ob + 8 + 32, work->data + 64, 12); - BFwrite(fdDev, ob, 60); - if (opt_debug) { - s = bin2hex(ob + 8, 44); - applog(LOG_DEBUG, "BitForce block data: %s", s); - free(s); - } - - BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (block data)"); - return 0; - } - if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { - applog(LOG_ERR, "BitForce block data reports: %s", pdevbuf); - return 0; - } BFwrite(fdDev, "ZLX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (ZKX)"); - return 0; + applog(LOG_ERR, "Error reading temp from BitForce (ZLX)"); + return false; } if ((!strncasecmp(pdevbuf, "TEMP", 4)) && (s = strchr(pdevbuf + 4, ':'))) { float temp = strtof(s + 1, NULL); @@ -326,10 +292,61 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 } } } + return true; +} - usleep(4500000); - i = 4500; - while (i < 10000) { +static bool bitforce_send_work(struct thr_info *thr, struct work *work) +{ + struct cgpu_info *bitforce = thr->cgpu; + int fdDev = bitforce->device_fd; + char pdevbuf[0x100]; + unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>"; + char *s; + + BFwrite(fdDev, "ZDX", 3); + BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + if (unlikely(!pdevbuf[0])) { + applog(LOG_ERR, "Error reading from BitForce (ZDX)"); + return false; + } + if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { + applog(LOG_ERR, "BitForce ZDX reports: %s", pdevbuf); + return false; + } + + memcpy(ob + 8, work->midstate, 32); + memcpy(ob + 8 + 32, work->data + 64, 12); + BFwrite(fdDev, ob, 60); + if (opt_debug) { + s = bin2hex(ob + 8, 44); + applog(LOG_DEBUG, "BitForce block data: %s", s); + free(s); + } + + BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + if (unlikely(!pdevbuf[0])) { + applog(LOG_ERR, "Error reading from BitForce (block data)"); + return false; + } + if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { + applog(LOG_ERR, "BitForce block data reports: %s", pdevbuf); + return false; + } + return true; +} + +static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) +{ + struct cgpu_info *bitforce = thr->cgpu; + int fdDev = bitforce->device_fd; + + char pdevbuf[0x100]; + char *pnoncebuf; + uint32_t nonce; + int i; + + i = BITFORCE_SLEEP_MS; + while (1) { BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { @@ -337,23 +354,20 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 return 0; } if (pdevbuf[0] != 'B') - break; + break; usleep(10000); i += 10; } - if (i >= 10000) { - applog(LOG_DEBUG, "BitForce took longer than 10s"); - return 0; - } - applog(LOG_DEBUG, "BitForce waited %dms until %s\n", i, pdevbuf); work->blk.nonce = 0xffffffff; - if (pdevbuf[2] == '-') - return 0xffffffff; + if (pdevbuf[2] == '-') + return 0xffffffff; /* No valid nonce found */ + else if (pdevbuf[0] == 'I') + return 1; /* Device idle */ else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) { - applog(LOG_ERR, "BitForce result reports: %s", pdevbuf); - return 0; + applog(LOG_WARNING, "BitForce result reports: %s", pdevbuf); + return 1; } pnoncebuf = &pdevbuf[12]; @@ -373,6 +387,21 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 return 0xffffffff; } +static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) +{ + struct cgpu_info *bitforce = thr->cgpu; + + if (!bitforce_send_work(thr, work)) + return 0; + + if (!bitforce_get_temp(bitforce)) + return 0; + + usleep(BITFORCE_SLEEP_US); + + return bitforce_get_result(thr, work); +} + struct device_api bitforce_api = { .dname = "bitforce", .name = "BFL", From ed06c97e2e2fb277ec7e023ffaec37c038a2811c Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sat, 9 Jun 2012 19:12:29 -0700 Subject: [PATCH 07/38] Added 30s BFL hashing timeout --- driver-bitforce.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 5d4c0bbe..e2d6430e 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -39,6 +39,7 @@ #define BITFORCE_SLEEP_US 4500000 #define BITFORCE_SLEEP_MS (BITFORCE_SLEEP_US/1000) +#define BITFORCE_TIMEOUT_MS 30000 struct device_api bitforce_api; @@ -346,7 +347,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) int i; i = BITFORCE_SLEEP_MS; - while (1) { + while (i < BITFORCE_TIMEOUT_MS) { BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { @@ -358,6 +359,14 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) usleep(10000); i += 10; } + + if (i >= BITFORCE_TIMEOUT_MS) { + applog(LOG_ERR, "BitForce took longer than 30s"); + bitforce->device_last_not_well = time(NULL); + bitforce->device_not_well_reason = REASON_THREAD_ZERO_HASH; + bitforce->thread_zero_hash_count++; + return 1; + } applog(LOG_DEBUG, "BitForce waited %dms until %s\n", i, pdevbuf); work->blk.nonce = 0xffffffff; From ebeaf15f18aa92622127d8d4f0ccddfaa2e251c7 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sat, 9 Jun 2012 19:30:32 -0700 Subject: [PATCH 08/38] Added idle mode Idle is only set by pgadisable, so GPU/CPU is unaffected. For Icarus/Ztex, in scanhash the thread is immediately set disabled then returns. --- api.c | 11 +++++++---- cgminer.c | 23 ++++++++--------------- driver-icarus.c | 6 ++++++ driver-ztex.c | 6 ++++++ miner.h | 1 + 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/api.c b/api.c index b6441490..3e6501af 100644 --- a/api.c +++ b/api.c @@ -167,6 +167,7 @@ static const char *SICK = "Sick"; static const char *NOSTART = "NoStart"; static const char *DISABLED = "Disabled"; static const char *ALIVE = "Alive"; +static const char *IDLE = "Idle"; static const char *REJECTING = "Rejecting"; static const char *UNKNOWN = "Unknown"; #define _DYNAMIC "D" @@ -879,7 +880,7 @@ static void pgastatus(int pga, bool isjson) cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; - if (cgpu->deven != DEV_DISABLED) + if (cgpu->deven == DEV_ENABLED) enabled = (char *)YES; else enabled = (char *)NO; @@ -890,6 +891,8 @@ static void pgastatus(int pga, bool isjson) status = (char *)SICK; else if (cgpu->status == LIFE_NOSTART) status = (char *)NOSTART; + else if (cgpu->deven == DEV_IDLE) + status = (char *)IDLE; else status = (char *)ALIVE; @@ -1092,7 +1095,7 @@ static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven != DEV_DISABLED) { + if (cgpu->deven == DEV_ENABLED) { strcpy(io_buffer, message(MSG_PGALRENA, id, NULL, isjson)); return; } @@ -1143,12 +1146,12 @@ static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven == DEV_DISABLED) { + if (cgpu->deven != DEV_ENABLED) { strcpy(io_buffer, message(MSG_PGALRDIS, id, NULL, isjson)); return; } - cgpu->deven = DEV_DISABLED; + cgpu->deven = DEV_IDLE; strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson)); } diff --git a/cgminer.c b/cgminer.c index a9f8445a..ad1259e3 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2643,22 +2643,15 @@ void remove_pool(struct pool *pool) void write_config(FILE *fcfg) { - int i = 0; - int j = 0; + int i; - /* Write pool values in priority order */ + /* Write pool values */ fputs("{\n\"pools\" : [", fcfg); - while((j < total_pools) && (i < total_pools)) { - if(pools[i]->prio == j) { - fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); - fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); - fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", pools[i]->rpc_pass); - j++; - i=0; - } - else - i++; - } + for(i = 0; i < total_pools; i++) { + fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); + fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); + fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", pools[i]->rpc_pass); + } fputs("\n]\n", fcfg); if (nDevs) { @@ -3925,7 +3918,7 @@ void *miner_thread(void *userdata) tv_lastupdate = tv_end; } - if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED)) { + if (unlikely(mythr->pause || cgpu->deven == DEV_DISABLED || cgpu->deven == DEV_RECOVER)) { applog(LOG_WARNING, "Thread %d being disabled", thr_id); disabled: mythr->rolling = mythr->cgpu->rolling = 0; diff --git a/driver-icarus.c b/driver-icarus.c index 75ab5e3f..630b66b3 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -566,6 +566,12 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, uint32_t values; uint64_t hash_count_range; + /* Device developer can make use of idle state, until then, disable and return */ + if (thr->cgpu->deven == DEV_IDLE) { + thr->cgpu->deven = DEV_DISABLED; + return 1; + } + elapsed.tv_sec = elapsed.tv_usec = 0; icarus = thr->cgpu; diff --git a/driver-ztex.c b/driver-ztex.c index c881cd7d..91f7a7bd 100644 --- a/driver-ztex.c +++ b/driver-ztex.c @@ -199,6 +199,12 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work, bool overflow, found, rv; struct libztex_hash_data hdata[GOLDEN_BACKLOG]; + /* Device developer can make use of idle state, until then, disable and return */ + if (thr->cgpu->deven == DEV_IDLE) { + thr->cgpu->deven = DEV_DISABLED; + return 1; + } + ztex = thr->cgpu->device_ztex; memcpy(sendbuf, work->data + 64, 12); diff --git a/miner.h b/miner.h index ec9d725b..f5f7122c 100644 --- a/miner.h +++ b/miner.h @@ -250,6 +250,7 @@ enum dev_enable { DEV_ENABLED, DEV_DISABLED, DEV_RECOVER, + DEV_IDLE, }; enum cl_kernels { From ec394533a215a4221264fc71304fa935aa20780a Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sat, 9 Jun 2012 19:47:54 -0700 Subject: [PATCH 09/38] Idle mode for bitforce --- driver-bitforce.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index e2d6430e..a5fa2d48 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -284,8 +284,8 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) if (temp > 0) { bitforce->temp = temp; if (temp > bitforce->cutofftemp) { - applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id); - bitforce->deven = DEV_RECOVER; + applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, setting idle", bitforce->api->name, bitforce->device_id); + bitforce->deven = DEV_IDLE; bitforce->device_last_not_well = time(NULL); bitforce->device_not_well_reason = REASON_DEV_THERMAL_CUTOFF; @@ -399,16 +399,21 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; - - if (!bitforce_send_work(thr, work)) - return 0; + bool dev_enabled = (bitforce->deven == DEV_ENABLED); + + if (dev_enabled) + if (!bitforce_send_work(thr, work)) + return 0; if (!bitforce_get_temp(bitforce)) return 0; usleep(BITFORCE_SLEEP_US); - return bitforce_get_result(thr, work); + if (dev_enabled) + return bitforce_get_result(thr, work); + else + return 1; } struct device_api bitforce_api = { From 036a97c21a92c2da4fa6ea95a00c259040f9dacd Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sat, 9 Jun 2012 20:03:18 -0700 Subject: [PATCH 10/38] Added bitforce init and shutdown. bitforce_init closes/reopens the com port and re-initialises the unit. --- driver-bitforce.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index a5fa2d48..00eeb9c5 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -267,6 +267,44 @@ static bool bitforce_thread_prepare(struct thr_info *thr) return true; } +static bool bitforce_init(struct cgpu_info *bitforce) +{ + int fdDev = bitforce->device_fd; + char *devpath = bitforce->device_path; + char pdevbuf[0x100]; + char *s; + + BFclose(fdDev); + + fdDev = BFopen(devpath); + if (unlikely(fdDev == -1)) { + applog(LOG_ERR, "BitForce init: Failed to open %s", devpath); + return false; + } + + bitforce->device_fd = fdDev; + + BFwrite(fdDev, "ZGX", 3); + BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + if (unlikely(!pdevbuf[0])) { + applog(LOG_ERR, "Error reading from BitForce (ZGX)"); + return false; + } + + if (unlikely(!strstr(pdevbuf, "SHA256"))) { + applog(LOG_ERR, "BitForce init: Didn't recognise BitForce on %s", devpath); + return false; + } + + if (likely((!memcmp(pdevbuf, ">>>ID: ", 7)) && (s = strstr(pdevbuf + 3, ">>>")))) + { + s[0] = '\0'; + bitforce->name = strdup(pdevbuf + 7); + } + + return true; +} + static bool bitforce_get_temp(struct cgpu_info *bitforce) { int fdDev = bitforce->device_fd; @@ -359,7 +397,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) usleep(10000); i += 10; } - + if (i >= BITFORCE_TIMEOUT_MS) { applog(LOG_ERR, "BitForce took longer than 30s"); bitforce->device_last_not_well = time(NULL); @@ -400,7 +438,12 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 { struct cgpu_info *bitforce = thr->cgpu; bool dev_enabled = (bitforce->deven == DEV_ENABLED); + static enum dev_enable last_dev_state = DEV_ENABLED; + // if device has just gone from disabled to enabled, re-initialise it + if (last_dev_state == DEV_DISABLED && dev_enabled) + bitforce_init(bitforce); + if (dev_enabled) if (!bitforce_send_work(thr, work)) return 0; @@ -416,6 +459,14 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 return 1; } +static void bitforce_shutdown(struct thr_info *thr) +{ + struct cgpu_info *bitforce = thr->cgpu; + int fdDev = bitforce->device_fd; + + BFclose(fdDev); +} + struct device_api bitforce_api = { .dname = "bitforce", .name = "BFL", @@ -423,4 +474,5 @@ struct device_api bitforce_api = { .get_statline_before = get_bitforce_statline_before, .thread_prepare = bitforce_thread_prepare, .scanhash = bitforce_scanhash, + .thread_shutdown = bitforce_shutdown }; From 820d662c9d4afb4824abecb42e0be31b06533f77 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sun, 10 Jun 2012 23:11:59 -0700 Subject: [PATCH 11/38] Removed idle mode. Added watchdog thread BFL temperature monitoring. --- api.c | 19 ++++++++----------- cgminer.c | 12 +++++++++--- driver-bitforce.c | 48 ++++++++++++++++++++++++++++++++++------------- driver-icarus.c | 6 ------ driver-ztex.c | 6 ------ miner.h | 4 +++- 6 files changed, 55 insertions(+), 40 deletions(-) diff --git a/api.c b/api.c index 3e6501af..268d90a7 100644 --- a/api.c +++ b/api.c @@ -167,7 +167,6 @@ static const char *SICK = "Sick"; static const char *NOSTART = "NoStart"; static const char *DISABLED = "Disabled"; static const char *ALIVE = "Alive"; -static const char *IDLE = "Idle"; static const char *REJECTING = "Rejecting"; static const char *UNKNOWN = "Unknown"; #define _DYNAMIC "D" @@ -466,7 +465,7 @@ struct CODES { { SEVERITY_SUCC, MSG_GPUFAN, PARAM_BOTH, "Setting GPU %d fan to (%s) reported succeess" }, { SEVERITY_ERR, MSG_MISFN, PARAM_NONE, "Missing save filename parameter" }, { SEVERITY_ERR, MSG_BADFN, PARAM_STR, "Can't open or create save file '%s'" }, - { SEVERITY_SUCC, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" }, + { SEVERITY_ERR, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" }, { SEVERITY_ERR, MSG_ACCDENY, PARAM_STR, "Access denied to '%s' command" }, { SEVERITY_SUCC, MSG_ACCOK, PARAM_NONE, "Privileged access OK" }, { SEVERITY_SUCC, MSG_ENAPOOL, PARAM_POOL, "Enabling pool %d:'%s'" }, @@ -880,7 +879,7 @@ static void pgastatus(int pga, bool isjson) cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; - if (cgpu->deven == DEV_ENABLED) + if (cgpu->deven != DEV_DISABLED) enabled = (char *)YES; else enabled = (char *)NO; @@ -891,8 +890,6 @@ static void pgastatus(int pga, bool isjson) status = (char *)SICK; else if (cgpu->status == LIFE_NOSTART) status = (char *)NOSTART; - else if (cgpu->deven == DEV_IDLE) - status = (char *)IDLE; else status = (char *)ALIVE; @@ -1095,7 +1092,7 @@ static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven == DEV_ENABLED) { + if (cgpu->deven != DEV_DISABLED) { strcpy(io_buffer, message(MSG_PGALRENA, id, NULL, isjson)); return; } @@ -1146,12 +1143,12 @@ static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven != DEV_ENABLED) { + if (cgpu->deven == DEV_DISABLED) { strcpy(io_buffer, message(MSG_PGALRDIS, id, NULL, isjson)); return; } - cgpu->deven = DEV_IDLE; + cgpu->deven = DEV_DISABLED; strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson)); } @@ -1982,13 +1979,12 @@ static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson) { - char filename[PATH_MAX]; FILE *fcfg; char *ptr; if (param == NULL || *param == '\0') { - default_save_file(filename); - param = filename; + strcpy(io_buffer, message(MSG_MISFN, 0, NULL, isjson)); + return; } fcfg = fopen(param, "w"); @@ -2570,3 +2566,4 @@ die: mutex_unlock(&quit_restart_lock); } + diff --git a/cgminer.c b/cgminer.c index ad1259e3..77284cdf 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3918,7 +3918,7 @@ void *miner_thread(void *userdata) tv_lastupdate = tv_end; } - if (unlikely(mythr->pause || cgpu->deven == DEV_DISABLED || cgpu->deven == DEV_RECOVER)) { + if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED)) { applog(LOG_WARNING, "Thread %d being disabled", thr_id); disabled: mythr->rolling = mythr->cgpu->rolling = 0; @@ -4274,13 +4274,17 @@ static void *watchdog_thread(void __maybe_unused *userdata) } } -#ifdef HAVE_OPENCL for (i = 0; i < total_devices; ++i) { struct cgpu_info *cgpu = devices[i]; struct thr_info *thr = cgpu->thread; enum dev_enable *denable; int gpu; + + if (cgpu->api->get_stats) { + cgpu->api->get_stats(cgpu); + } +#ifdef HAVE_OPENCL if (cgpu->api != &opencl_api) continue; /* Use only one thread per device to determine if the GPU is healthy */ @@ -4300,6 +4304,7 @@ static void *watchdog_thread(void __maybe_unused *userdata) temp, fanpercent, fanspeed, engineclock, memclock, vddc, activity, powertune); } #endif + /* Thread is waiting on getwork or disabled */ if (thr->getwork || *denable == DEV_DISABLED) continue; @@ -4347,8 +4352,9 @@ static void *watchdog_thread(void __maybe_unused *userdata) if (opt_restart) reinit_device(thr->cgpu); } +#endif /* HAVE_OPENCL */ } -#endif + } return NULL; diff --git a/driver-bitforce.c b/driver-bitforce.c index 00eeb9c5..e930d149 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -133,6 +133,8 @@ static bool bitforce_detect_one(const char *devpath) s[0] = '\0'; bitforce->name = strdup(pdevbuf + 7); } + + mutex_init(&bitforce->dev_lock); return add_cgpu(bitforce); } @@ -284,8 +286,11 @@ static bool bitforce_init(struct cgpu_info *bitforce) bitforce->device_fd = fdDev; + mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZGX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + mutex_unlock(&bitforce->dev_lock); + if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading from BitForce (ZGX)"); return false; @@ -311,8 +316,11 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) char pdevbuf[0x100]; char *s; + mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZLX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + mutex_unlock(&bitforce->dev_lock); + if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading temp from BitForce (ZLX)"); return false; @@ -322,8 +330,8 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) if (temp > 0) { bitforce->temp = temp; if (temp > bitforce->cutofftemp) { - applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, setting idle", bitforce->api->name, bitforce->device_id); - bitforce->deven = DEV_IDLE; + applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id); + bitforce->deven = DEV_RECOVER; bitforce->device_last_not_well = time(NULL); bitforce->device_not_well_reason = REASON_DEV_THERMAL_CUTOFF; @@ -342,27 +350,30 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>"; char *s; + mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZDX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading from BitForce (ZDX)"); + mutex_unlock(&bitforce->dev_lock); return false; } if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { applog(LOG_ERR, "BitForce ZDX reports: %s", pdevbuf); + mutex_unlock(&bitforce->dev_lock); return false; } - memcpy(ob + 8, work->midstate, 32); memcpy(ob + 8 + 32, work->data + 64, 12); + BFwrite(fdDev, ob, 60); if (opt_debug) { s = bin2hex(ob + 8, 44); applog(LOG_DEBUG, "BitForce block data: %s", s); free(s); } - BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + mutex_unlock(&bitforce->dev_lock); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading from BitForce (block data)"); return false; @@ -386,10 +397,13 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) i = BITFORCE_SLEEP_MS; while (i < BITFORCE_TIMEOUT_MS) { + mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + mutex_unlock(&bitforce->dev_lock); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "Error reading from BitForce (ZFX)"); + mutex_unlock(&bitforce->dev_lock); return 0; } if (pdevbuf[0] != 'B') @@ -410,7 +424,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) work->blk.nonce = 0xffffffff; if (pdevbuf[2] == '-') return 0xffffffff; /* No valid nonce found */ - else if (pdevbuf[0] == 'I') + else if (pdevbuf[0] == 'I') return 1; /* Device idle */ else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) { applog(LOG_WARNING, "BitForce result reports: %s", pdevbuf); @@ -434,12 +448,25 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) return 0xffffffff; } +static void bitforce_shutdown(struct thr_info *thr) +{ + struct cgpu_info *bitforce = thr->cgpu; + int fdDev = bitforce->device_fd; + + BFclose(fdDev); +} + static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; bool dev_enabled = (bitforce->deven == DEV_ENABLED); static enum dev_enable last_dev_state = DEV_ENABLED; + if (bitforce->deven == DEV_DISABLED) { + bitforce_shutdown(thr); + return 1; + } + // if device has just gone from disabled to enabled, re-initialise it if (last_dev_state == DEV_DISABLED && dev_enabled) bitforce_init(bitforce); @@ -448,9 +475,6 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 if (!bitforce_send_work(thr, work)) return 0; - if (!bitforce_get_temp(bitforce)) - return 0; - usleep(BITFORCE_SLEEP_US); if (dev_enabled) @@ -459,12 +483,9 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 return 1; } -static void bitforce_shutdown(struct thr_info *thr) +static bool bitforce_get_stats(struct cgpu_info *bitforce) { - struct cgpu_info *bitforce = thr->cgpu; - int fdDev = bitforce->device_fd; - - BFclose(fdDev); + return bitforce_get_temp(bitforce); } struct device_api bitforce_api = { @@ -472,6 +493,7 @@ struct device_api bitforce_api = { .name = "BFL", .api_detect = bitforce_detect, .get_statline_before = get_bitforce_statline_before, + .get_stats = bitforce_get_stats, .thread_prepare = bitforce_thread_prepare, .scanhash = bitforce_scanhash, .thread_shutdown = bitforce_shutdown diff --git a/driver-icarus.c b/driver-icarus.c index 630b66b3..75ab5e3f 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -566,12 +566,6 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, uint32_t values; uint64_t hash_count_range; - /* Device developer can make use of idle state, until then, disable and return */ - if (thr->cgpu->deven == DEV_IDLE) { - thr->cgpu->deven = DEV_DISABLED; - return 1; - } - elapsed.tv_sec = elapsed.tv_usec = 0; icarus = thr->cgpu; diff --git a/driver-ztex.c b/driver-ztex.c index 91f7a7bd..c881cd7d 100644 --- a/driver-ztex.c +++ b/driver-ztex.c @@ -199,12 +199,6 @@ static uint64_t ztex_scanhash(struct thr_info *thr, struct work *work, bool overflow, found, rv; struct libztex_hash_data hdata[GOLDEN_BACKLOG]; - /* Device developer can make use of idle state, until then, disable and return */ - if (thr->cgpu->deven == DEV_IDLE) { - thr->cgpu->deven = DEV_DISABLED; - return 1; - } - ztex = thr->cgpu->device_ztex; memcpy(sendbuf, work->data + 64, 12); diff --git a/miner.h b/miner.h index f5f7122c..2251031b 100644 --- a/miner.h +++ b/miner.h @@ -235,6 +235,7 @@ struct device_api { void (*get_statline_before)(char*, struct cgpu_info*); void (*get_statline)(char*, struct cgpu_info*); void (*get_api_stats)(char*, struct cgpu_info*, bool); + bool (*get_stats)(struct cgpu_info*); // Thread-specific functions bool (*thread_prepare)(struct thr_info*); @@ -250,7 +251,6 @@ enum dev_enable { DEV_ENABLED, DEV_DISABLED, DEV_RECOVER, - DEV_IDLE, }; enum cl_kernels { @@ -366,6 +366,8 @@ struct cgpu_info { int dev_thermal_cutoff_count; struct cgminer_stats cgminer_stats; + + pthread_mutex_t dev_lock; }; extern bool add_cgpu(struct cgpu_info*); From 2dd7c4e1c0b4858ae643d9cc0906ca90ff5ac522 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Mon, 11 Jun 2012 13:17:59 -0700 Subject: [PATCH 12/38] Added checking of work_reset while waiting for BFL to return results --- driver-bitforce.c | 108 ++++++++-------------------------------------- 1 file changed, 19 insertions(+), 89 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index c177726b..f90e0119 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -269,9 +269,6 @@ static bool bitforce_thread_prepare(struct thr_info *thr) return true; } -<<<<<<< HEAD -static uint64_t bitforce_get_temp(struct cgpu_info *bitforce) -======= static bool bitforce_init(struct cgpu_info *bitforce) { int fdDev = bitforce->device_fd; @@ -279,6 +276,8 @@ static bool bitforce_init(struct cgpu_info *bitforce) char pdevbuf[0x100]; char *s; + applog(LOG_DEBUG, "BFL%i: Re-initalizing", bitforce->device_id); + BFclose(fdDev); fdDev = BFopen(devpath); @@ -314,28 +313,10 @@ static bool bitforce_init(struct cgpu_info *bitforce) } static bool bitforce_get_temp(struct cgpu_info *bitforce) ->>>>>>> origin/master { int fdDev = bitforce->device_fd; char pdevbuf[0x100]; char *s; -<<<<<<< HEAD - - BFwrite(fdDev, "ZLX", 3); - BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (ZKX)"); - return 0; - } - if ((!strncasecmp(pdevbuf, "TEMP", 4)) && (s = strchr(pdevbuf + 4, ':'))) { - float temp = strtof(s + 1, NULL); - if (temp > 0) { - bitforce->temp = temp; - if (temp > bitforce->cutofftemp) { - applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id); - bitforce->deven = DEV_RECOVER; - -======= mutex_lock(&bitforce->dev_lock); BFwrite(fdDev, "ZLX", 3); @@ -354,28 +335,18 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id); bitforce->deven = DEV_RECOVER; ->>>>>>> origin/master bitforce->device_last_not_well = time(NULL); bitforce->device_not_well_reason = REASON_DEV_THERMAL_CUTOFF; bitforce->dev_thermal_cutoff_count++; } } } -<<<<<<< HEAD - return 1; -} - - -static uint64_t bitforce_send_work(struct cgpu_info *bitforce, struct work *work) -{ -======= return true; } static bool bitforce_send_work(struct thr_info *thr, struct work *work) { struct cgpu_info *bitforce = thr->cgpu; ->>>>>>> origin/master int fdDev = bitforce->device_fd; char pdevbuf[0x100]; unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>"; @@ -413,11 +384,7 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) applog(LOG_ERR, "BitForce block data reports: %s", pdevbuf); return false; } -<<<<<<< HEAD - return 1; -======= return true; ->>>>>>> origin/master } static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) @@ -426,14 +393,6 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) int fdDev = bitforce->device_fd; char pdevbuf[0x100]; -<<<<<<< HEAD - int i; - char *pnoncebuf; - uint32_t nonce; - - i = 5000; - while (i < 10000) { -======= char *pnoncebuf; uint32_t nonce; int i; @@ -441,7 +400,6 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) i = BITFORCE_SLEEP_MS; while (i < BITFORCE_TIMEOUT_MS) { mutex_lock(&bitforce->dev_lock); ->>>>>>> origin/master BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); mutex_unlock(&bitforce->dev_lock); @@ -456,12 +414,6 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) i += 10; } -<<<<<<< HEAD - if (i >= 10000) { - applog(LOG_DEBUG, "BitForce took longer than 10s"); - return 0; - } -======= if (i >= BITFORCE_TIMEOUT_MS) { applog(LOG_ERR, "BitForce took longer than 30s"); bitforce->device_last_not_well = time(NULL); @@ -469,19 +421,13 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) bitforce->thread_zero_hash_count++; return 1; } ->>>>>>> origin/master applog(LOG_DEBUG, "BitForce waited %dms until %s\n", i, pdevbuf); work->blk.nonce = 0xffffffff; if (pdevbuf[2] == '-') return 0xffffffff; /* No valid nonce found */ -<<<<<<< HEAD - else if (pdevbuf[0] == 'I') - return 0x1; /* Device idle */ -======= else if (pdevbuf[0] == 'I') return 1; /* Device idle */ ->>>>>>> origin/master else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) { applog(LOG_WARNING, "BitForce result reports: %s", pdevbuf); return 1; @@ -494,37 +440,14 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) #ifndef __BIG_ENDIAN__ nonce = swab32(nonce); #endif + submit_nonce(thr, work, nonce); if (pnoncebuf[8] != ',') break; pnoncebuf += 9; } - - return 0xffffffff; -} -static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) -{ - struct cgpu_info *bitforce = thr->cgpu; - - if (bitforce->deven == DEV_ENABLED) { - if (!bitforce_send_work(bitforce, work)) - return 0; - } - - if (!bitforce_get_temp(bitforce)) - return 0; - - usleep(5000000); - -// if (bitforce->deven == DEV_IDLE) -// applog(LOG_ERR, "BitForce idle mode"); - - if (bitforce->deven == DEV_ENABLED) - return bitforce_get_result(thr, work); - else - return 0x1; - + return 0xffffffff; } static void bitforce_shutdown(struct thr_info *thr) @@ -535,11 +458,14 @@ static void bitforce_shutdown(struct thr_info *thr) BFclose(fdDev); } +#define CHECK_INTERVAL_MS 200 + static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; bool dev_enabled = (bitforce->deven == DEV_ENABLED); static enum dev_enable last_dev_state = DEV_ENABLED; + int wait_ms = 0; if (bitforce->deven == DEV_DISABLED) { bitforce_shutdown(thr); @@ -549,17 +475,21 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 // if device has just gone from disabled to enabled, re-initialise it if (last_dev_state == DEV_DISABLED && dev_enabled) bitforce_init(bitforce); + last_dev_state = bitforce->deven; - if (dev_enabled) - if (!bitforce_send_work(thr, work)) - return 0; + if (!bitforce_send_work(thr, work)) + return 0; - usleep(BITFORCE_SLEEP_US); + while (wait_ms < BITFORCE_SLEEP_MS) { + usleep(CHECK_INTERVAL_MS * 1000); + wait_ms += CHECK_INTERVAL_MS; + if (work_restart[thr->id].restart) { + applog(LOG_DEBUG, "BFL%i: New work detected, discarding current job", bitforce->device_id); + return 1; //we have discard all work; equivilent to 0 hashes done. + } + } - if (dev_enabled) - return bitforce_get_result(thr, work); - else - return 1; + return bitforce_get_result(thr, work); } static bool bitforce_get_stats(struct cgpu_info *bitforce) From 2384d0fbc6b2040507dd1af8c45cd297ed5526e1 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Tue, 12 Jun 2012 18:20:18 -0700 Subject: [PATCH 13/38] Removed idle mode... again!? Changed work_reset rate to every 100ms & use defines rather than numerics. Change total sleep time to 4300ms after performance testing/measurement (now good to 916MH/s). Changed timeout to 15s - Throttle time is 15s. Added support for 'Busy' when submitting work. Improved logging text to include device identifier. Added a thread_enable api function, called when a thread is re-enabled. ... and removed useless re-init inside scanhash. Use modminer introduced mutex. --- api.c | 16 +++--- cgminer.c | 3 +- driver-bitforce.c | 140 ++++++++++++++++++++++++---------------------- miner.h | 4 +- 4 files changed, 83 insertions(+), 80 deletions(-) diff --git a/api.c b/api.c index c71b9498..6a4d7156 100644 --- a/api.c +++ b/api.c @@ -465,7 +465,7 @@ struct CODES { { SEVERITY_SUCC, MSG_GPUFAN, PARAM_BOTH, "Setting GPU %d fan to (%s) reported succeess" }, { SEVERITY_ERR, MSG_MISFN, PARAM_NONE, "Missing save filename parameter" }, { SEVERITY_ERR, MSG_BADFN, PARAM_STR, "Can't open or create save file '%s'" }, - { SEVERITY_ERR, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" }, + { SEVERITY_SUCC, MSG_SAVED, PARAM_STR, "Configuration saved to file '%s'" }, { SEVERITY_ERR, MSG_ACCDENY, PARAM_STR, "Access denied to '%s' command" }, { SEVERITY_SUCC, MSG_ACCOK, PARAM_NONE, "Privileged access OK" }, { SEVERITY_SUCC, MSG_ENAPOOL, PARAM_POOL, "Enabling pool %d:'%s'" }, @@ -879,7 +879,7 @@ static void pgastatus(int pga, bool isjson) cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60; - if (cgpu->deven == DEV_ENABLED) + if (cgpu->deven != DEV_DISABLED) enabled = (char *)YES; else enabled = (char *)NO; @@ -1092,7 +1092,7 @@ static void pgaenable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven == DEV_ENABLED) { + if (cgpu->deven != DEV_DISABLED) { strcpy(io_buffer, message(MSG_PGALRENA, id, NULL, isjson)); return; } @@ -1143,12 +1143,12 @@ static void pgadisable(__maybe_unused SOCKETTYPE c, char *param, bool isjson) struct cgpu_info *cgpu = devices[dev]; - if (cgpu->deven != DEV_ENABLED) { + if (cgpu->deven == DEV_DISABLED) { strcpy(io_buffer, message(MSG_PGALRDIS, id, NULL, isjson)); return; } - cgpu->deven = DEV_IDLE; + cgpu->deven = DEV_DISABLED; strcpy(io_buffer, message(MSG_PGADIS, id, NULL, isjson)); } @@ -1979,12 +1979,13 @@ static void devdetails(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, void dosave(__maybe_unused SOCKETTYPE c, char *param, bool isjson) { + char filename[PATH_MAX]; FILE *fcfg; char *ptr; if (param == NULL || *param == '\0') { - strcpy(io_buffer, message(MSG_MISFN, 0, NULL, isjson)); - return; + default_save_file(filename); + param = filename; } fcfg = fopen(param, "w"); @@ -2584,4 +2585,3 @@ die: mutex_unlock(&quit_restart_lock); } - diff --git a/cgminer.c b/cgminer.c index d12a009f..ceda7a62 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3959,7 +3959,7 @@ void *miner_thread(void *userdata) tv_lastupdate = tv_end; } - if (unlikely(mythr->pause || cgpu->deven == DEV_DISABLED || cgpu->deven == DEV_RECOVER)) { + if (unlikely(mythr->pause || cgpu->deven != DEV_ENABLED)) { applog(LOG_WARNING, "Thread %d being disabled", thr_id); disabled: mythr->rolling = mythr->cgpu->rolling = 0; @@ -3968,6 +3968,7 @@ disabled: tq_pop(mythr->q, NULL); /* Ignore ping that's popped */ thread_reportin(mythr); applog(LOG_WARNING, "Thread %d being re-enabled", thr_id); + if (api->thread_enable) api->thread_enable(mythr); } sdiff.tv_sec = sdiff.tv_usec = 0; diff --git a/driver-bitforce.c b/driver-bitforce.c index 8067cca1..0a2fc82e 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -20,9 +20,13 @@ #include "fpgautils.h" #include "miner.h" -#define BITFORCE_SLEEP_US 4500000 -#define BITFORCE_SLEEP_MS (BITFORCE_SLEEP_US/1000) -#define BITFORCE_TIMEOUT_MS 30000 +/* @832MH/s wait time is ~4500ms + @864MH/s wait time is ~4430ms +-> @896MH/s wait time will be ~4350ms */ +#define BITFORCE_SLEEP_MS 4300 +#define BITFORCE_TIMEOUT_MS 15000 +#define BITFORCE_CHECK_INTERVAL_MS 10 +#define WORK_CHECK_INTERVAL_MS 100 struct device_api bitforce_api; @@ -44,7 +48,7 @@ static ssize_t BFwrite2(int fd, const void *buf, ssize_t bufLen) #define BFwrite(fd, buf, bufLen) do { \ if ((bufLen) != BFwrite2(fd, buf, bufLen)) { \ - applog(LOG_ERR, "Error writing to BitForce (" #buf ")"); \ + applog(LOG_ERR, "BFL: Error writing (" #buf ")"); \ return 0; \ } \ } while(0) @@ -58,18 +62,18 @@ static bool bitforce_detect_one(const char *devpath) int fdDev = BFopen(devpath); if (unlikely(fdDev == -1)) { - applog(LOG_ERR, "BitForce Detect: Failed to open %s", devpath); + applog(LOG_ERR, "BFL: Failed to open %s", devpath); return false; } BFwrite(fdDev, "ZGX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (ZGX)"); + applog(LOG_ERR, "BFL: Error reading (ZGX)"); return 0; } BFclose(fdDev); if (unlikely(!strstr(pdevbuf, "SHA256"))) { - applog(LOG_ERR, "BitForce Detect: Didn't recognise BitForce on %s", devpath); + applog(LOG_ERR, "BFL: Didn't recognise BitForce on %s", devpath); return false; } @@ -86,7 +90,7 @@ static bool bitforce_detect_one(const char *devpath) bitforce->name = strdup(pdevbuf + 7); } - mutex_init(&bitforce->dev_lock); + mutex_init(&bitforce->device_mutex); return add_cgpu(bitforce); } @@ -122,13 +126,13 @@ static bool bitforce_thread_prepare(struct thr_info *thr) int fdDev = BFopen(bitforce->device_path); if (unlikely(-1 == fdDev)) { - applog(LOG_ERR, "Failed to open BitForce on %s", bitforce->device_path); + applog(LOG_ERR, "BFL%i: Failed to open %s", bitforce->device_id, bitforce->device_path); return false; } bitforce->device_fd = fdDev; - applog(LOG_INFO, "Opened BitForce on %s", bitforce->device_path); + applog(LOG_INFO, "BFL%i: Opened %s", bitforce->device_id, bitforce->device_path); gettimeofday(&now, NULL); get_datestamp(bitforce->init, &now); @@ -142,30 +146,33 @@ static bool bitforce_init(struct cgpu_info *bitforce) char pdevbuf[0x100]; char *s; - applog(LOG_DEBUG, "BFL%i: Re-initalizing", bitforce->device_id); + applog(LOG_INFO, "BFL%i: Re-initalizing", bitforce->device_id); - BFclose(fdDev); + if (fdDev) { + BFclose(fdDev); + bitforce->device_fd = 0; + } fdDev = BFopen(devpath); if (unlikely(fdDev == -1)) { - applog(LOG_ERR, "BitForce init: Failed to open %s", devpath); + applog(LOG_ERR, "BFL%i: Failed to open %s", bitforce->device_id, devpath); return false; } bitforce->device_fd = fdDev; - mutex_lock(&bitforce->dev_lock); + mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZGX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - mutex_unlock(&bitforce->dev_lock); + mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (ZGX)"); + applog(LOG_ERR, "BFL%i: Error reading (ZGX)", bitforce->device_id); return false; } if (unlikely(!strstr(pdevbuf, "SHA256"))) { - applog(LOG_ERR, "BitForce init: Didn't recognise BitForce on %s", devpath); + applog(LOG_ERR, "BFL%i: Didn't recognise BitForce on %s", bitforce->device_id, devpath); return false; } @@ -184,13 +191,13 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) char pdevbuf[0x100]; char *s; - mutex_lock(&bitforce->dev_lock); + mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZLX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - mutex_unlock(&bitforce->dev_lock); + mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading temp from BitForce (ZLX)"); + applog(LOG_ERR, "BFL%i: Error reading (ZLX)", bitforce->device_id); return false; } if ((!strncasecmp(pdevbuf, "TEMP", 4)) && (s = strchr(pdevbuf + 4, ':'))) { @@ -198,7 +205,7 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) if (temp > 0) { bitforce->temp = temp; if (temp > bitforce->cutofftemp) { - applog(LOG_WARNING, "Hit thermal cutoff limit on %s %d, disabling!", bitforce->api->name, bitforce->device_id); + applog(LOG_WARNING, "BFL%i: Hit thermal cutoff limit, disabling!", bitforce->device_id); bitforce->deven = DEV_RECOVER; bitforce->device_last_not_well = time(NULL); @@ -218,17 +225,22 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>"; char *s; - mutex_lock(&bitforce->dev_lock); + mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZDX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (ZDX)"); - mutex_unlock(&bitforce->dev_lock); + applog(LOG_ERR, "BFL%i: Error reading (ZDX)", bitforce->device_id); + mutex_unlock(&bitforce->device_mutex); return false; } - if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { - applog(LOG_ERR, "BitForce ZDX reports: %s", pdevbuf); - mutex_unlock(&bitforce->dev_lock); + if (pdevbuf[0] == 'B'){ + applog(LOG_WARNING, "BFL%i: Throttling", bitforce->device_id); + mutex_unlock(&bitforce->device_mutex); + return true; + } + else if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { + applog(LOG_ERR, "BFL%i: ZDX reports: %s", bitforce->device_id, pdevbuf); + mutex_unlock(&bitforce->device_mutex); return false; } memcpy(ob + 8, work->midstate, 32); @@ -237,17 +249,17 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) BFwrite(fdDev, ob, 60); if (opt_debug) { s = bin2hex(ob + 8, 44); - applog(LOG_DEBUG, "BitForce block data: %s", s); + applog(LOG_DEBUG, "BFL%i: block data: %s", bitforce->device_id, s); free(s); } BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - mutex_unlock(&bitforce->dev_lock); + mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (block data)"); + applog(LOG_ERR, "BFL%i: Error reading (block data)", bitforce->device_id); return false; } if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { - applog(LOG_ERR, "BitForce block data reports: %s", pdevbuf); + applog(LOG_ERR, "BFL%i: block data reports: %s", bitforce->device_id, pdevbuf); return false; } return true; @@ -261,41 +273,39 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) char pdevbuf[0x100]; char *pnoncebuf; uint32_t nonce; - int i; + unsigned int wait_ms = BITFORCE_SLEEP_MS; - i = BITFORCE_SLEEP_MS; - while (i < BITFORCE_TIMEOUT_MS) { - mutex_lock(&bitforce->dev_lock); + while (wait_ms < BITFORCE_TIMEOUT_MS) { + mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - mutex_unlock(&bitforce->dev_lock); + mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "Error reading from BitForce (ZFX)"); - mutex_unlock(&bitforce->dev_lock); + applog(LOG_ERR, "BFL%i: Error reading (ZFX)", bitforce->device_id); + mutex_unlock(&bitforce->device_mutex); return 0; } if (pdevbuf[0] != 'B') break; - usleep(10000); - i += 10; + usleep(BITFORCE_CHECK_INTERVAL_MS*1000); + wait_ms += BITFORCE_CHECK_INTERVAL_MS; } - - if (i >= BITFORCE_TIMEOUT_MS) { - applog(LOG_ERR, "BitForce took longer than 30s"); + if (wait_ms >= BITFORCE_TIMEOUT_MS) { + applog(LOG_ERR, "BFL%i took longer than 15s"); bitforce->device_last_not_well = time(NULL); bitforce->device_not_well_reason = REASON_THREAD_ZERO_HASH; bitforce->thread_zero_hash_count++; return 1; } - applog(LOG_DEBUG, "BitForce waited %dms until %s\n", i, pdevbuf); + applog(LOG_DEBUG, "BFL%i: waited %dms until %s\n", bitforce->device_id, wait_ms, pdevbuf); work->blk.nonce = 0xffffffff; if (pdevbuf[2] == '-') return 0xffffffff; /* No valid nonce found */ else if (pdevbuf[0] == 'I') return 1; /* Device idle */ else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) { - applog(LOG_WARNING, "BitForce result reports: %s", pdevbuf); + applog(LOG_WARNING, "BFL%i: result reports: %s", bitforce->device_id, pdevbuf); return 1; } @@ -319,42 +329,34 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) static void bitforce_shutdown(struct thr_info *thr) { struct cgpu_info *bitforce = thr->cgpu; - int fdDev = bitforce->device_fd; - BFclose(fdDev); + BFclose(bitforce->device_fd); + bitforce->device_fd = 0; } -#define CHECK_INTERVAL_MS 200 +static void biforce_thread_enable(struct thr_info *thr) +{ + struct cgpu_info *bitforce = thr->cgpu; + + bitforce_init(bitforce); +} static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; - bool dev_enabled = (bitforce->deven == DEV_ENABLED); - static enum dev_enable last_dev_state = DEV_ENABLED; - int wait_ms = 0; - - if (bitforce->deven == DEV_DISABLED) { - bitforce_shutdown(thr); - return 1; - } - - // if device has just gone from disabled to enabled, re-initialise it - if (last_dev_state == DEV_DISABLED && dev_enabled) - bitforce_init(bitforce); - last_dev_state = bitforce->deven; + unsigned int wait_ms = 0; if (!bitforce_send_work(thr, work)) return 0; - + while (wait_ms < BITFORCE_SLEEP_MS) { - usleep(CHECK_INTERVAL_MS * 1000); - wait_ms += CHECK_INTERVAL_MS; + usleep(WORK_CHECK_INTERVAL_MS*1000); + wait_ms += WORK_CHECK_INTERVAL_MS; if (work_restart[thr->id].restart) { - applog(LOG_DEBUG, "BFL%i: New work detected, discarding current job", bitforce->device_id); - return 1; //we have discard all work; equivilent to 0 hashes done. + applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, wait_ms); + return 1; //we have discarded all work; equivilent to 0 hashes done. } } - return bitforce_get_result(thr, work); } @@ -367,9 +369,11 @@ struct device_api bitforce_api = { .dname = "bitforce", .name = "BFL", .api_detect = bitforce_detect, + .reinit_device = bitforce_init, .get_statline_before = get_bitforce_statline_before, .get_stats = bitforce_get_stats, .thread_prepare = bitforce_thread_prepare, .scanhash = bitforce_scanhash, - .thread_shutdown = bitforce_shutdown + .thread_shutdown = bitforce_shutdown, + .thread_enable = biforce_thread_enable }; diff --git a/miner.h b/miner.h index 6e9ea704..a71447b9 100644 --- a/miner.h +++ b/miner.h @@ -245,13 +245,13 @@ struct device_api { bool (*prepare_work)(struct thr_info*, struct work*); uint64_t (*scanhash)(struct thr_info*, struct work*, uint64_t); void (*thread_shutdown)(struct thr_info*); + void (*thread_enable)(struct thr_info*); }; enum dev_enable { DEV_ENABLED, DEV_DISABLED, DEV_RECOVER, - DEV_IDLE, }; enum cl_kernels { @@ -377,8 +377,6 @@ struct cgpu_info { int dev_thermal_cutoff_count; struct cgminer_stats cgminer_stats; - - pthread_mutex_t dev_lock; }; extern bool add_cgpu(struct cgpu_info*); From 1b63a75d2c56f2c32cc8fcb3f8922879df277806 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Wed, 13 Jun 2012 12:26:03 -0700 Subject: [PATCH 14/38] Simple auto sleep-time calibration. Optimises the sleep time while waiting for the BFL work to finish. Takes ~5 mins to settle to the correct time for each unit, then will continue to make adjustments. --- driver-bitforce.c | 32 ++++++++++++++++++-------------- miner.h | 4 ++++ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 0a2fc82e..9b76fd40 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -20,13 +20,10 @@ #include "fpgautils.h" #include "miner.h" -/* @832MH/s wait time is ~4500ms - @864MH/s wait time is ~4430ms --> @896MH/s wait time will be ~4350ms */ -#define BITFORCE_SLEEP_MS 4300 +#define BITFORCE_SLEEP_MS 2000 #define BITFORCE_TIMEOUT_MS 15000 #define BITFORCE_CHECK_INTERVAL_MS 10 -#define WORK_CHECK_INTERVAL_MS 100 +#define WORK_CHECK_INTERVAL_MS 50 struct device_api bitforce_api; @@ -84,6 +81,7 @@ static bool bitforce_detect_one(const char *devpath) bitforce->device_path = strdup(devpath); bitforce->deven = DEV_ENABLED; bitforce->threads = 1; + bitforce->sleep_ms = BITFORCE_SLEEP_MS; if (likely((!memcmp(pdevbuf, ">>>ID: ", 7)) && (s = strstr(pdevbuf + 3, ">>>")))) { s[0] = '\0'; @@ -273,9 +271,8 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) char pdevbuf[0x100]; char *pnoncebuf; uint32_t nonce; - unsigned int wait_ms = BITFORCE_SLEEP_MS; - while (wait_ms < BITFORCE_TIMEOUT_MS) { + while (bitforce->wait_ms < BITFORCE_TIMEOUT_MS) { mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); @@ -288,17 +285,24 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) if (pdevbuf[0] != 'B') break; usleep(BITFORCE_CHECK_INTERVAL_MS*1000); - wait_ms += BITFORCE_CHECK_INTERVAL_MS; + bitforce->wait_ms += BITFORCE_CHECK_INTERVAL_MS; } - if (wait_ms >= BITFORCE_TIMEOUT_MS) { + if (bitforce->wait_ms >= BITFORCE_TIMEOUT_MS) { applog(LOG_ERR, "BFL%i took longer than 15s"); bitforce->device_last_not_well = time(NULL); bitforce->device_not_well_reason = REASON_THREAD_ZERO_HASH; bitforce->thread_zero_hash_count++; return 1; + } else { + /* Simple timing adjustment */ + // applog(LOG_WARNING, "BFL%i: Waited: %ums, sleep is:%ums", bitforce->device_id, bitforce->wait_ms, bitforce->sleep_ms); + if (bitforce->wait_ms > (bitforce->sleep_ms + WORK_CHECK_INTERVAL_MS)) + bitforce->sleep_ms += WORK_CHECK_INTERVAL_MS; + else if (bitforce->wait_ms == bitforce->sleep_ms) + bitforce->sleep_ms -= WORK_CHECK_INTERVAL_MS; } - applog(LOG_DEBUG, "BFL%i: waited %dms until %s\n", bitforce->device_id, wait_ms, pdevbuf); + applog(LOG_DEBUG, "BFL%i: waited %dms until %s", bitforce->device_id, bitforce->wait_ms, pdevbuf); work->blk.nonce = 0xffffffff; if (pdevbuf[2] == '-') return 0xffffffff; /* No valid nonce found */ @@ -344,16 +348,16 @@ static void biforce_thread_enable(struct thr_info *thr) static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; - unsigned int wait_ms = 0; + bitforce->wait_ms = 0; if (!bitforce_send_work(thr, work)) return 0; - while (wait_ms < BITFORCE_SLEEP_MS) { + while (bitforce->wait_ms < bitforce->sleep_ms) { usleep(WORK_CHECK_INTERVAL_MS*1000); - wait_ms += WORK_CHECK_INTERVAL_MS; + bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; if (work_restart[thr->id].restart) { - applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, wait_ms); + applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); return 1; //we have discarded all work; equivilent to 0 hashes done. } } diff --git a/miner.h b/miner.h index a71447b9..71ece039 100644 --- a/miner.h +++ b/miner.h @@ -315,6 +315,10 @@ struct cgpu_info { #endif int device_fd; }; +#ifdef USE_BITFORCE + unsigned int wait_ms; + unsigned int sleep_ms; +#endif pthread_mutex_t device_mutex; enum dev_enable deven; From 2ec612e0b4084c93ee76b5879eb9fb50be1955b4 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Wed, 13 Jun 2012 17:26:37 -0700 Subject: [PATCH 15/38] Added startup delay to worker threads. Prevents devices from making calls at the same time. --- driver-bitforce.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/driver-bitforce.c b/driver-bitforce.c index 9b76fd40..61d7c0c9 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -24,6 +24,7 @@ #define BITFORCE_TIMEOUT_MS 15000 #define BITFORCE_CHECK_INTERVAL_MS 10 #define WORK_CHECK_INTERVAL_MS 50 +#define MAX_START_DELAY_US 100000 struct device_api bitforce_api; @@ -369,6 +370,19 @@ static bool bitforce_get_stats(struct cgpu_info *bitforce) return bitforce_get_temp(bitforce); } +static bool bitforce_thread_init(struct thr_info *thr) +{ + unsigned int wait; + thr; + /* Pause each new thread a random time between 0-100ms + so the devices aren't making calls all at the same time. */ + wait = (rand() * MAX_START_DELAY_US)/RAND_MAX; + applog(LOG_DEBUG, "BFL%i: Delaying start by %dms", bitforce->device_id, wait/1000); + usleep(wait); + + return true; +} + struct device_api bitforce_api = { .dname = "bitforce", .name = "BFL", @@ -377,6 +391,7 @@ struct device_api bitforce_api = { .get_statline_before = get_bitforce_statline_before, .get_stats = bitforce_get_stats, .thread_prepare = bitforce_thread_prepare, + .thread_init = bitforce_thread_init, .scanhash = bitforce_scanhash, .thread_shutdown = bitforce_shutdown, .thread_enable = biforce_thread_enable From 4fd53c9eb15cb603ba8837b20ab9383948582201 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Thu, 14 Jun 2012 00:04:37 -0700 Subject: [PATCH 16/38] thread init fix --- driver-bitforce.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 61d7c0c9..dc8fa6ed 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -372,8 +372,9 @@ static bool bitforce_get_stats(struct cgpu_info *bitforce) static bool bitforce_thread_init(struct thr_info *thr) { + struct cgpu_info *bitforce = thr->cgpu; unsigned int wait; - thr; + /* Pause each new thread a random time between 0-100ms so the devices aren't making calls all at the same time. */ wait = (rand() * MAX_START_DELAY_US)/RAND_MAX; From fa3f357fc1fdda299f2d1348bd92b12f88350abf Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Thu, 14 Jun 2012 17:36:59 -0700 Subject: [PATCH 17/38] Sick/dead handling for non-gpus --- cgminer.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cgminer.c b/cgminer.c index cef4c8cc..db1339d2 100644 --- a/cgminer.c +++ b/cgminer.c @@ -4347,19 +4347,18 @@ static void *watchdog_thread(void __maybe_unused *userdata) struct thr_info *thr = cgpu->thr[0]; enum dev_enable *denable; int gpu; + char dev_str[8]; - if (cgpu->api->get_stats) { - cgpu->api->get_stats(cgpu); - } + if (cgpu->api->get_stats) + cgpu->api->get_stats(cgpu); -#ifdef HAVE_OPENCL - if (cgpu->api != &opencl_api) - continue; /* Use only one thread per device to determine if the GPU is healthy */ if (i >= nDevs) break; gpu = thr->cgpu->device_id; denable = &cgpu->deven; + sprintf(dev_str, "%s%d", cgpu->api->name, gpu); + #ifdef HAVE_ADL if (adl_active && gpus[gpu].has_adl) gpu_autotune(gpu, denable); @@ -4378,13 +4377,13 @@ static void *watchdog_thread(void __maybe_unused *userdata) continue; if (gpus[gpu].status != LIFE_WELL && now.tv_sec - thr->last.tv_sec < 60) { - applog(LOG_ERR, "Device %d recovered, GPU %d declared WELL!", i, gpu); + applog(LOG_ERR, "%s: Recovered, declaring WELL!", dev_str); gpus[gpu].status = LIFE_WELL; gpus[gpu].device_last_well = time(NULL); } else if (now.tv_sec - thr->last.tv_sec > 60 && gpus[gpu].status == LIFE_WELL) { thr->rolling = thr->cgpu->rolling = 0; gpus[gpu].status = LIFE_SICK; - applog(LOG_ERR, "Device %d idle for more than 60 seconds, GPU %d declared SICK!", i, gpu); + applog(LOG_ERR, "%s: Idle for more than 60 seconds, declaring SICK!", dev_str); gettimeofday(&thr->sick, NULL); gpus[gpu].device_last_not_well = time(NULL); @@ -4397,12 +4396,12 @@ static void *watchdog_thread(void __maybe_unused *userdata) } else #endif if (opt_restart) { - applog(LOG_ERR, "Attempting to restart GPU"); + applog(LOG_ERR, "%s: Attempting to restart", dev_str); reinit_device(thr->cgpu); } } else if (now.tv_sec - thr->last.tv_sec > 600 && gpus[i].status == LIFE_SICK) { gpus[gpu].status = LIFE_DEAD; - applog(LOG_ERR, "Device %d not responding for more than 10 minutes, GPU %d declared DEAD!", i, gpu); + applog(LOG_ERR, "%s: Not responded for more than 10 minutes, declaring DEAD!", dev_str); gettimeofday(&thr->sick, NULL); gpus[gpu].device_last_not_well = time(NULL); @@ -4420,9 +4419,7 @@ static void *watchdog_thread(void __maybe_unused *userdata) if (opt_restart) reinit_device(thr->cgpu); } -#endif /* HAVE_OPENCL */ } - } return NULL; @@ -5296,6 +5293,7 @@ begin_bench: quit(1, "watchdog thread create failed"); pthread_detach(thr->pth); +#ifdef HAVE_OPENCL /* Create reinit gpu thread */ gpur_thr_id = mining_threads + 4; thr = &thr_info[gpur_thr_id]; @@ -5304,6 +5302,7 @@ begin_bench: quit(1, "tq_new failed for gpur_thr_id"); if (thr_info_create(thr, NULL, reinit_gpu, thr)) quit(1, "reinit_gpu thread create failed"); +#endif /* Create API socket thread */ api_thr_id = mining_threads + 5; @@ -5312,6 +5311,7 @@ begin_bench: quit(1, "API thread create failed"); pthread_detach(thr->pth); + #ifdef HAVE_CURSES /* Create curses input thread for keyboard input. Create this last so * that we know all threads are created since this can call kill_work From 6ed75c96cbc085dca182ea28d59d9993d2ea1aa5 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Fri, 15 Jun 2012 12:11:28 -0700 Subject: [PATCH 18/38] Remove nDev limit in watchdog_thread Can't work out why it was even there... so there could still be a reason for it! --- cgminer.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cgminer.c b/cgminer.c index db1339d2..dd215fc3 100644 --- a/cgminer.c +++ b/cgminer.c @@ -4348,13 +4348,10 @@ static void *watchdog_thread(void __maybe_unused *userdata) enum dev_enable *denable; int gpu; char dev_str[8]; - + if (cgpu->api->get_stats) cgpu->api->get_stats(cgpu); - /* Use only one thread per device to determine if the GPU is healthy */ - if (i >= nDevs) - break; gpu = thr->cgpu->device_id; denable = &cgpu->deven; sprintf(dev_str, "%s%d", cgpu->api->name, gpu); From 68f2aaf9304d75da2db1412939dba0382d6bd1db Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Fri, 15 Jun 2012 16:43:05 -0700 Subject: [PATCH 19/38] fix bitforce_init return value Also add filename as kernel name --- driver-bitforce.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index dc8fa6ed..a02000ed 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -39,18 +39,15 @@ static void BFgets(char *buf, size_t bufLen, int fd) buf[0] = '\0'; } -static ssize_t BFwrite2(int fd, const void *buf, ssize_t bufLen) +static ssize_t BFwrite(int fd, const void *buf, ssize_t bufLen) { - return write(fd, buf, bufLen); + if ((bufLen) != write(fd, buf, bufLen)) { + applog(LOG_ERR, "BFL: Error writing: %s", buf); + return 0; + } else + return bufLen; } -#define BFwrite(fd, buf, bufLen) do { \ - if ((bufLen) != BFwrite2(fd, buf, bufLen)) { \ - applog(LOG_ERR, "BFL: Error writing (" #buf ")"); \ - return 0; \ - } \ -} while(0) - #define BFclose(fd) close(fd) static bool bitforce_detect_one(const char *devpath) @@ -83,6 +80,7 @@ static bool bitforce_detect_one(const char *devpath) bitforce->deven = DEV_ENABLED; bitforce->threads = 1; bitforce->sleep_ms = BITFORCE_SLEEP_MS; + bitforce->kname = __FILE__; if (likely((!memcmp(pdevbuf, ">>>ID: ", 7)) && (s = strstr(pdevbuf + 3, ">>>")))) { s[0] = '\0'; @@ -138,7 +136,7 @@ static bool bitforce_thread_prepare(struct thr_info *thr) return true; } -static bool bitforce_init(struct cgpu_info *bitforce) +void bitforce_init(struct cgpu_info *bitforce) { int fdDev = bitforce->device_fd; char *devpath = bitforce->device_path; @@ -155,7 +153,7 @@ static bool bitforce_init(struct cgpu_info *bitforce) fdDev = BFopen(devpath); if (unlikely(fdDev == -1)) { applog(LOG_ERR, "BFL%i: Failed to open %s", bitforce->device_id, devpath); - return false; + return; } bitforce->device_fd = fdDev; @@ -167,12 +165,12 @@ static bool bitforce_init(struct cgpu_info *bitforce) if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "BFL%i: Error reading (ZGX)", bitforce->device_id); - return false; + return; } if (unlikely(!strstr(pdevbuf, "SHA256"))) { applog(LOG_ERR, "BFL%i: Didn't recognise BitForce on %s", bitforce->device_id, devpath); - return false; + return; } if (likely((!memcmp(pdevbuf, ">>>ID: ", 7)) && (s = strstr(pdevbuf + 3, ">>>")))) @@ -180,8 +178,6 @@ static bool bitforce_init(struct cgpu_info *bitforce) s[0] = '\0'; bitforce->name = strdup(pdevbuf + 7); } - - return true; } static bool bitforce_get_temp(struct cgpu_info *bitforce) From 9bc95ab30bd56a43a234c7b1cabbb45fcdfc7506 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Tue, 19 Jun 2012 10:36:24 -0700 Subject: [PATCH 20/38] Comms error trapping Comms error will not disable the device permanently but put it in to recovery mode. Here it will attempt to be re-initialised after 60s. --- driver-bitforce.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index a02000ed..5e9d2582 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -80,7 +80,6 @@ static bool bitforce_detect_one(const char *devpath) bitforce->deven = DEV_ENABLED; bitforce->threads = 1; bitforce->sleep_ms = BITFORCE_SLEEP_MS; - bitforce->kname = __FILE__; if (likely((!memcmp(pdevbuf, ">>>ID: ", 7)) && (s = strstr(pdevbuf + 3, ">>>")))) { s[0] = '\0'; @@ -193,6 +192,7 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "BFL%i: Error reading (ZLX)", bitforce->device_id); + bitforce->temp = 0; return false; } if ((!strncasecmp(pdevbuf, "TEMP", 4)) && (s = strchr(pdevbuf + 4, ':'))) { @@ -285,14 +285,13 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) bitforce->wait_ms += BITFORCE_CHECK_INTERVAL_MS; } if (bitforce->wait_ms >= BITFORCE_TIMEOUT_MS) { - applog(LOG_ERR, "BFL%i took longer than 15s"); + applog(LOG_ERR, "BFL%i: took longer than 15s", bitforce->device_id); bitforce->device_last_not_well = time(NULL); - bitforce->device_not_well_reason = REASON_THREAD_ZERO_HASH; - bitforce->thread_zero_hash_count++; + bitforce->device_not_well_reason = REASON_DEV_OVER_HEAT; + bitforce->dev_over_heat_count++; return 1; } else { /* Simple timing adjustment */ - // applog(LOG_WARNING, "BFL%i: Waited: %ums, sleep is:%ums", bitforce->device_id, bitforce->wait_ms, bitforce->sleep_ms); if (bitforce->wait_ms > (bitforce->sleep_ms + WORK_CHECK_INTERVAL_MS)) bitforce->sleep_ms += WORK_CHECK_INTERVAL_MS; else if (bitforce->wait_ms == bitforce->sleep_ms) @@ -346,19 +345,29 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 { struct cgpu_info *bitforce = thr->cgpu; bitforce->wait_ms = 0; + uint64_t ret; - if (!bitforce_send_work(thr, work)) - return 0; - - while (bitforce->wait_ms < bitforce->sleep_ms) { - usleep(WORK_CHECK_INTERVAL_MS*1000); - bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; - if (work_restart[thr->id].restart) { - applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); - return 1; //we have discarded all work; equivilent to 0 hashes done. + if (ret = bitforce_send_work(thr, work)) { + while (bitforce->wait_ms < bitforce->sleep_ms) { + usleep(WORK_CHECK_INTERVAL_MS*1000); + bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; + if (work_restart[thr->id].restart) { + applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); + return 1; //we have discarded all work; equivilent to 0 hashes done. + } } + ret = bitforce_get_result(thr, work); } - return bitforce_get_result(thr, work); + + if (!ret) { + ret = 1; + applog(LOG_ERR, "BFL%i: Comms error, going to recover mode", bitforce->device_id); + bitforce->device_last_not_well = time(NULL); + bitforce->device_not_well_reason = REASON_THREAD_ZERO_HASH; + bitforce->thread_zero_hash_count++; + bitforce->deven = DEV_RECOVER; + } + return ret; } static bool bitforce_get_stats(struct cgpu_info *bitforce) From 57fa2be13beee54f0f9db217cf7db085b439b261 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Wed, 20 Jun 2012 11:40:28 -0700 Subject: [PATCH 21/38] Write pools in priority order --- cgminer.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/cgminer.c b/cgminer.c index 5dbfc76b..58657fc0 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2694,15 +2694,21 @@ void remove_pool(struct pool *pool) void write_config(FILE *fcfg) { - int i; + int i = 0; + int j = 0; - /* Write pool values */ + /* Write pool values in priority order */ fputs("{\n\"pools\" : [", fcfg); - for(i = 0; i < total_pools; i++) { - fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); - fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); - fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", pools[i]->rpc_pass); - } + while((j < total_pools) && (i < total_pools)) { + if(pools[i]->prio == j) { + fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); + fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); + fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", pools[i]->rpc_pass); + j++; + i=0; + } else + i++; + } fputs("\n]\n", fcfg); #ifdef HAVE_OPENCL From 0bcdc2cac42c29fd0dbfe727bb467f21dc25c216 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Wed, 20 Jun 2012 15:49:07 -0700 Subject: [PATCH 22/38] Add ability to disable pools in config file. Also fix pool writing in priorty order. --- cgminer.c | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/cgminer.c b/cgminer.c index 58657fc0..bf8db766 100644 --- a/cgminer.c +++ b/cgminer.c @@ -192,11 +192,11 @@ unsigned int total_go, total_ro; struct pool *pools[MAX_POOLS]; static struct pool *currentpool = NULL; - +enum pool_enable opt_pool_enabled = POOL_ENABLED; int total_pools; enum pool_strategy pool_strategy = POOL_FAILOVER; int opt_rotate_period; -static int total_urls, total_users, total_passes, total_userpasses; +static int total_urls = 0, total_users = 0, total_passes = 0, total_userpasses = 0; #ifndef HAVE_CURSES const @@ -405,6 +405,9 @@ static struct pool *add_pool(void) /* Make sure the pool doesn't think we've been idle since time 0 */ pool->tv_idle.tv_sec = ~0UL; + pool->enabled = POOL_ENABLED; + pool->idle = true; + return pool; } @@ -590,6 +593,18 @@ static char *set_userpass(const char *arg) return NULL; } +static char *set_pool_disabled(enum pool_enable *pool_state) +{ + struct pool *pool; + *pool_state = POOL_DISABLED; // This (and opt_pool_enabled) does nothing. Here for compatability + + if (total_pools) { + pool = pools[total_pools - 1]; + pool->enabled = POOL_DISABLED; + } + return NULL; +} + static char *enable_debug(bool *flag) { *flag = true; @@ -986,6 +1001,9 @@ static struct opt_table opt_config_table[] = { OPT_WITH_ARG("--userpass|-O", set_userpass, NULL, NULL, "Username:Password pair for bitcoin JSON-RPC server"), + OPT_WITHOUT_ARG("--disable-pool", + set_pool_disabled, &opt_pool_enabled, + "Start with pool disabled."), OPT_WITH_ARG("--pools", opt_set_bool, NULL, NULL, opt_hidden), OPT_ENDTABLE @@ -2696,14 +2714,17 @@ void write_config(FILE *fcfg) { int i = 0; int j = 0; + char *s; /* Write pool values in priority order */ fputs("{\n\"pools\" : [", fcfg); while((j < total_pools) && (i < total_pools)) { if(pools[i]->prio == j) { - fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); + fprintf(fcfg, "\n\t{\n\t\t\"url\" : \"%s\",", pools[i]->rpc_url); fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); - fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", pools[i]->rpc_pass); + fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"", pools[i]->rpc_pass); + s = (pools[i]->enabled == POOL_DISABLED) ? ",\n\t\t\"disable-pool\" : true\n\t}%s" : "\n\t}%s"; + fprintf(fcfg, s, (j < total_pools - 1) ? "," : ""); j++; i=0; } else @@ -5118,8 +5139,14 @@ int main(int argc, char *argv[]) quit(1, "Failed to find colon delimiter in userpass"); } } - /* Set the currentpool to pool 0 */ - currentpool = pools[0]; + /* Set the currentpool to pool first enabled */ + for (i = 0; i < total_pools; i++) { + currentpool = pools[i]; + if (currentpool->enabled == POOL_ENABLED) + break; + } + if (i == total_pools) + quit(1, "All pools disabled!"); #ifdef HAVE_SYSLOG_H if (use_syslog) @@ -5172,13 +5199,6 @@ int main(int argc, char *argv[]) if (opt_benchmark) goto begin_bench; - for (i = 0; i < total_pools; i++) { - struct pool *pool = pools[i]; - - pool->enabled = POOL_ENABLED; - pool->idle = true; - } - applog(LOG_NOTICE, "Probing for an alive pool"); do { /* Look for at least one active pool before starting */ From 50e996c75309fd426670a4b9511babf573452352 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Mon, 25 Jun 2012 10:01:34 -0700 Subject: [PATCH 23/38] Get rid of recover mode. Not useful at all. Change zero hash to no start error. Neither is accurate, but zero hash makes less sense than no start. --- driver-bitforce.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 20904596..110d06f0 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -363,11 +363,10 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 if (!ret) { ret = 1; - applog(LOG_ERR, "BFL%i: Comms error, going to recover mode", bitforce->device_id); + applog(LOG_ERR, "BFL%i: Comms error", bitforce->device_id); bitforce->device_last_not_well = time(NULL); - bitforce->device_not_well_reason = REASON_THREAD_ZERO_HASH; - bitforce->thread_zero_hash_count++; - bitforce->deven = DEV_RECOVER; + bitforce->device_not_well_reason = REASON_DEV_NOSTART; + bitforce->dev_nostart_count++; } return ret; } From 90d82aa61d7fbeff2948758b68a7d4a81d727184 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Mon, 25 Jun 2012 10:27:08 -0700 Subject: [PATCH 24/38] Revert to pre pool merge --- cgminer.c | 62 ++++++++++++++--------------------------------- driver-bitforce.c | 7 +++--- 2 files changed, 22 insertions(+), 47 deletions(-) diff --git a/cgminer.c b/cgminer.c index ec28b945..ec062789 100644 --- a/cgminer.c +++ b/cgminer.c @@ -192,11 +192,11 @@ unsigned int total_go, total_ro; struct pool *pools[MAX_POOLS]; static struct pool *currentpool = NULL; -enum pool_enable opt_pool_enabled = POOL_ENABLED; + int total_pools; enum pool_strategy pool_strategy = POOL_FAILOVER; int opt_rotate_period; -static int total_urls = 0, total_users = 0, total_passes = 0, total_userpasses = 0; +static int total_urls, total_users, total_passes, total_userpasses; #ifndef HAVE_CURSES const @@ -405,9 +405,6 @@ static struct pool *add_pool(void) /* Make sure the pool doesn't think we've been idle since time 0 */ pool->tv_idle.tv_sec = ~0UL; - pool->enabled = POOL_ENABLED; - pool->idle = true; - return pool; } @@ -593,18 +590,6 @@ static char *set_userpass(const char *arg) return NULL; } -static char *set_pool_disabled(enum pool_enable *pool_state) -{ - struct pool *pool; - *pool_state = POOL_DISABLED; // This (and opt_pool_enabled) does nothing. Here for compatability - - if (total_pools) { - pool = pools[total_pools - 1]; - pool->enabled = POOL_DISABLED; - } - return NULL; -} - static char *enable_debug(bool *flag) { *flag = true; @@ -1001,9 +986,6 @@ static struct opt_table opt_config_table[] = { OPT_WITH_ARG("--userpass|-O", set_userpass, NULL, NULL, "Username:Password pair for bitcoin JSON-RPC server"), - OPT_WITHOUT_ARG("--disable-pool", - set_pool_disabled, &opt_pool_enabled, - "Start with pool disabled."), OPT_WITH_ARG("--pools", opt_set_bool, NULL, NULL, opt_hidden), OPT_ENDTABLE @@ -2712,24 +2694,15 @@ void remove_pool(struct pool *pool) void write_config(FILE *fcfg) { - int i = 0; - int j = 0; - char *s; + int i; - /* Write pool values in priority order */ + /* Write pool values */ fputs("{\n\"pools\" : [", fcfg); - while((j < total_pools) && (i < total_pools)) { - if(pools[i]->prio == j) { - fprintf(fcfg, "\n\t{\n\t\t\"url\" : \"%s\",", pools[i]->rpc_url); - fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); - fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"", pools[i]->rpc_pass); - s = (pools[i]->enabled == POOL_DISABLED) ? ",\n\t\t\"disable-pool\" : true\n\t}%s" : "\n\t}%s"; - fprintf(fcfg, s, (j < total_pools - 1) ? "," : ""); - j++; - i=0; - } else - i++; - } + for(i = 0; i < total_pools; i++) { + fprintf(fcfg, "%s\n\t{\n\t\t\"url\" : \"%s\",", i > 0 ? "," : "", pools[i]->rpc_url); + fprintf(fcfg, "\n\t\t\"user\" : \"%s\",", pools[i]->rpc_user); + fprintf(fcfg, "\n\t\t\"pass\" : \"%s\"\n\t}", pools[i]->rpc_pass); + } fputs("\n]\n", fcfg); #ifdef HAVE_OPENCL @@ -5140,14 +5113,8 @@ int main(int argc, char *argv[]) quit(1, "Failed to find colon delimiter in userpass"); } } - /* Set the currentpool to pool first enabled */ - for (i = 0; i < total_pools; i++) { - currentpool = pools[i]; - if (currentpool->enabled == POOL_ENABLED) - break; - } - if (i == total_pools) - quit(1, "All pools disabled!"); + /* Set the currentpool to pool 0 */ + currentpool = pools[0]; #ifdef HAVE_SYSLOG_H if (use_syslog) @@ -5200,6 +5167,13 @@ int main(int argc, char *argv[]) if (opt_benchmark) goto begin_bench; + for (i = 0; i < total_pools; i++) { + struct pool *pool = pools[i]; + + pool->enabled = POOL_ENABLED; + pool->idle = true; + } + applog(LOG_NOTICE, "Probing for an alive pool"); do { /* Look for at least one active pool before starting */ diff --git a/driver-bitforce.c b/driver-bitforce.c index 110d06f0..20904596 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -363,10 +363,11 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 if (!ret) { ret = 1; - applog(LOG_ERR, "BFL%i: Comms error", bitforce->device_id); + applog(LOG_ERR, "BFL%i: Comms error, going to recover mode", bitforce->device_id); bitforce->device_last_not_well = time(NULL); - bitforce->device_not_well_reason = REASON_DEV_NOSTART; - bitforce->dev_nostart_count++; + bitforce->device_not_well_reason = REASON_THREAD_ZERO_HASH; + bitforce->thread_zero_hash_count++; + bitforce->deven = DEV_RECOVER; } return ret; } From f149aea91eea761abc6a2b1985eeffdc80e83a16 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Mon, 25 Jun 2012 10:33:18 -0700 Subject: [PATCH 25/38] Redo recover removal. FML. --- driver-bitforce.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 20904596..110d06f0 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -363,11 +363,10 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 if (!ret) { ret = 1; - applog(LOG_ERR, "BFL%i: Comms error, going to recover mode", bitforce->device_id); + applog(LOG_ERR, "BFL%i: Comms error", bitforce->device_id); bitforce->device_last_not_well = time(NULL); - bitforce->device_not_well_reason = REASON_THREAD_ZERO_HASH; - bitforce->thread_zero_hash_count++; - bitforce->deven = DEV_RECOVER; + bitforce->device_not_well_reason = REASON_DEV_NOSTART; + bitforce->dev_nostart_count++; } return ret; } From 1ef52e0bac1fbc67d9ef097c07a8c32bab1d98e8 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Mon, 25 Jun 2012 19:23:10 -0700 Subject: [PATCH 26/38] Check for submit_stale before checking for work_restart (to keep Kano happy) --- cgminer.c | 2 +- driver-bitforce.c | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cgminer.c b/cgminer.c index 75a28244..21f3f1ef 100644 --- a/cgminer.c +++ b/cgminer.c @@ -126,7 +126,7 @@ bool use_curses = true; #else bool use_curses; #endif -static bool opt_submit_stale = true; +bool opt_submit_stale = true; static int opt_shares; static bool opt_fail_only; bool opt_autofan; diff --git a/driver-bitforce.c b/driver-bitforce.c index 110d06f0..44c4a476 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -343,20 +343,28 @@ static void biforce_thread_enable(struct thr_info *thr) bitforce_init(bitforce); } +extern bool opt_submit_stale; + static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; + bool submit_old = work->pool->submit_old; bitforce->wait_ms = 0; uint64_t ret; if (ret = bitforce_send_work(thr, work)) { - while (bitforce->wait_ms < bitforce->sleep_ms) { - usleep(WORK_CHECK_INTERVAL_MS*1000); - bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; - if (work_restart[thr->id].restart) { - applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); - return 1; //we have discarded all work; equivilent to 0 hashes done. + if(!opt_submit_stale || !submit_old) { + while (bitforce->wait_ms < bitforce->sleep_ms) { + usleep(WORK_CHECK_INTERVAL_MS*1000); + bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; + if (work_restart[thr->id].restart) { + applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); + return 1; //we have discarded all work; equivilent to 0 hashes done. + } } + } else { + usleep(bitforce->sleep_ms*1000); + bitforce->wait_ms = bitforce->sleep_ms; } ret = bitforce_get_result(thr, work); } From d3e2b62c54cdb4eb69db31658c332a17bc492d1a Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Tue, 26 Jun 2012 14:45:48 -0700 Subject: [PATCH 27/38] Change sick/dead processing to use device pointer, not gpu array. Change BFL timing to adjust only when hashing complete (not error/idle etc.). --- cgminer.c | 44 ++++++++++++++++++++++---------------------- driver-bitforce.c | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/cgminer.c b/cgminer.c index dbbc045d..9b77d693 100644 --- a/cgminer.c +++ b/cgminer.c @@ -4484,14 +4484,14 @@ static void *watchdog_thread(void __maybe_unused *userdata) if (cgpu->api->get_stats) cgpu->api->get_stats(cgpu); - gpu = thr->cgpu->device_id; + gpu = cgpu->device_id; denable = &cgpu->deven; sprintf(dev_str, "%s%d", cgpu->api->name, gpu); #ifdef HAVE_ADL - if (adl_active && gpus[gpu].has_adl) + if (adl_active && cgpu->has_adl) gpu_autotune(gpu, denable); - if (opt_debug && gpus[gpu].has_adl) { + if (opt_debug && cgpu->has_adl) { int engineclock = 0, memclock = 0, activity = 0, fanspeed = 0, fanpercent = 0, powertune = 0; float temp = 0, vddc = 0; @@ -4505,48 +4505,48 @@ static void *watchdog_thread(void __maybe_unused *userdata) if (thr->getwork || *denable == DEV_DISABLED) continue; - if (gpus[gpu].status != LIFE_WELL && now.tv_sec - thr->last.tv_sec < 60) { + if (cgpu->status != LIFE_WELL && now.tv_sec - thr->last.tv_sec < 60) { applog(LOG_ERR, "%s: Recovered, declaring WELL!", dev_str); - gpus[gpu].status = LIFE_WELL; - gpus[gpu].device_last_well = time(NULL); - } else if (now.tv_sec - thr->last.tv_sec > 60 && gpus[gpu].status == LIFE_WELL) { - thr->rolling = thr->cgpu->rolling = 0; - gpus[gpu].status = LIFE_SICK; + cgpu->status = LIFE_WELL; + cgpu->device_last_well = time(NULL); + } else if (now.tv_sec - thr->last.tv_sec > 60 && cgpu->status == LIFE_WELL) { + thr->rolling = cgpu->rolling = 0; + cgpu->status = LIFE_SICK; applog(LOG_ERR, "%s: Idle for more than 60 seconds, declaring SICK!", dev_str); gettimeofday(&thr->sick, NULL); - gpus[gpu].device_last_not_well = time(NULL); - gpus[gpu].device_not_well_reason = REASON_DEV_SICK_IDLE_60; - gpus[gpu].dev_sick_idle_60_count++; + cgpu->device_last_not_well = time(NULL); + cgpu->device_not_well_reason = REASON_DEV_SICK_IDLE_60; + cgpu->dev_sick_idle_60_count++; #ifdef HAVE_ADL - if (adl_active && gpus[gpu].has_adl && gpu_activity(gpu) > 50) { + if (adl_active && cgpu->has_adl && gpu_activity(gpu) > 50) { applog(LOG_ERR, "GPU still showing activity suggesting a hard hang."); applog(LOG_ERR, "Will not attempt to auto-restart it."); } else #endif if (opt_restart) { applog(LOG_ERR, "%s: Attempting to restart", dev_str); - reinit_device(thr->cgpu); + reinit_device(cgpu); } - } else if (now.tv_sec - thr->last.tv_sec > 600 && gpus[i].status == LIFE_SICK) { - gpus[gpu].status = LIFE_DEAD; + } else if (now.tv_sec - thr->last.tv_sec > 600 && cgpu->status == LIFE_SICK) { + cgpu->status = LIFE_DEAD; applog(LOG_ERR, "%s: Not responded for more than 10 minutes, declaring DEAD!", dev_str); gettimeofday(&thr->sick, NULL); - gpus[gpu].device_last_not_well = time(NULL); - gpus[gpu].device_not_well_reason = REASON_DEV_DEAD_IDLE_600; - gpus[gpu].dev_dead_idle_600_count++; + cgpu->device_last_not_well = time(NULL); + cgpu->device_not_well_reason = REASON_DEV_DEAD_IDLE_600; + cgpu->dev_dead_idle_600_count++; } else if (now.tv_sec - thr->sick.tv_sec > 60 && - (gpus[i].status == LIFE_SICK || gpus[i].status == LIFE_DEAD)) { + (cgpu->status == LIFE_SICK || cgpu->status == LIFE_DEAD)) { /* Attempt to restart a GPU that's sick or dead once every minute */ gettimeofday(&thr->sick, NULL); #ifdef HAVE_ADL - if (adl_active && gpus[gpu].has_adl && gpu_activity(gpu) > 50) { + if (adl_active && cgpu->has_adl && gpu_activity(gpu) > 50) { /* Again do not attempt to restart a device that may have hard hung */ } else #endif if (opt_restart) - reinit_device(thr->cgpu); + reinit_device(cgpu); } } } diff --git a/driver-bitforce.c b/driver-bitforce.c index 44c4a476..1980006d 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -292,7 +292,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) bitforce->device_not_well_reason = REASON_DEV_OVER_HEAT; bitforce->dev_over_heat_count++; return 1; - } else { + } else if (pdevbuf[0] == 'N') {/* Hashing complete (NONCE-FOUND or NO-NONCE) */ /* Simple timing adjustment */ if (bitforce->wait_ms > (bitforce->sleep_ms + WORK_CHECK_INTERVAL_MS)) bitforce->sleep_ms += WORK_CHECK_INTERVAL_MS; From 01a7e912c804d8b2af4932b72195ee3e46a3921c Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Wed, 27 Jun 2012 08:25:25 -0700 Subject: [PATCH 28/38] Lock comms around entire bitforce_init, and move setting of fd to end. Make sleep occur everytime in scanhash. --- driver-bitforce.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 1980006d..63729446 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -146,6 +146,7 @@ void bitforce_init(struct cgpu_info *bitforce) applog(LOG_INFO, "BFL%i: Re-initalizing", bitforce->device_id); + mutex_lock(&bitforce->device_mutex); if (fdDev) { BFclose(fdDev); bitforce->device_fd = 0; @@ -154,23 +155,22 @@ void bitforce_init(struct cgpu_info *bitforce) fdDev = BFopen(devpath); if (unlikely(fdDev == -1)) { applog(LOG_ERR, "BFL%i: Failed to open %s", bitforce->device_id, devpath); + mutex_unlock(&bitforce->device_mutex); return; } - bitforce->device_fd = fdDev; - - mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZGX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "BFL%i: Error reading (ZGX)", bitforce->device_id); + mutex_unlock(&bitforce->device_mutex); return; } if (unlikely(!strstr(pdevbuf, "SHA256"))) { - applog(LOG_ERR, "BFL%i: Didn't recognise BitForce on %s", bitforce->device_id, devpath); + applog(LOG_ERR, "BFL%i: Didn't recognise BitForce on %s returned: %s", bitforce->device_id, devpath, pdevbuf); + mutex_unlock(&bitforce->device_mutex); return; } @@ -179,6 +179,9 @@ void bitforce_init(struct cgpu_info *bitforce) s[0] = '\0'; bitforce->name = strdup(pdevbuf + 7); } + + bitforce->device_fd = fdDev; + mutex_unlock(&bitforce->device_mutex); } static bool bitforce_get_temp(struct cgpu_info *bitforce) @@ -187,6 +190,9 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) char pdevbuf[0x100]; char *s; + if (!fdDev) + return false; + mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZLX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); @@ -352,23 +358,25 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 bitforce->wait_ms = 0; uint64_t ret; - if (ret = bitforce_send_work(thr, work)) { - if(!opt_submit_stale || !submit_old) { - while (bitforce->wait_ms < bitforce->sleep_ms) { - usleep(WORK_CHECK_INTERVAL_MS*1000); - bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; - if (work_restart[thr->id].restart) { - applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); - return 1; //we have discarded all work; equivilent to 0 hashes done. - } + ret = bitforce_send_work(thr, work); + + if(!opt_submit_stale || !submit_old) { + while (bitforce->wait_ms < bitforce->sleep_ms) { + usleep(WORK_CHECK_INTERVAL_MS*1000); + bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; + if (work_restart[thr->id].restart) { + applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); + return 1; //we have discarded all work; equivilent to 0 hashes done. } - } else { - usleep(bitforce->sleep_ms*1000); - bitforce->wait_ms = bitforce->sleep_ms; } - ret = bitforce_get_result(thr, work); + } else { + usleep(bitforce->sleep_ms*1000); + bitforce->wait_ms = bitforce->sleep_ms; } + if (ret) + ret = bitforce_get_result(thr, work); + if (!ret) { ret = 1; applog(LOG_ERR, "BFL%i: Comms error", bitforce->device_id); @@ -411,3 +419,4 @@ struct device_api bitforce_api = { .thread_shutdown = bitforce_shutdown, .thread_enable = biforce_thread_enable }; + From f2253929903a04af719b6636d51a20b87439d91a Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Thu, 28 Jun 2012 08:20:45 -0700 Subject: [PATCH 29/38] Add low hash threshold in sick/dead processing Add check for fd in comms procedures --- cgminer.c | 32 +++++++++++++++++++++++++++----- driver-bitforce.c | 17 +++++++++++------ miner.h | 2 ++ 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/cgminer.c b/cgminer.c index 8b7de73f..ced66636 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3648,7 +3648,8 @@ static inline bool should_roll(struct work *work) * reject blocks as invalid. */ static inline bool can_roll(struct work *work) { - return (work->pool && work->rolltime && !work->clone && work->rolls < 7000); + return (work->pool && work->rolltime && !work->clone && +work->rolls < 7000 && !stale_work(work, false)); } static void roll_work(struct work *work) @@ -4404,9 +4405,16 @@ static void age_work(void) /* Makes sure the hashmeter keeps going even if mining threads stall, updates * the screen at regular intervals, and restarts threads if they appear to have * died. */ +#define WATCHDOG_INTERVAL 3 +#define WATCHDOG_SICK_TIME 60 +#define WATCHDOG_DEAD_TIME 600 +#define WATCHDOG_SICK_COUNT (WATCHDOG_SICK_TIME/WATCHDOG_INTERVAL) +#define WATCHDOG_DEAD_COUNT (WATCHDOG_DEAD_TIME/WATCHDOG_INTERVAL) +#define WATCHDOG_LOW_HASH 1.0 /* consider < 1MH too low for any device */ + static void *watchdog_thread(void __maybe_unused *userdata) { - const unsigned int interval = 3; + const unsigned int interval = WATCHDOG_INTERVAL; struct timeval zero_tv; pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); @@ -4510,11 +4518,24 @@ static void *watchdog_thread(void __maybe_unused *userdata) if (thr->getwork || *denable == DEV_DISABLED) continue; - if (cgpu->status != LIFE_WELL && now.tv_sec - thr->last.tv_sec < 60) { + if (cgpu->rolling < WATCHDOG_LOW_HASH) + cgpu->low_count++; + else + cgpu->low_count = 0; + + uint64_t hashtime = now.tv_sec - thr->last.tv_sec; + bool dev_time_well = hashtime < WATCHDOG_SICK_TIME; + bool dev_time_sick = hashtime > WATCHDOG_SICK_TIME; + bool dev_time_dead = hashtime > WATCHDOG_DEAD_TIME; + bool dev_count_well = cgpu->low_count < WATCHDOG_SICK_COUNT; + bool dev_count_sick = cgpu->low_count > WATCHDOG_SICK_COUNT; + bool dev_count_dead = cgpu->low_count > WATCHDOG_DEAD_COUNT; + + if (cgpu->status != LIFE_WELL && dev_time_well && dev_count_well) { applog(LOG_ERR, "%s: Recovered, declaring WELL!", dev_str); cgpu->status = LIFE_WELL; cgpu->device_last_well = time(NULL); - } else if (now.tv_sec - thr->last.tv_sec > 60 && cgpu->status == LIFE_WELL) { + } else if (cgpu->status == LIFE_WELL && (dev_time_sick || dev_count_sick)) { thr->rolling = cgpu->rolling = 0; cgpu->status = LIFE_SICK; applog(LOG_ERR, "%s: Idle for more than 60 seconds, declaring SICK!", dev_str); @@ -4533,7 +4554,7 @@ static void *watchdog_thread(void __maybe_unused *userdata) applog(LOG_ERR, "%s: Attempting to restart", dev_str); reinit_device(cgpu); } - } else if (now.tv_sec - thr->last.tv_sec > 600 && cgpu->status == LIFE_SICK) { + } else if (cgpu->status == LIFE_SICK && (dev_time_dead || dev_count_dead)) { cgpu->status = LIFE_DEAD; applog(LOG_ERR, "%s: Not responded for more than 10 minutes, declaring DEAD!", dev_str); gettimeofday(&thr->sick, NULL); @@ -5473,3 +5494,4 @@ begin_bench: return 0; } + diff --git a/driver-bitforce.c b/driver-bitforce.c index 63729446..0a47df55 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -144,13 +144,12 @@ void bitforce_init(struct cgpu_info *bitforce) char pdevbuf[0x100]; char *s; - applog(LOG_INFO, "BFL%i: Re-initalizing", bitforce->device_id); + applog(LOG_WARNING, "BFL%i: Re-initalizing", bitforce->device_id); mutex_lock(&bitforce->device_mutex); - if (fdDev) { + if (fdDev) BFclose(fdDev); - bitforce->device_fd = 0; - } + bitforce->device_fd = 0; fdDev = BFopen(devpath); if (unlikely(fdDev == -1)) { @@ -228,6 +227,9 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) unsigned char ob[61] = ">>>>>>>>12345678901234567890123456789012123456789012>>>>>>>>"; char *s; + if (!fdDev) + return false; + mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZDX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); @@ -277,6 +279,9 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) char *pnoncebuf; uint32_t nonce; + if (!fdDev) + return 0; + while (bitforce->wait_ms < BITFORCE_TIMEOUT_MS) { mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZFX", 3); @@ -284,7 +289,6 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { applog(LOG_ERR, "BFL%i: Error reading (ZFX)", bitforce->device_id); - mutex_unlock(&bitforce->device_mutex); return 0; } if (pdevbuf[0] != 'B') @@ -366,7 +370,7 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; if (work_restart[thr->id].restart) { applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); - return 1; //we have discarded all work; equivilent to 0 hashes done. + return 1; //we have discarded all work; equivalent to 0 hashes done. } } } else { @@ -420,3 +424,4 @@ struct device_api bitforce_api = { .thread_enable = biforce_thread_enable }; + diff --git a/miner.h b/miner.h index 9347d191..d32f6f02 100644 --- a/miner.h +++ b/miner.h @@ -326,6 +326,7 @@ struct cgpu_info { int accepted; int rejected; int hw_errors; + unsigned int low_count; double rolling; double total_mhashes; double utility; @@ -796,3 +797,4 @@ extern void adl(void); extern void app_restart(void); #endif /* __MINER_H__ */ + From 123058b587c1cc38a6a6d2fe0073f532d7936347 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Thu, 28 Jun 2012 11:02:03 -0700 Subject: [PATCH 30/38] Add macro roundl for compilers without said function. --- miner.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/miner.h b/miner.h index 57fa774f..1e42c6fc 100644 --- a/miner.h +++ b/miner.h @@ -159,6 +159,10 @@ void *alloca (size_t); #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #endif +#ifndef roundl +#define roundl(x) (long double)((long long)((x==0)?0.0:((x)+((x)>0)?0.5:-0.5))) +#endif + enum alive { LIFE_WELL, LIFE_SICK, From 75a651c13fe6365175e042f4a2319326d4ce503d Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Thu, 28 Jun 2012 16:08:10 -0700 Subject: [PATCH 31/38] Revert "Check for submit_stale before checking for work_restart" Makes no sense to continue working on the old block whether submit_stale is enabled or not. --- cgminer.c | 2 +- driver-bitforce.c | 20 ++++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/cgminer.c b/cgminer.c index 31b58208..d9e6cd00 100644 --- a/cgminer.c +++ b/cgminer.c @@ -125,7 +125,7 @@ bool use_curses = true; #else bool use_curses; #endif -bool opt_submit_stale = true; +static bool opt_submit_stale = true; static int opt_shares; static bool opt_fail_only; bool opt_autofan; diff --git a/driver-bitforce.c b/driver-bitforce.c index 0a47df55..29d27c91 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -353,29 +353,21 @@ static void biforce_thread_enable(struct thr_info *thr) bitforce_init(bitforce); } -extern bool opt_submit_stale; - static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; - bool submit_old = work->pool->submit_old; bitforce->wait_ms = 0; uint64_t ret; ret = bitforce_send_work(thr, work); - if(!opt_submit_stale || !submit_old) { - while (bitforce->wait_ms < bitforce->sleep_ms) { - usleep(WORK_CHECK_INTERVAL_MS*1000); - bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; - if (work_restart[thr->id].restart) { - applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); - return 1; //we have discarded all work; equivalent to 0 hashes done. - } + while (bitforce->wait_ms < bitforce->sleep_ms) { + usleep(WORK_CHECK_INTERVAL_MS*1000); + bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; + if (work_restart[thr->id].restart) { + applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); + return 1; //we have discarded all work; equivilent to 0 hashes done. } - } else { - usleep(bitforce->sleep_ms*1000); - bitforce->wait_ms = bitforce->sleep_ms; } if (ret) From 86c8bbe57e71981bfcedc04f4f58fdaf614ba265 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Fri, 29 Jun 2012 17:19:28 -0700 Subject: [PATCH 32/38] Need to run Hashmeter all the time. and not just if logging/display is enabled --- cgminer.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cgminer.c b/cgminer.c index d9e6cd00..0e8e221c 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3338,10 +3338,6 @@ static void hashmeter(int thr_id, struct timeval *diff, thr_info[thr_id].cgpu->device_last_well = time(NULL); } - /* Don't bother calculating anything if we're not displaying it */ - if (opt_realquiet || !opt_log_interval) - return; - secs = (double)diff->tv_sec + ((double)diff->tv_usec / 1000000.0); /* So we can call hashmeter from a non worker thread */ From adc26f0e3f3034fb78c351112f3d428ec94c157b Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Fri, 29 Jun 2012 17:20:57 -0700 Subject: [PATCH 33/38] Add facility to clear BFL read buffer. Reduce timeout to 10s. --- driver-bitforce.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 29d27c91..eec3ecfb 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -21,7 +21,7 @@ #include "miner.h" #define BITFORCE_SLEEP_MS 2000 -#define BITFORCE_TIMEOUT_MS 15000 +#define BITFORCE_TIMEOUT_MS 10000 #define BITFORCE_CHECK_INTERVAL_MS 10 #define WORK_CHECK_INTERVAL_MS 50 #define MAX_START_DELAY_US 100000 @@ -34,8 +34,7 @@ static void BFgets(char *buf, size_t bufLen, int fd) { do --bufLen; - while (likely(bufLen && read(fd, buf, 1) && (buf++)[0] != '\n')) - ; + while (likely(bufLen && read(fd, buf, 1) && (buf++)[0] != '\n')); buf[0] = '\0'; } @@ -137,6 +136,21 @@ static bool bitforce_thread_prepare(struct thr_info *thr) return true; } +static void biforce_clear_buffer(struct cgpu_info *bitforce) +{ + int fdDev = bitforce->device_fd; + char pdevbuf[0x100]; + + applog(LOG_DEBUG, "BFL%i: Clearing read buffer", bitforce->device_id); + + mutex_lock(&bitforce->device_mutex); + do { + pdevbuf[0] = '\0'; + BFgets(pdevbuf, sizeof(pdevbuf), fdDev); + } while (pdevbuf[0]); + mutex_unlock(&bitforce->device_mutex); +} + void bitforce_init(struct cgpu_info *bitforce) { int fdDev = bitforce->device_fd; @@ -146,6 +160,8 @@ void bitforce_init(struct cgpu_info *bitforce) applog(LOG_WARNING, "BFL%i: Re-initalizing", bitforce->device_id); + biforce_clear_buffer(bitforce); + mutex_lock(&bitforce->device_mutex); if (fdDev) BFclose(fdDev); @@ -297,7 +313,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) bitforce->wait_ms += BITFORCE_CHECK_INTERVAL_MS; } if (bitforce->wait_ms >= BITFORCE_TIMEOUT_MS) { - applog(LOG_ERR, "BFL%i: took longer than 15s", bitforce->device_id); + applog(LOG_ERR, "BFL%i: took longer than 10s", bitforce->device_id); bitforce->device_last_not_well = time(NULL); bitforce->device_not_well_reason = REASON_DEV_OVER_HEAT; bitforce->dev_over_heat_count++; @@ -353,6 +369,8 @@ static void biforce_thread_enable(struct thr_info *thr) bitforce_init(bitforce); } + + static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; @@ -379,6 +397,8 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 bitforce->device_last_not_well = time(NULL); bitforce->device_not_well_reason = REASON_DEV_NOSTART; bitforce->dev_nostart_count++; + /* empty read buffer */ + biforce_clear_buffer(bitforce); } return ret; } From efaa7398fb56a17ccfcb3645369ec1abba1dd6e6 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sat, 30 Jun 2012 11:59:53 -0700 Subject: [PATCH 34/38] Tweak sick/dead logic (remove pre-computed time calculations) --- cgminer.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/cgminer.c b/cgminer.c index 0e8e221c..861332a5 100644 --- a/cgminer.c +++ b/cgminer.c @@ -4534,19 +4534,15 @@ static void *watchdog_thread(void __maybe_unused *userdata) else cgpu->low_count = 0; - uint64_t hashtime = now.tv_sec - thr->last.tv_sec; - bool dev_time_well = hashtime < WATCHDOG_SICK_TIME; - bool dev_time_sick = hashtime > WATCHDOG_SICK_TIME; - bool dev_time_dead = hashtime > WATCHDOG_DEAD_TIME; - bool dev_count_well = cgpu->low_count < WATCHDOG_SICK_COUNT; - bool dev_count_sick = cgpu->low_count > WATCHDOG_SICK_COUNT; - bool dev_count_dead = cgpu->low_count > WATCHDOG_DEAD_COUNT; + bool dev_count_well = (cgpu->low_count < WATCHDOG_SICK_COUNT); + bool dev_count_sick = (cgpu->low_count > WATCHDOG_SICK_COUNT); + bool dev_count_dead = (cgpu->low_count > WATCHDOG_DEAD_COUNT); - if (cgpu->status != LIFE_WELL && dev_time_well && dev_count_well) { + if (gpus[gpu].status != LIFE_WELL && (now.tv_sec - thr->last.tv_sec < WATCHDOG_SICK_TIME) && dev_count_well) { applog(LOG_ERR, "%s: Recovered, declaring WELL!", dev_str); cgpu->status = LIFE_WELL; cgpu->device_last_well = time(NULL); - } else if (cgpu->status == LIFE_WELL && (dev_time_sick || dev_count_sick)) { + } else if (cgpu->status == LIFE_WELL && ((now.tv_sec - thr->last.tv_sec > WATCHDOG_SICK_TIME) || dev_count_sick)) { thr->rolling = cgpu->rolling = 0; cgpu->status = LIFE_SICK; applog(LOG_ERR, "%s: Idle for more than 60 seconds, declaring SICK!", dev_str); @@ -4565,7 +4561,7 @@ static void *watchdog_thread(void __maybe_unused *userdata) applog(LOG_ERR, "%s: Attempting to restart", dev_str); reinit_device(cgpu); } - } else if (cgpu->status == LIFE_SICK && (dev_time_dead || dev_count_dead)) { + } else if (cgpu->status == LIFE_SICK && ((now.tv_sec - thr->last.tv_sec > WATCHDOG_DEAD_TIME) || dev_count_dead)) { cgpu->status = LIFE_DEAD; applog(LOG_ERR, "%s: Not responded for more than 10 minutes, declaring DEAD!", dev_str); gettimeofday(&thr->sick, NULL); From a11a322ba6da0fd40aee0d6f61bf9c598066cd2a Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sat, 30 Jun 2012 20:45:08 -0700 Subject: [PATCH 35/38] Add tiny delay after writing to BFL Change BFL errors to something more human readable Send work busy re-tries after 10ms delay --- driver-bitforce.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index eec3ecfb..af6989e1 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -43,8 +43,10 @@ static ssize_t BFwrite(int fd, const void *buf, ssize_t bufLen) if ((bufLen) != write(fd, buf, bufLen)) { applog(LOG_ERR, "BFL: Error writing: %s", buf); return 0; - } else + } else { + usleep(100); return bufLen; + } } #define BFclose(fd) close(fd) @@ -214,7 +216,7 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce) mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "BFL%i: Error reading (ZLX)", bitforce->device_id); + applog(LOG_ERR, "BFL%i: Error: Get temp returned empty string", bitforce->device_id); bitforce->temp = 0; return false; } @@ -245,22 +247,21 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) if (!fdDev) return false; - +re_send: mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZDX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "BFL%i: Error reading (ZDX)", bitforce->device_id); + applog(LOG_ERR, "BFL%i: Error: Send work returned empty string", bitforce->device_id); mutex_unlock(&bitforce->device_mutex); return false; - } - if (pdevbuf[0] == 'B'){ - applog(LOG_WARNING, "BFL%i: Throttling", bitforce->device_id); + } else if (pdevbuf[0] == 'B'){ + applog(LOG_DEBUG, "BFL%i: Busy", bitforce->device_id); mutex_unlock(&bitforce->device_mutex); - return true; - } - else if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { - applog(LOG_ERR, "BFL%i: ZDX reports: %s", bitforce->device_id, pdevbuf); + usleep(BITFORCE_CHECK_INTERVAL_MS*1000); + goto re_send; + } else if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { + applog(LOG_ERR, "BFL%i: Error: Send work reports: %s", bitforce->device_id, pdevbuf); mutex_unlock(&bitforce->device_mutex); return false; } @@ -276,11 +277,11 @@ static bool bitforce_send_work(struct thr_info *thr, struct work *work) BFgets(pdevbuf, sizeof(pdevbuf), fdDev); mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "BFL%i: Error reading (block data)", bitforce->device_id); + applog(LOG_ERR, "BFL%i: Error: Send block data returned empty string", bitforce->device_id); return false; } if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { - applog(LOG_ERR, "BFL%i: block data reports: %s", bitforce->device_id, pdevbuf); + applog(LOG_ERR, "BFL%i: Error: Send block data reports: %s", bitforce->device_id, pdevbuf); return false; } return true; @@ -304,7 +305,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) BFgets(pdevbuf, sizeof(pdevbuf), fdDev); mutex_unlock(&bitforce->device_mutex); if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "BFL%i: Error reading (ZFX)", bitforce->device_id); + applog(LOG_ERR, "BFL%i: Error: Get result returned empty string", bitforce->device_id); return 0; } if (pdevbuf[0] != 'B') @@ -333,7 +334,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) else if (pdevbuf[0] == 'I') return 1; /* Device idle */ else if (strncasecmp(pdevbuf, "NONCE-FOUND", 11)) { - applog(LOG_WARNING, "BFL%i: result reports: %s", bitforce->device_id, pdevbuf); + applog(LOG_WARNING, "BFL%i: Error: Get result reports: %s", bitforce->device_id, pdevbuf); return 1; } From 855d1bb3e33dd2c12f7edbfe3dd7dfab6a9de03e Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sun, 1 Jul 2012 17:35:53 -0700 Subject: [PATCH 36/38] Add busy time to wait time. --- driver-bitforce.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index af6989e1..4a608724 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -255,9 +255,10 @@ re_send: applog(LOG_ERR, "BFL%i: Error: Send work returned empty string", bitforce->device_id); mutex_unlock(&bitforce->device_mutex); return false; - } else if (pdevbuf[0] == 'B'){ + } else if (pdevbuf[0] == 'B') { applog(LOG_DEBUG, "BFL%i: Busy", bitforce->device_id); mutex_unlock(&bitforce->device_mutex); + bitforce->wait_ms += BITFORCE_CHECK_INTERVAL_MS; usleep(BITFORCE_CHECK_INTERVAL_MS*1000); goto re_send; } else if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { From 04a6c3b18847db1fa351e4a38c90efeeb38ed640 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Sun, 1 Jul 2012 21:47:18 -0700 Subject: [PATCH 37/38] More improvements to comms. BFL return nothing when throttling, so should not be considered an error. Instead repeat with a longer delay. --- driver-bitforce.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 4a608724..8f21a3e6 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -251,15 +251,10 @@ re_send: mutex_lock(&bitforce->device_mutex); BFwrite(fdDev, "ZDX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); - if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "BFL%i: Error: Send work returned empty string", bitforce->device_id); + if (!pdevbuf[0] || (pdevbuf[0] == 'B')) { mutex_unlock(&bitforce->device_mutex); - return false; - } else if (pdevbuf[0] == 'B') { - applog(LOG_DEBUG, "BFL%i: Busy", bitforce->device_id); - mutex_unlock(&bitforce->device_mutex); - bitforce->wait_ms += BITFORCE_CHECK_INTERVAL_MS; - usleep(BITFORCE_CHECK_INTERVAL_MS*1000); + bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; + usleep(WORK_CHECK_INTERVAL_MS*1000); goto re_send; } else if (unlikely(pdevbuf[0] != 'O' || pdevbuf[1] != 'K')) { applog(LOG_ERR, "BFL%i: Error: Send work reports: %s", bitforce->device_id, pdevbuf); @@ -296,6 +291,7 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) char pdevbuf[0x100]; char *pnoncebuf; uint32_t nonce; + unsigned int delay_time_ms = BITFORCE_CHECK_INTERVAL_MS; if (!fdDev) return 0; @@ -305,14 +301,12 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) BFwrite(fdDev, "ZFX", 3); BFgets(pdevbuf, sizeof(pdevbuf), fdDev); mutex_unlock(&bitforce->device_mutex); - if (unlikely(!pdevbuf[0])) { - applog(LOG_ERR, "BFL%i: Error: Get result returned empty string", bitforce->device_id); - return 0; - } - if (pdevbuf[0] != 'B') + if (pdevbuf[0] && pdevbuf[0] != 'B') /* BFL does not respond during throttling */ break; - usleep(BITFORCE_CHECK_INTERVAL_MS*1000); - bitforce->wait_ms += BITFORCE_CHECK_INTERVAL_MS; + /* if BFL is throttling, no point checking so quickly */ + delay_time_ms = (pdevbuf[0] ? BITFORCE_CHECK_INTERVAL_MS : 2*WORK_CHECK_INTERVAL_MS); + usleep(delay_time_ms*1000); + bitforce->wait_ms += delay_time_ms; } if (bitforce->wait_ms >= BITFORCE_TIMEOUT_MS) { applog(LOG_ERR, "BFL%i: took longer than 10s", bitforce->device_id); @@ -376,9 +370,9 @@ static void biforce_thread_enable(struct thr_info *thr) static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint64_t __maybe_unused max_nonce) { struct cgpu_info *bitforce = thr->cgpu; - bitforce->wait_ms = 0; uint64_t ret; + bitforce->wait_ms = 0; ret = bitforce_send_work(thr, work); while (bitforce->wait_ms < bitforce->sleep_ms) { From ad5b470b0461dc61727c35dc64e33765947696f9 Mon Sep 17 00:00:00 2001 From: Paul Sheppard Date: Mon, 2 Jul 2012 14:27:19 -0700 Subject: [PATCH 38/38] Fine-tune timing adjustment. Also remove old work_restart timing. --- driver-bitforce.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/driver-bitforce.c b/driver-bitforce.c index 53280778..d0c99c21 100644 --- a/driver-bitforce.c +++ b/driver-bitforce.c @@ -316,10 +316,13 @@ static uint64_t bitforce_get_result(struct thr_info *thr, struct work *work) return 1; } else if (pdevbuf[0] == 'N') {/* Hashing complete (NONCE-FOUND or NO-NONCE) */ /* Simple timing adjustment */ - if (bitforce->wait_ms > (bitforce->sleep_ms + WORK_CHECK_INTERVAL_MS)) - bitforce->sleep_ms += WORK_CHECK_INTERVAL_MS; + delay_time_ms = bitforce->sleep_ms; + if (bitforce->wait_ms > (bitforce->sleep_ms + BITFORCE_CHECK_INTERVAL_MS)) + bitforce->sleep_ms += (unsigned int) ((double) (bitforce->wait_ms - bitforce->sleep_ms) / 1.6); else if (bitforce->wait_ms == bitforce->sleep_ms) - bitforce->sleep_ms -= WORK_CHECK_INTERVAL_MS; + bitforce->sleep_ms -= BITFORCE_CHECK_INTERVAL_MS; + if (delay_time_ms != bitforce->sleep_ms) + applog(LOG_DEBUG, "BFL%i: Wait time changed to: %d. Waited: %d", bitforce->device_id, bitforce->sleep_ms, bitforce->wait_ms); } applog(LOG_DEBUG, "BFL%i: waited %dms until %s", bitforce->device_id, bitforce->wait_ms, pdevbuf); @@ -392,16 +395,7 @@ static uint64_t bitforce_scanhash(struct thr_info *thr, struct work *work, uint6 if (!restart_wait(&tdiff)) return 1; bitforce->wait_ms += sleep_time; -/* - while (bitforce->wait_ms < bitforce->sleep_ms) { - usleep(WORK_CHECK_INTERVAL_MS*1000); - bitforce->wait_ms += WORK_CHECK_INTERVAL_MS; - if (work_restart[thr->id].restart) { - applog(LOG_DEBUG, "BFL%i: Work restart, discarding after %dms", bitforce->device_id, bitforce->wait_ms); - return 1; //we have discarded all work; equivilent to 0 hashes done. - } - } -*/ + if (ret) ret = bitforce_get_result(thr, work);