[RFC] add sysfs to dynamically control blk request tag maintenance

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



blk_queue_start_tag and blk_queue_end_tag are called for tagging
I/O to scsi device that is capable of tcq. blk_queue_find_tag is
a function that utilizes the tag information built up on every I/O.

However, there aren't many consumers for blk_queue_find_tag, except
NCR53c700 and tekram-dc390.  Vast majority of scsi drivers don't
use these tag currently.  So why bother build them at the beginning
of an I/O and then tear it all down at the end, all doing hard work
but no other functions in the kernel appears to care.

Is there another big scheme in the works to use these tags?  If not,
I'd like to propose we add a sysfs attribute to dynamically control
whether kernel maintains blk request tag or not.  This has performance
advantage that we don't needlessly waste CPU cycle on things we throw
away without using them. Would the following patch be acceptable?
Comments?


Signed-off-by: Ken Chen <[email protected]>

--- linux-2.6.14-rc3/drivers/block/ll_rw_blk.c.orig	2005-10-06 19:11:28.452697852 -0700
+++ linux-2.6.14-rc3/drivers/block/ll_rw_blk.c	2005-10-06 19:11:43.198791421 -0700
@@ -757,7 +757,7 @@ static void __blk_queue_free_tags(reques
 	}
 
 	q->queue_tags = NULL;
-	q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED);
+	q->queue_flags &= ~(1 << QUEUE_FLAG_QUEUED | 1 << QUEUE_FLAG_TAGGED);
 }
 
 /**
@@ -771,6 +771,7 @@ static void __blk_queue_free_tags(reques
 void blk_queue_free_tags(request_queue_t *q)
 {
 	clear_bit(QUEUE_FLAG_QUEUED, &q->queue_flags);
+	clear_bit(QUEUE_FLAG_TAGGED, &q->queue_flags);
 }
 
 EXPORT_SYMBOL(blk_queue_free_tags);
@@ -838,6 +839,7 @@ int blk_queue_init_tags(request_queue_t 
 		if ((rc = blk_queue_resize_tags(q, depth)))
 			return rc;
 		set_bit(QUEUE_FLAG_QUEUED, &q->queue_flags);
+		set_bit(QUEUE_FLAG_TAGGED, &q->queue_flags);
 		return 0;
 	} else
 		atomic_inc(&tags->refcnt);
@@ -846,7 +848,7 @@ int blk_queue_init_tags(request_queue_t 
 	 * assign it, all done
 	 */
 	q->queue_tags = tags;
-	q->queue_flags |= (1 << QUEUE_FLAG_QUEUED);
+	q->queue_flags |= (1 << QUEUE_FLAG_QUEUED | 1 << QUEUE_FLAG_TAGGED);
 	return 0;
 fail:
 	kfree(tags);
@@ -3589,6 +3591,26 @@ static ssize_t queue_max_hw_sectors_show
 	return queue_var_show(max_hw_sectors_kb, (page));
 }
 
+static ssize_t
+queue_tag_maint_store(struct request_queue *q, const char *page, size_t count)
+{
+	unsigned long tag_maint;
+	ssize_t ret = queue_var_store(&tag_maint, page, count);
+
+	if (blk_queue_queued(q)) {
+		if (tag_maint)
+			set_bit(QUEUE_FLAG_TAGGED, &q->queue_flags);
+		else
+			clear_bit(QUEUE_FLAG_TAGGED, &q->queue_flags);
+	}
+
+	return ret;
+}
+
+static ssize_t queue_tag_maint_show(struct request_queue *q, char *page)
+{
+	return queue_var_show(blk_queue_tagged(q), (page));
+}
 
 static struct queue_sysfs_entry queue_requests_entry = {
 	.attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
@@ -3619,12 +3641,19 @@ static struct queue_sysfs_entry queue_io
 	.store = elv_iosched_store,
 };
 
+static struct queue_sysfs_entry queue_tag_maint_entry = {
+	.attr = {.name = "tag_maint", .mode = S_IRUGO | S_IWUSR },
+	.show = queue_tag_maint_show,
+	.store = queue_tag_maint_store,
+};
+
 static struct attribute *default_attrs[] = {
 	&queue_requests_entry.attr,
 	&queue_ra_entry.attr,
 	&queue_max_hw_sectors_entry.attr,
 	&queue_max_sectors_entry.attr,
 	&queue_iosched_entry.attr,
+	&queue_tag_maint_entry.attr,
 	NULL,
 };
 
--- linux-2.6.14-rc3/include/linux/blkdev.h.orig	2005-10-06 19:14:45.193906379 -0700
+++ linux-2.6.14-rc3/include/linux/blkdev.h	2005-10-06 19:18:17.228083470 -0700
@@ -436,9 +436,11 @@ enum {
 #define QUEUE_FLAG_PLUGGED	7	/* queue is plugged */
 #define QUEUE_FLAG_DRAIN	8	/* draining queue for sched switch */
 #define QUEUE_FLAG_FLUSH	9	/* doing barrier flush sequence */
+#define QUEUE_FLAG_TAGGED	10	/* maintain per request tag */
 
 #define blk_queue_plugged(q)	test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
-#define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
+#define blk_queue_queued(q)	test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
+#define blk_queue_tagged(q)	test_bit(QUEUE_FLAG_TAGGED, &(q)->queue_flags)
 #define blk_queue_stopped(q)	test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
 #define blk_queue_flushing(q)	test_bit(QUEUE_FLAG_FLUSH, &(q)->queue_flags)
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux