[PATCH] reworked IDE/general tagged command queueing

From: Jens Axboe (axboe@suse.de)
Date: Wed May 01 2002 - 07:37:05 EST


I've rewritten parts of the IDE TCQ stuff to be, well, a lot better in
my oppinion. I had to accept that the ata_request and rq->special usage
sucked, it was just one big mess.

So following a suggestion from Martin and Linus, I implemented some
basic tagged command queueing back end in the block layer. This is what
the new IDE TCQ core is build on, and what potentially others can use as
well. I'll start by describing the new API:

int blk_queue_init_tags(request_queue_t *q, int depth)

        Setup queueing structures for the request queue and depth given.
        This will setup q->queue_tags, which is a struct blk_queue_tag:

        struct blk_queue_tag {
                struct request **tag_index; /* map of busy tags */
                unsigned long *tag_map; /* bit map of free/busy tags */
                struct list_head busy_list; /* fifo list of busy tags */
                int busy; /* current depth */
                int max_depth;

        tag_index[] holds pointers to the active requests, and tag_map
         is a bitmap of busy tags. The rest should not need any

void blk_queue_free_tags(request_queue_t *q)

        Tear down the tag info setup by blk_queue_init_tags(). This will
        be done automatically when blk_cleanup_queue() is called, so
        there's usually no need to call this directly (unless you just
        want to disable tagging and let the queue live on).

int blk_queue_start_tag(request_queue_t *q, struct request *rq)

        Start a new tag associated with struct request. This will grab
        an available tag number and add it to the internal structures.

void blk_queue_end_tag(request_queue_t *q, struct request *rq)

        End this tag. Typically called when end_that_request_first()
        says the request is done, before calling

void blk_queue_invalidate_tags(request_queue_t *q)

        Called by driver to clear our internal tag queue and readd the
        requests to the request queue. Submission order is preserved,
        so should be safe for barriers too.

That's it. For an example of usage, see the IDE TCQ patch attached as
well. The API can of course be extended if the need arises, I've kept it
simple on purpose since it was all I needed for the IDE parts -- and
it's silly to add features just because you _think_ someone might need

Now on to the IDE parts. The TCQ patch is now a LOT less invasive than
before. With the block tagged features in place, there's no need for a
private request type in the IDE layer -- struct request is just fine.
Changes to IDE core (ide.c) are now extremely small. Changes to ide-disk
are minute as well, most of it is actually just the proc file stuff.
ide-dma changes are mainly needed because otherwise ide-tcq would have
to duplicate the ide_start_dma() functionality on its own. ide-taskfile
changes are just to detect the new commands possibly (read queued etc)
and a spelling fix :-). There is one ugly hack in ide-taskfile, that
will disappear once the dmaproc parts are split in two as outlined in
the FIXME there.

So give it a whirl, patches is against 2.5.12. block-tag-4 can be
applied independently, ide-tag-2 relies on it of course.

Note that hdparm-4.7 and later has support for enabling and disabling
tcq/queue depth, it's done with the -Q parameter:

bart:~ # hdparm -Q0 /dev/hdc

 setting using_dma_q to 0 (off)
 using_dma_q = 0 (off)

bart:~ # hdparm -Q32 /dev/hdc

 setting using_dma_q to 32 (on)
 using_dma_q = 1 (on)

and so forth :-)

Find it here:


Jens Axboe

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

This archive was generated by hypermail 2b29 : Tue May 07 2002 - 22:00:10 EST