From: NeilBrown <neilb@suse.de>
Subject: Allow a queue to request that timeouts don't get rounded up
Patch-mainline: no
References: bnc#768084

Rounding a timeout up to the next second, plus a bit for different
CPUs, can add more than a second to a timeout.  But sometimes we
really want the timeout we request.  So allow that possibilty via a flag.

Signed-off-by: Neil Brown <neilb@suse.de>

---
 block/blk-timeout.c       |    9 +++++++--
 drivers/s390/block/dasd.c |    1 +
 include/linux/blkdev.h    |    1 +
 3 files changed, 9 insertions(+), 2 deletions(-)

--- linux-3.0-SLE11-SP2-BTMU.orig/block/blk-timeout.c
+++ linux-3.0-SLE11-SP2-BTMU/block/blk-timeout.c
@@ -129,8 +129,10 @@ void blk_rq_timed_out_timer(unsigned lon
 		}
 	}
 
+	if (!test_bit(QUEUE_FLAG_NO_ROUND, &q->queue_flags))
+		next = round_jiffies_up(next);
 	if (next_set)
-		mod_timer(&q->timeout, round_jiffies_up(next));
+		mod_timer(&q->timeout, next);
 
 	spin_unlock_irqrestore(q->queue_lock, flags);
 }
@@ -187,7 +189,10 @@ void blk_add_timer(struct request *req)
 	 * than an existing one, modify the timer. Round up to next nearest
 	 * second.
 	 */
-	expiry = round_jiffies_up(req->deadline);
+	if (test_bit(QUEUE_FLAG_NO_ROUND, &q->queue_flags))
+		expiry = req->deadline;
+	else
+		expiry = round_jiffies_up(req->deadline);
 
 	if (!timer_pending(&q->timeout) ||
 	    time_before(expiry, q->timeout.expires))
--- linux-3.0-SLE11-SP2-BTMU.orig/drivers/s390/block/dasd.c
+++ linux-3.0-SLE11-SP2-BTMU/drivers/s390/block/dasd.c
@@ -2406,6 +2406,7 @@ static void dasd_setup_queue(struct dasd
 	blk_queue_max_segment_size(block->request_queue, PAGE_SIZE);
 	blk_queue_segment_boundary(block->request_queue, PAGE_SIZE - 1);
 	blk_queue_rq_timed_out(block->request_queue, dasd_times_out);
+	set_bit(QUEUE_FLAG_NO_ROUND, &block->request_queue->queue_flags);
 	/*
 	 * blk_timeout must be enabled via sysfs; set defaults to
 	 * expires * (retries + 1)
--- linux-3.0-SLE11-SP2-BTMU.orig/include/linux/blkdev.h
+++ linux-3.0-SLE11-SP2-BTMU/include/linux/blkdev.h
@@ -407,6 +407,7 @@ struct request_queue
 #define QUEUE_FLAG_NOXMERGES   15	/* No extended merges */
 #define QUEUE_FLAG_ADD_RANDOM  16	/* Contributes to random pool */
 #define QUEUE_FLAG_SECDISCARD  17	/* supports SECDISCARD */
+#define QUEUE_FLAG_NO_ROUND    18	/* Don't round timeout up to next second */
 #define QUEUE_FLAG_DEAD        19	/* queue tear-down finished */
 
 #define QUEUE_FLAG_DEFAULT	((1 << QUEUE_FLAG_IO_STAT) |		\
