Setting and Clearing the Congested State

The kernel provides two standard functions (declared in <blkdev.h>) to set queues to the congested state and to clear this state: blk_set_queue_congested and blk_clear_queue_congested, respectively. Both obtain the backing_dev_info for the queue under consideration and hand over the real work to set_bdi_congested or clear_bdi_congested, respectively, in mm/backing-dev.c.

Two data structures are manipulated to change the state. First, the request queue of the block device must be modified (you are familiar with the associated request_queue data structure from Chapter 6), and second, note must be taken of the global congestion array (congestion_wqh).

blk_set_queue_congested is used to mark a queue as congested. Remarkably, it is invoked at only a single point in the kernel — by get_request.5 As discussed in Chapter 6, the purpose of get_request is to allocate a request instance for a queue or to fetch one from the appropriate cache. This is the ideal place to check for congestion. If the number of request instances falls below the threshold, set_queue_congested informs the remaining code that congestion has occurred.

5This is not entirely precise: It is also called from queue_request_store. But since this code path is only activated if the system administrator changes the nr_requests field of a request queue via sysfs, I do not bother to discuss this possibility any further.

" congestion_on-

congestion_off

nr_requests

*****

- x ./

,

The implementation of set_bdi_congested is very simple. Only a single bit need be set in the request queue — albeit a different bit depending on the direction of congestion:

Continue reading here: Blockbackingdevc

Was this article helpful?

0 0