From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755496Ab0HXUGi (ORCPT ); Tue, 24 Aug 2010 16:06:38 -0400 Received: from iolanthe.rowland.org ([192.131.102.54]:56415 "HELO iolanthe.rowland.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S1752664Ab0HXUGg (ORCPT ); Tue, 24 Aug 2010 16:06:36 -0400 Date: Tue, 24 Aug 2010 16:06:35 -0400 (EDT) From: Alan Stern X-X-Sender: stern@iolanthe.rowland.org To: Jens Axboe cc: Kernel development list Subject: Re: Runtime PM and the block layer In-Reply-To: <4C73FCBE.7020305@kernel.dk> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, 24 Aug 2010, Jens Axboe wrote: > On 2010-08-24 16:42, Alan Stern wrote: > >> Sounds like all you need is a way to return BLKPREP_DEFER_AND_STOP and > >> have the block layer stop the queue for you. When you need to restart, > >> you would insert a special request at the head of the queue and call > >> blk_start_queue() to get things going again. > > > > Yes. > > > > Suppose the driver needs to send two of these special requests before > > going back to normal operation. Won't restarting the queue for the > > first special request also cause the following regular request to be > > passed to the driver before the second special request can be inserted? > > Of course, the driver could cope with this simply by returning another > > BLKPREP_DEFER_AND_STOP. > > For that special request, you are sure to have some ->end_io() hook to > know when it's complete. When that triggers, you queue the 2nd special > request. And so on, for how many you need. That's not what I meant. Suppose the driver wants to carry out special requests A and B before carrying out request R, which is initially at the head of the queue. The driver inserts A at the front, calls blk_start_queue(), and inserts B at the front when A completes. What's to prevent the block layer from sending R to the driver while A is running? > >> The only missing bit would then be the idle detection. That would need > >> to be in the block layer itself, and the scheme I described should be > >> fine for that still. > > > > Are you sure it needs to be in the block layer? Is there no way for > > the driver's completion handler to tell whether the queue is now empty? > > Certainly it already has enough information to know whether the device > > is still busy processing another request. When the device is no longer > > busy and the queue is empty, that's when the idle timer should be > > started or restarted. > > To some extent there is, but there can be context outside of the queue > it doesn't know about. That is the case for the plugging rework, for > instance. That also removes the queue_empty() call. Then there's > blk_fetch_request(), but that may return NULL while there's IO pending > in the block layer - so not reliable for that either. The block layer is > tracking this state anyway, if you are leaving it to the driver then it > would have to check everytime it completes the last request it has. It's > cheaper to do in the block layer. I see. You're suggesting we add a new "power_mode" or "queue_idle" callback to the request_queue struct, and make the block layer invoke this callback whenever a request completes and there are no other requests pending or in flight. Right? And similarly, invoke the callback (with a different argument) when the first request gets added to an otherwise empty queue. That would suit my needs. Alan Stern