Commit fa881badf4005d3136102d4abb7e74a348ce0a09

Con Kolivas 2013-06-19T10:22:54

Only mandatorily grab the bflsc mutex on submitting work when the queue is empty.

diff --git a/driver-bflsc.c b/driver-bflsc.c
index 20f32f6..95ab2fa 100644
--- a/driver-bflsc.c
+++ b/driver-bflsc.c
@@ -1638,7 +1638,8 @@ static void bflsc_thread_enable(struct thr_info *thr)
 	bflsc_initialise(bflsc);
 }
 
-static bool bflsc_send_work(struct cgpu_info *bflsc, int dev, struct work *work)
+static bool bflsc_send_work(struct cgpu_info *bflsc, int dev, struct work *work,
+			    bool mandatory)
 {
 	struct bflsc_info *sc_info = (struct bflsc_info *)(bflsc->device_data);
 	struct FullNonceRangeJob data;
@@ -1663,7 +1664,15 @@ static bool bflsc_send_work(struct cgpu_info *bflsc, int dev, struct work *work)
 
 	try = 0;
 
-	mutex_lock(&(bflsc->device_mutex));
+	/* On faster devices we have a lot of lock contention so only
+	 * mandatorily grab the lock and send work if the queue is empty since
+	 * we have a submit queue. */
+	if (mandatory)
+		mutex_lock(&(bflsc->device_mutex));
+	else {
+		if (mutex_trylock(&bflsc->device_mutex))
+			return false;
+	}
 re_send:
 	err = write_to_dev(bflsc, dev, BFLSC_QJOB, BFLSC_QJOB_LEN, &amount, C_REQUESTQUEJOB);
 	if (err < 0 || amount != BFLSC_QJOB_LEN) {
@@ -1724,6 +1733,8 @@ static bool bflsc_queue_full(struct cgpu_info *bflsc)
 	// if something is wrong with a device try the next one available
 	// TODO: try them all? Add an unavailable flag to sc_devs[i] init to 0 here first
 	while (++tries < 3) {
+		bool mandatory = false;
+
 		// Device is gone - shouldn't normally get here
 		if (bflsc->usbinfo.nodev) {
 			ret = true;
@@ -1754,6 +1765,8 @@ static bool bflsc_queue_full(struct cgpu_info *bflsc)
 			}
 			if (que > sc_info->que_full_enough)
 				dev = -1;
+			else if (que == 0)
+				mandatory = true;
 		}
 		rd_unlock(&(sc_info->stat_lock));
 
@@ -1767,7 +1780,7 @@ static bool bflsc_queue_full(struct cgpu_info *bflsc)
 			work = get_queued(bflsc);
 		if (unlikely(!work))
 			break;
-		if (bflsc_send_work(bflsc, dev, work)) {
+		if (bflsc_send_work(bflsc, dev, work, mandatory)) {
 			work = NULL;
 			break;
 		} else