From 852f6a0eb02f1c5a715a62e6b1142ca684aa4611 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 3 May 2012 22:39:12 +1000 Subject: [PATCH 1/6] Don't try to reap curls if benchmarking is enabled. --- cgminer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index 26259c6e..58731a9c 100644 --- a/cgminer.c +++ b/cgminer.c @@ -4058,7 +4058,8 @@ static void *watchpool_thread(void __maybe_unused *userdata) for (i = 0; i < total_pools; i++) { struct pool *pool = pools[i]; - reap_curl(pool); + if (!opt_benchmark) + reap_curl(pool); if (!pool->enabled) continue; From 44fc698750a22a7c13637dbe2ef6020a9efb7df6 Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 4 May 2012 00:13:42 +1000 Subject: [PATCH 2/6] API add last share time to each pool --- api.c | 8 ++++---- cgminer.c | 1 + miner.h | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/api.c b/api.c index 8571dccd..1bf9b2b7 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.9"; +static const char *APIVERSION = "1.10"; static const char *DEAD = "Dead"; static const char *SICK = "Sick"; static const char *NOSTART = "NoStart"; @@ -1221,8 +1221,8 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, rpc_user = escape_string(pool->rpc_user, isjson); sprintf(buf, isjson - ? "%s{\"POOL\":%d,\"URL\":\"%s\",\"Status\":\"%s\",\"Priority\":%d,\"Long Poll\":\"%s\",\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Remote Failures\":%d,\"User\":\"%s\"}" - : "%sPOOL=%d,URL=%s,Status=%s,Priority=%d,Long Poll=%s,Getworks=%d,Accepted=%d,Rejected=%d,Discarded=%d,Stale=%d,Get Failures=%d,Remote Failures=%d,User=%s" SEPSTR, + ? "%s{\"POOL\":%d,\"URL\":\"%s\",\"Status\":\"%s\",\"Priority\":%d,\"Long Poll\":\"%s\",\"Getworks\":%d,\"Accepted\":%d,\"Rejected\":%d,\"Discarded\":%d,\"Stale\":%d,\"Get Failures\":%d,\"Remote Failures\":%d,\"User\":\"%s\",\"Last Share Time\":%lu}" + : "%sPOOL=%d,URL=%s,Status=%s,Priority=%d,Long Poll=%s,Getworks=%d,Accepted=%d,Rejected=%d,Discarded=%d,Stale=%d,Get Failures=%d,Remote Failures=%d,User=%s,Last Share Time=%lu" SEPSTR, (isjson && (i > 0)) ? COMMA : BLANK, i, rpc_url, status, pool->prio, lp, pool->getwork_requested, @@ -1231,7 +1231,7 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, pool->stale_shares, pool->getfail_occasions, pool->remotefail_occasions, - rpc_user); + rpc_user, pool->last_share_time); strcat(io_buffer, buf); diff --git a/cgminer.c b/cgminer.c index 58731a9c..d3937458 100644 --- a/cgminer.c +++ b/cgminer.c @@ -1660,6 +1660,7 @@ static bool submit_upstream_work(const struct work *work, CURL *curl) pool->seq_rejects = 0; cgpu->last_share_pool = pool->pool_no; cgpu->last_share_pool_time = time(NULL); + pool->last_share_time = cgpu->last_share_pool_time; applog(LOG_DEBUG, "PROOF OF WORK RESULT: true (yay!!!)"); if (!QUIET) { if (total_pools > 1) diff --git a/miner.h b/miner.h index 27decf2d..4115cc5b 100644 --- a/miner.h +++ b/miner.h @@ -645,6 +645,8 @@ struct pool { int curls; pthread_cond_t cr_cond; struct list_head curlring; + + time_t last_share_time; }; struct work { From b3a50dd465d9e82546ef03a624d24fdd50fb70b0 Mon Sep 17 00:00:00 2001 From: Kano Date: Fri, 4 May 2012 10:35:45 +1000 Subject: [PATCH 3/6] Icarus - correct MH/s and U: with work restart set at 8 seconds --- driver-icarus.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/driver-icarus.c b/driver-icarus.c index 7a7ec494..47b0b164 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -72,12 +72,8 @@ // 2 x 11.1 / (5.26 x 10^-9) //#define ESTIMATE_HASHES 0xFB90365E -// This is the 8s value but causes hash rate loss -//#define ESTIMATE_HASHES 0xB54E9147 - -// TODO: determine why returning any other value when no nonce is found -// causes hash rate loss -#define ESTIMATE_HASHES 0xffffffff +// This is the 8s value +#define ESTIMATE_HASHES 0xB54E9147 struct device_api icarus_api; @@ -353,6 +349,7 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, if (opt_debug) gettimeofday(&tv_finish, NULL); + work->blk.nonce = 0xffffffff; memcpy((char *)&nonce, nonce_bin, sizeof(nonce_bin)); // aborted before becoming idle, get new work @@ -369,7 +366,6 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work, nonce = swab32(nonce); #endif - work->blk.nonce = 0xffffffff; submit_nonce(thr, work, nonce); if (opt_debug) { From 4d090a587cd3df350d05c333ec72178518f7679d Mon Sep 17 00:00:00 2001 From: ckolivas Date: Fri, 4 May 2012 12:51:32 +1000 Subject: [PATCH 4/6] Reset sequential reject counter after a pool is disabled for when it is re-enabled. --- cgminer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cgminer.c b/cgminer.c index 58731a9c..d1713cc7 100644 --- a/cgminer.c +++ b/cgminer.c @@ -1724,6 +1724,7 @@ static bool submit_upstream_work(const struct work *work, CURL *curl) pool->enabled = false; if (pool == current_pool()) switch_pools(NULL); + pool->seq_rejects = 0; } } } From 376fcd3c02df9b934ab739e8ec7916c27d12bc29 Mon Sep 17 00:00:00 2001 From: ckolivas Date: Fri, 4 May 2012 13:10:18 +1000 Subject: [PATCH 5/6] Fix the benchmark feature by bypassing the new networking code. --- cgminer.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/cgminer.c b/cgminer.c index d1713cc7..a4097975 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2043,25 +2043,30 @@ static void *get_work_thread(void *userdata) else ret_work->thr = NULL; - pool = ret_work->pool = select_pool(wc->lagging); - ce = pop_curl_entry(pool); + if (opt_benchmark) + get_benchmark_work(ret_work); + else { + pool = ret_work->pool = select_pool(wc->lagging); + + ce = pop_curl_entry(pool); + + /* obtain new work from bitcoin via JSON-RPC */ + while (!get_upstream_work(ret_work, ce->curl)) { + if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) { + applog(LOG_ERR, "json_rpc_call failed, terminating workio thread"); + free_work(ret_work); + kill_work(); + goto out; + } - /* obtain new work from bitcoin via JSON-RPC */ - while (!get_upstream_work(ret_work, ce->curl)) { - if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) { - applog(LOG_ERR, "json_rpc_call failed, terminating workio thread"); - free_work(ret_work); - kill_work(); - goto out; + /* pause, then restart work-request loop */ + applog(LOG_DEBUG, "json_rpc_call failed on get work, retry after %d seconds", + fail_pause); + sleep(fail_pause); + fail_pause += opt_fail_pause; } - - /* pause, then restart work-request loop */ - applog(LOG_DEBUG, "json_rpc_call failed on get work, retry after %d seconds", - fail_pause); - sleep(fail_pause); - fail_pause += opt_fail_pause; + fail_pause = opt_fail_pause; } - fail_pause = opt_fail_pause; applog(LOG_DEBUG, "Pushing work to requesting thread"); @@ -2074,7 +2079,8 @@ static void *get_work_thread(void *userdata) out: workio_cmd_free(wc); - push_curl_entry(ce, pool); + if (!opt_benchmark) + push_curl_entry(ce, pool); return NULL; } From 4987958e6a9bd85a580931dcaf7c8eddec49365c Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 4 May 2012 20:10:38 +1000 Subject: [PATCH 6/6] Add a temporarily disabled state for enabled pools called POOL_REJECTING and use the work from each longpoll to help determine when a rejecting pool has started working again. Switch pools based on the multipool strategy once a pool is re-enabled. --- cgminer.c | 63 ++++++++++++++++++++++++++++++++++++++----------------- miner.h | 8 ++++++- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/cgminer.c b/cgminer.c index db8a0339..b2bcd5ae 100644 --- a/cgminer.c +++ b/cgminer.c @@ -1676,6 +1676,16 @@ static bool submit_upstream_work(const struct work *work, CURL *curl) kill_work(); goto out; } + + /* Detect if a pool that has been temporarily disabled for + * continually rejecting shares has started accepting shares. + * This will only happen with the work returned from a + * longpoll */ + if (unlikely(pool->enabled == POOL_REJECTING)) { + applog(LOG_WARNING, "Rejecting pool %d now accepting shares, re-enabling!", pool->pool_no); + pool->enabled = POOL_ENABLED; + switch_pools(NULL); + } } else { cgpu->rejected++; total_rejected++; @@ -1722,7 +1732,7 @@ static bool submit_upstream_work(const struct work *work, CURL *curl) if (pool->seq_rejects > utility) { applog(LOG_WARNING, "Pool %d rejected %d sequential shares, disabling!", pool->pool_no, pool->seq_rejects); - pool->enabled = false; + pool->enabled = POOL_REJECTING; if (pool == current_pool()) switch_pools(NULL); pool->seq_rejects = 0; @@ -1770,7 +1780,7 @@ static inline struct pool *select_pool(bool lagging) if (++rotating_pool >= total_pools) rotating_pool = 0; pool = pools[rotating_pool]; - if ((!pool->idle && pool->enabled) || pool == cp) + if ((!pool->idle && pool->enabled == POOL_ENABLED) || pool == cp) break; pool = NULL; } @@ -2102,6 +2112,7 @@ static bool workio_get_work(struct workio_cmd *wc) static bool stale_work(struct work *work, bool share) { struct timeval now; + struct pool *pool; if (opt_benchmark) return false; @@ -2116,7 +2127,8 @@ static bool stale_work(struct work *work, bool share) if (work->work_block != work_block) return true; - if (opt_fail_only && !share && work->pool != current_pool()) + pool = work->pool; + if (opt_fail_only && !share && pool != current_pool() && pool->enabled != POOL_REJECTING) return true; return false; @@ -2241,7 +2253,7 @@ void switch_pools(struct pool *selected) case POOL_LOADBALANCE: for (i = 0; i < total_pools; i++) { pool = priority_pool(i); - if (!pool->idle && pool->enabled) { + if (!pool->idle && pool->enabled == POOL_ENABLED) { pool_no = pool->pool_no; break; } @@ -2550,7 +2562,7 @@ int active_pools(void) int i; for (i = 0; i < total_pools; i++) { - if ((pools[i])->enabled) + if ((pools[i])->enabled == POOL_ENABLED) ret++; } return ret; @@ -2772,11 +2784,21 @@ updated: if (pool == current_pool()) wattron(logwin, A_BOLD); - if (!pool->enabled) + if (pool->enabled != POOL_ENABLED) wattron(logwin, A_DIM); - wlogprint("%d: %s %s Priority %d: %s User:%s\n", - pool->pool_no, - pool->enabled? "Enabled" : "Disabled", + wlogprint("%d: "); + switch (pool->enabled) { + case POOL_ENABLED: + wlogprint("Enabled "); + break; + case POOL_DISABLED: + wlogprint("Disabled "); + break; + case POOL_REJECTING: + wlogprint("Rejecting "); + break; + } + wlogprint("%s Priority %d: %s User:%s\n", pool->idle? "Dead" : "Alive", pool->prio, pool->rpc_url, pool->rpc_user); @@ -2812,7 +2834,7 @@ retry: wlogprint("Unable to remove pool due to activity\n"); goto retry; } - pool->enabled = false; + pool->enabled = POOL_DISABLED; remove_pool(pool); goto updated; } else if (!strncasecmp(&input, "s", 1)) { @@ -2822,7 +2844,7 @@ retry: goto retry; } pool = pools[selected]; - pool->enabled = true; + pool->enabled = POOL_ENABLED; switch_pools(pool); goto updated; } else if (!strncasecmp(&input, "d", 1)) { @@ -2836,7 +2858,7 @@ retry: goto retry; } pool = pools[selected]; - pool->enabled = false; + pool->enabled = POOL_DISABLED; if (pool == current_pool()) switch_pools(NULL); goto updated; @@ -2847,7 +2869,7 @@ retry: goto retry; } pool = pools[selected]; - pool->enabled = true; + pool->enabled = POOL_ENABLED; if (pool->prio < current_pool()->prio) switch_pools(pool); goto updated; @@ -3888,8 +3910,11 @@ static void convert_to_work(json_t *val, bool rolltime, struct pool *pool) * allows testwork to know whether LP discovered the block or not. */ test_work_current(work); - /* Don't use backup LPs as work if we have failover-only enabled */ - if (pool != current_pool() && opt_fail_only) { + /* Don't use backup LPs as work if we have failover-only enabled. Use + * the longpoll work from a pool that has been rejecting shares as a + * way to detect when the pool has recovered. + */ + if (pool != current_pool() && opt_fail_only && pool->enabled != POOL_REJECTING) { free_work(work); return; } @@ -4068,7 +4093,7 @@ static void *watchpool_thread(void __maybe_unused *userdata) if (!opt_benchmark) reap_curl(pool); - if (!pool->enabled) + if (pool->enabled != POOL_ENABLED) continue; /* Test pool is idle once every minute */ @@ -4417,7 +4442,7 @@ int add_pool_details(bool live, char *url, char *user, char *pass) /* Test the pool is not idle if we're live running, otherwise * it will be tested separately */ - pool->enabled = true; + pool->enabled = POOL_ENABLED; if (live && !pool_active(pool, false)) pool->idle = true; @@ -4737,7 +4762,7 @@ int main(int argc, char *argv[]) strcpy(pool->rpc_url, "Benchmark"); pool->rpc_user = pool->rpc_url; pool->rpc_pass = pool->rpc_url; - pool->enabled = true; + pool->enabled = POOL_ENABLED; pool->idle = false; successful_connect = true; } @@ -4966,7 +4991,7 @@ int main(int argc, char *argv[]) for (i = 0; i < total_pools; i++) { struct pool *pool = pools[i]; - pool->enabled = true; + pool->enabled = POOL_ENABLED; pool->idle = true; } diff --git a/miner.h b/miner.h index 4115cc5b..a965ecc9 100644 --- a/miner.h +++ b/miner.h @@ -604,6 +604,12 @@ struct curl_ent { struct timeval tv; }; +enum pool_enable { + POOL_ENABLED, + POOL_DISABLED, + POOL_REJECTING, +}; + struct pool { int pool_no; int prio; @@ -614,7 +620,7 @@ struct pool { bool idle; bool lagging; bool probed; - bool enabled; + enum pool_enable enabled; bool submit_old; bool removed; bool lp_started;