From c1ff90a7ab9c19e58df1ed6bd67a87e6e6a19421 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 18 Apr 2013 15:07:32 +1000 Subject: [PATCH] Do testing for HW errors on submit nonce for both scrypt and sha. --- cgminer.c | 27 ++++++++++++++++----------- findnonce.c | 16 +--------------- scrypt.c | 8 ++++++-- scrypt.h | 6 +++--- 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/cgminer.c b/cgminer.c index cbbb510d..cf1c03ab 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5525,7 +5525,8 @@ void inc_hw_errors(struct thr_info *thr) thr->cgpu->drv->hw_error(thr); } -static bool hashtest(struct thr_info *thr, struct work *work) +/* Returns 1 if meets difficulty target, 0 if not, -1 if hw error */ +static int hashtest(struct thr_info *thr, struct work *work) { uint32_t *data32 = (uint32_t *)(work->data); unsigned char swap[80]; @@ -5533,7 +5534,6 @@ static bool hashtest(struct thr_info *thr, struct work *work) unsigned char hash1[32]; unsigned char hash2[32]; uint32_t *hash2_32 = (uint32_t *)hash2; - bool ret = false; flip80(swap32, data32); sha2(swap, 80, hash1); @@ -5544,29 +5544,29 @@ static bool hashtest(struct thr_info *thr, struct work *work) applog(LOG_WARNING, "%s%d: invalid nonce - HW error", thr->cgpu->drv->name, thr->cgpu->device_id); - inc_hw_errors(thr); - goto out; + return -1; } mutex_lock(&stats_lock); thr->cgpu->last_device_valid_work = time(NULL); mutex_unlock(&stats_lock); - ret = fulltest(hash2, work->target); - if (!ret) { + if (!fulltest(hash2, work->target)) { applog(LOG_INFO, "Share below target"); /* Check the diff of the share, even if it didn't reach the * target, just to set the best share value if it's higher. */ share_diff(work); + return 0; } -out: - return ret; + + return 1; } void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) { uint32_t *work_nonce = (uint32_t *)(work->data + 64 + 12); struct timeval tv_work_found; + int valid; gettimeofday(&tv_work_found, NULL); *work_nonce = htole32(nonce); @@ -5578,10 +5578,15 @@ void submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) mutex_unlock(&stats_lock); /* Do one last check before attempting to submit the work */ - if (!opt_scrypt && !hashtest(thr, work)) - return; + if (opt_scrypt) + valid = scrypt_test(work->data, work->target, nonce); + else + valid = hashtest(thr, work); - submit_work_async(work, &tv_work_found); + if (unlikely(valid == -1)) + inc_hw_errors(thr); + else if (valid == 1) + submit_work_async(work, &tv_work_found); } static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes) diff --git a/findnonce.c b/findnonce.c index 65055d9f..2f9d27a7 100644 --- a/findnonce.c +++ b/findnonce.c @@ -179,17 +179,6 @@ struct pc_data { int found; }; -static void send_scrypt_nonce(struct pc_data *pcd, uint32_t nonce) -{ - struct thr_info *thr = pcd->thr; - struct work *work = pcd->work; - - if (scrypt_test(work->data, work->target, nonce)) - submit_nonce(thr, work, nonce); - else - inc_hw_errors(thr); -} - static void *postcalc_hash(void *userdata) { struct pc_data *pcd = (struct pc_data *)userdata; @@ -212,10 +201,7 @@ static void *postcalc_hash(void *userdata) uint32_t nonce = pcd->res[entry]; applog(LOG_DEBUG, "OCL NONCE %u found in slot %d", nonce, entry); - if (opt_scrypt) - send_scrypt_nonce(pcd, nonce); - else - submit_nonce(thr, pcd->work, nonce); + submit_nonce(thr, pcd->work, nonce); } discard_work(pcd->work); diff --git a/scrypt.c b/scrypt.c index e0af4f0f..3d92c15b 100644 --- a/scrypt.c +++ b/scrypt.c @@ -420,7 +420,7 @@ void scrypt_regenhash(struct work *work) } /* Used externally as confirmation of correct OCL code */ -bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce) +int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce) { uint32_t tmp_hash7, Htarg = ((const uint32_t *)ptarget)[7]; uint32_t data[20], ohash[8]; @@ -432,7 +432,11 @@ bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t no scrypt_1024_1_1_256_sp(data, scratchbuf, ohash); tmp_hash7 = be32toh(ohash[7]); - return (tmp_hash7 <= Htarg); + /* FIXME: Needs to be able to return 0 as well for not meeting target + * but target diff currently is sent to devices. */ + if (tmp_hash7 > Htarg) + return -1; + return 1; } bool scanhash_scrypt(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate, diff --git a/scrypt.h b/scrypt.h index c7b85387..8f3d2190 100644 --- a/scrypt.h +++ b/scrypt.h @@ -4,16 +4,16 @@ #include "miner.h" #ifdef USE_SCRYPT -extern bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, +extern int scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce); extern void scrypt_regenhash(struct work *work); #else /* USE_SCRYPT */ -static inline bool scrypt_test(__maybe_unused unsigned char *pdata, +static inline int scrypt_test(__maybe_unused unsigned char *pdata, __maybe_unused const unsigned char *ptarget, __maybe_unused uint32_t nonce) { - return false; + return 0; } static inline void scrypt_regenhash(__maybe_unused struct work *work)