Browse Source

Bugfix: Sanitise lock situation for work2d

Luke Dashjr 10 years ago
parent
commit
2846102b17
6 changed files with 47 additions and 27 deletions
  1. 0 1
      driver-avalonmm.c
  2. 2 5
      driver-stratum.c
  3. 28 18
      miner.c
  4. 1 0
      miner.h
  5. 15 3
      work2d.c
  6. 1 0
      work2d.h

+ 0 - 1
driver-avalonmm.c

@@ -509,7 +509,6 @@ bool avalonmm_update_swork_from_pool(struct cgpu_info * const master_dev, struct
 	stratum_work_cpy(&mmjob->swork, &pool->swork);
 	cg_runlock(&pool->data_lock);
 	timer_set_now(&mmjob->tv_prepared);
-	mmjob->swork.data_lock_p = NULL;
 	if (!avalonmm_send_swork(fd, chain, &mmjob->swork, mmjob->jobid, &mmjob->nonce_diff))
 	{
 		avalonmm_free_job(mmjob);

+ 2 - 5
driver-stratum.c

@@ -91,8 +91,6 @@ void stratumsrv_send_set_difficulty(struct stratumsrv_conn * const conn, const f
 	bufferevent_write(bev, buf, bufsz);
 }
 
-#define _ssm_gen_dummy_work work2d_gen_dummy_work
-
 static void stratumsrv_boot_all_subscribed(const char *);
 static void _ssj_free(struct stratumsrv_job *);
 static void stratumsrv_job_pruner();
@@ -119,7 +117,7 @@ fail:
 	
 	{
 		struct work work;
-		work2d_gen_dummy_work(&work, &pool->swork, &tv_now, NULL, 0);
+		work2d_gen_dummy_work_for_stale_check(&work, &pool->swork, &tv_now, NULL);
 		
 		const bool is_stale = stale_work(&work, false);
 		
@@ -216,12 +214,11 @@ fail:
 	else
 		stratumsrv_job_pruner();
 	
-	ssj->swork.data_lock_p = NULL;
 	HASH_ADD_KEYPTR(hh, _ssm_jobs, ssj->my_job_id, strlen(ssj->my_job_id), ssj);
 	
 	if (likely(_ssm_cur_job_work.pool))
 		clean_work(&_ssm_cur_job_work);
-	_ssm_gen_dummy_work(&_ssm_cur_job_work, &ssj->swork, &ssj->tv_prepared, NULL, 0);
+	work2d_gen_dummy_work_for_stale_check(&_ssm_cur_job_work, &ssj->swork, &ssj->tv_prepared, NULL);
 	
 	_ssm_notify_sz = p - buf;
 	assert(_ssm_notify_sz <= bufsz);

+ 28 - 18
miner.c

@@ -1066,6 +1066,7 @@ struct pool *add_pool(void)
 	if (unlikely(pthread_cond_init(&pool->cr_cond, bfg_condattr)))
 		quit(1, "Failed to pthread_cond_init in add_pool");
 	cglock_init(&pool->data_lock);
+	pool->swork.data_lock_p = &pool->data_lock;
 	mutex_init(&pool->stratum_lock);
 	timer_unset(&pool->swork.tv_transparency);
 	pool->swork.pool = pool;
@@ -9591,6 +9592,7 @@ void stratum_work_cpy(struct stratum_work * const dst, const struct stratum_work
 	dst->job_id = maybe_strdup(src->job_id);
 	bytes_cpy(&dst->coinbase, &src->coinbase);
 	bytes_cpy(&dst->merkle_bin, &src->merkle_bin);
+	dst->data_lock_p = NULL;
 }
 
 void stratum_work_clean(struct stratum_work * const swork)
@@ -9625,7 +9627,6 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
 	clean_work(work);
 	
 	cg_wlock(&pool->data_lock);
-	pool->swork.data_lock_p = &pool->data_lock;
 	
 	const int n2size = pool->swork.n2size;
 	bytes_resize(&work->nonce2, n2size);
@@ -9650,11 +9651,8 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
 
 void gen_stratum_work2(struct work *work, struct stratum_work *swork)
 {
-	unsigned char *coinbase, merkle_root[32], merkle_sha[64];
-	uint8_t *merkle_bin;
-	uint32_t *data32, *swap32;
-	int i;
-
+	unsigned char *coinbase;
+	
 	/* Generate coinbase */
 	coinbase = bytes_buf(&swork->coinbase);
 	memcpy(&coinbase[swork->nonce2_offset], bytes_buf(&work->nonce2), bytes_len(&work->nonce2));
@@ -9662,7 +9660,29 @@ void gen_stratum_work2(struct work *work, struct stratum_work *swork)
 	/* Downgrade to a read lock to read off the variables */
 	if (swork->data_lock_p)
 		cg_dwlock(swork->data_lock_p);
+	
+	gen_stratum_work3(work, swork, swork->data_lock_p);
+	
+	if (opt_debug)
+	{
+		char header[161];
+		char nonce2hex[(bytes_len(&work->nonce2) * 2) + 1];
+		bin2hex(header, work->data, 80);
+		bin2hex(nonce2hex, bytes_buf(&work->nonce2), bytes_len(&work->nonce2));
+		applog(LOG_DEBUG, "Generated stratum header %s", header);
+		applog(LOG_DEBUG, "Work job_id %s nonce2 %s", work->job_id, nonce2hex);
+	}
+}
 
+void gen_stratum_work3(struct work * const work, struct stratum_work * const swork, cglock_t * const data_lock_p)
+{
+	unsigned char *coinbase, merkle_root[32], merkle_sha[64];
+	uint8_t *merkle_bin;
+	uint32_t *data32, *swap32;
+	int i;
+	
+	coinbase = bytes_buf(&swork->coinbase);
+	
 	/* Generate merkle root */
 	gen_hash(coinbase, merkle_root, bytes_len(&swork->coinbase));
 	memcpy(merkle_sha, merkle_root, 32);
@@ -9689,18 +9709,8 @@ void gen_stratum_work2(struct work *work, struct stratum_work *swork)
 	memcpy(work->target, swork->target, sizeof(work->target));
 	work->job_id = maybe_strdup(swork->job_id);
 	work->nonce1 = maybe_strdup(swork->nonce1);
-	if (swork->data_lock_p)
-		cg_runlock(swork->data_lock_p);
-
-	if (opt_debug)
-	{
-		char header[161];
-		char nonce2hex[(bytes_len(&work->nonce2) * 2) + 1];
-		bin2hex(header, work->data, 80);
-		bin2hex(nonce2hex, bytes_buf(&work->nonce2), bytes_len(&work->nonce2));
-		applog(LOG_DEBUG, "Generated stratum header %s", header);
-		applog(LOG_DEBUG, "Work job_id %s nonce2 %s", work->job_id, nonce2hex);
-	}
+	if (data_lock_p)
+		cg_runlock(data_lock_p);
 
 	calc_midstate(work);
 

+ 1 - 0
miner.h

@@ -1470,6 +1470,7 @@ extern void stratum_work_cpy(struct stratum_work *dst, const struct stratum_work
 extern void stratum_work_clean(struct stratum_work *);
 extern bool pool_has_usable_swork(const struct pool *);
 extern void gen_stratum_work2(struct work *, struct stratum_work *);
+extern void gen_stratum_work3(struct work *, struct stratum_work *, cglock_t *data_lock_p);
 extern void inc_hw_errors3(struct thr_info *thr, const struct work *work, const uint32_t *bad_nonce_p, float nonce_diff);
 static inline
 void inc_hw_errors2(struct thr_info * const thr, const struct work * const work, const uint32_t *bad_nonce_p)

+ 15 - 3
work2d.c

@@ -71,15 +71,21 @@ void *work2d_pad_xnonce(void * const buf_, const struct stratum_work * const swo
 	return &buf[pad];
 }
 
-void work2d_gen_dummy_work(struct work * const work, struct stratum_work * const swork, const struct timeval * const tvp_prepared, const void * const xnonce2, const uint32_t xnonce1)
+static void work2d_gen_dummy_work_prepare(struct work * const work, struct stratum_work * const swork, const struct timeval * const tvp_prepared)
 {
-	uint8_t *p, *s;
-	
 	*work = (struct work){
 		.pool = swork->pool,
 		.work_restart_id = swork->work_restart_id,
 		.tv_staged = *tvp_prepared,
 	};
+}
+
+void work2d_gen_dummy_work(struct work * const work, struct stratum_work * const swork, const struct timeval * const tvp_prepared, const void * const xnonce2, const uint32_t xnonce1)
+{
+	uint8_t *p, *s;
+	
+	work2d_gen_dummy_work_prepare(work, swork, tvp_prepared);
+	
 	bytes_resize(&work->nonce2, swork->n2size);
 	s = bytes_buf(&work->nonce2);
 	p = &s[swork->n2size - work2d_xnonce2sz];
@@ -95,6 +101,12 @@ void work2d_gen_dummy_work(struct work * const work, struct stratum_work * const
 	gen_stratum_work2(work, swork);
 }
 
+void work2d_gen_dummy_work_for_stale_check(struct work * const work, struct stratum_work * const swork, const struct timeval * const tvp_prepared, cglock_t * const data_lock_p)
+{
+	work2d_gen_dummy_work_prepare(work, swork, tvp_prepared);
+	gen_stratum_work3(work, swork, data_lock_p);
+}
+
 bool work2d_submit_nonce(struct thr_info * const thr, struct stratum_work * const swork, const struct timeval * const tvp_prepared, const void * const xnonce2, const uint32_t xnonce1, const uint32_t nonce, const uint32_t ntime, bool * const out_is_stale, const float nonce_diff)
 {
 	struct work _work, *work;

+ 1 - 0
work2d.h

@@ -16,6 +16,7 @@ extern void release_work2d_(uint32_t xnonce1);
 extern int work2d_pad_xnonce_size(const struct stratum_work *);
 extern void *work2d_pad_xnonce(void *buf, const struct stratum_work *, bool hex);
 extern void work2d_gen_dummy_work(struct work *, struct stratum_work *, const struct timeval *tvp_prepared, const void *xnonce2, uint32_t xnonce1);
+extern void work2d_gen_dummy_work_for_stale_check(struct work *, struct stratum_work *, const struct timeval *tvp_prepared, cglock_t *data_lock_p);
 extern bool work2d_submit_nonce(struct thr_info *, struct stratum_work *, const struct timeval *tvp_prepared, const void *xnonce2, uint32_t xnonce1, uint32_t nonce, uint32_t ntime, bool *out_is_stale, float nonce_diff);
 
 #endif