Главная » Просмотр файлов » Linux Device Drivers 2nd Edition

Linux Device Drivers 2nd Edition (779877), страница 81

Файл №779877 Linux Device Drivers 2nd Edition (Linux Device Drivers 2nd Edition) 81 страницаLinux Device Drivers 2nd Edition (779877) страница 812018-01-10СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 81)

This step modifies the request queue, and thus mustbe performed with the io_request_lock held.5.Release the finished request back to the system; io_request_lock isrequired here too.The kernel defines a couple of helper functions that are used by end_r equest todo most of this work. The first one is called end_that_r equest_first, which handlesthe first two steps just described.

Its prototype isint end_that_request_first(struct request *req, int status, char *name);status is the status of the request as passed to end_r equest; the name parameteris the device name, to be used when printing error messages. The return value isnonzero if there are more buffers to be processed in the current request; in thatcase the work is done.

Otherwise, the request is dequeued and released withend_that_r equest_last:void end_that_request_last(struct request *req);In end_r equest this step is handled with this code:struct request *req = CURRENT;blkdev_dequeue_request(req);end_that_request_last(req);That is all there is to it.Clustered RequestsThe time has come to look at how to apply all of that background material to thetask of writing better block drivers. We’ll start with a look at the handling of clustered requests.

Clustering, as mentioned earlier, is simply the practice of joiningtogether requests that operate on adjacent blocks on the disk. There are twoadvantages to doing things this way. First, clustering speeds up the transfer; clustering can also save some memory in the kernel by avoiding allocation of redundant request structures.34022 June 2001 16:41http://openlib.org.uaHandling Requests: The Detailed ViewAs we have seen, block drivers need not be aware of clustering at all;<linux/blk.h> transparently splits each clustered request into its componentpieces.

In many cases, however, a driver can do better by explicitly acting on clustering. It is often possible to set up the I/O for several consecutive blocks at thesame time, with an improvement in throughput. For example, the Linux floppydriver attempts to write an entire track to the diskette in a single operation.

Mosthigh-performance disk controllers can do “scatter/gather” I/O as well, leading tolarge performance gains.To take advantage of clustering, a block driver must look directly at the list ofbuffer_head structures attached to the request. This list is pointed to by CURRENT->bh; subsequent buffers can be found by following the b_reqnext pointers in each buffer_head structure. A driver performing clustered I/O shouldfollow roughly this sequence of operations with each buffer in the cluster:1.Arrange to transfer the data block at address bh->b_data, of sizebh->b_size bytes.

The direction of the data transfer is CURRENT->cmd (i.e.,either READ or WRITE).2.Retrieve the next buffer head in the list: bh->b_reqnext. Then detach thebuffer just transferred from the list, by zeroing its b_reqnext—the pointer tothe new buffer you just retrieved.3.Update the request structure to reflect the I/O done with the buffer that hasjust been removed. Both CURRENT->hard_nr_sectors and CURRENT->nr_sectors should be decremented by the number of sectors (notblocks) transferred from the buffer.

The sector numbers CURRENT->hard_sector and CURRENT->sector should be incremented bythe same amount. Performing these operations keeps the request structureconsistent.4.Loop back to the beginning to transfer the next adjacent block.When the I/O on each buffer completes, your driver should notify the kernel bycalling the buffer’s I/O completion routine:bh->b_end_io(bh, status);status is nonzero if the operation was successful. You also, of course, need toremove the request structure for the completed operations from the queue. Theprocessing steps just described can be done without holding theio_request_lock, but that lock must be reacquired before changing the queueitself.Your driver can still use end_r equest (as opposed to manipulating the queuedirectly) at the completion of the I/O operation, as long as it takes care to set theCURRENT->bh pointer properly.

This pointer should either be NULL or it should34122 June 2001 16:41http://openlib.org.uaChapter 12: Loading Block Driverspoint to the last buffer_head structure that was transferred. In the latter case,the b_end_io function should not have been called on that last buffer, sinceend_r equest will make that call.A full-featured implementation of clustering appears in drivers/block/floppy.c, whilea summary of the operations required appears in end_r equest, in blk.h. Neitherfloppy.c nor blk.h are easy to understand, but the latter is a better place to start.The active queue headOne other detail regarding the behavior of the I/O request queue is relevant forblock drivers that are dealing with clustering.

It has to do with the queue head—the first request on the queue. For historical compatibility reasons, the kernel(almost) always assumes that a block driver is processing the first entry in therequest queue. To avoid corruption resulting from conflicting activity, the kernelwill never modify a request once it gets to the head of the queue. No further clustering will happen on that request, and the elevator code will not put otherrequests in front of it.Many block drivers remove requests from the queue entirely before beginning toprocess them.

If your driver works this way, the request at the head of the queueshould be fair game for the kernel. In this case, your driver should inform the kernel that the head of the queue is not active by calling blk_queue_headactive:blk_queue_headactive(request_queue_t *queue, int active);If active is 0, the kernel will be able to make changes to the head of the requestqueue.Multiqueue Block DriversAs we have seen, the kernel, by default, maintains a single I/O request queue foreach major number.

The single queue works well for devices like sbull, but it isnot always optimal for real-world situations.Consider a driver that is handling real disk devices. Each disk is capable of operating independently; the performance of the system is sure to be better if the drivescould be kept busy in parallel. A simple driver based on a single queue will notachieve that—it will perform operations on a single device at a time.It would not be all that hard for a driver to walk through the request queue andpick out requests for independent drives. But the 2.4 kernel makes life easier byallowing the driver to set up independent queues for each device.

Most high-performance drivers take advantage of this multiqueue capability. Doing so is not difficult, but it does require moving beyond the simple <linux/blk.h> definitions.34222 June 2001 16:41http://openlib.org.uaHandling Requests: The Detailed ViewThe sbull driver, when compiled with the SBULL_MULTIQUEUE symbol defined,operates in a multiqueue mode. It works without the <linux/blk.h> macros,and demonstrates a number of the features that have been described in this section.To operate in a multiqueue mode, a block driver must define its own requestqueues.

sbull does this by adding a queue member to the Sbull_Dev structure:request_queue_t queue;int busy;The busy flag is used to protect against request function reentrancy, as we willsee.Request queues must be initialized, of course. sbull initializes its device-specificqueues in this manner:for (i = 0; i < sbull_devs; i++) {blk_init_queue(&sbull_devices[i].queue, sbull_request);blk_queue_headactive(&sbull_devices[i].queue, 0);}blk_dev[major].queue = sbull_find_queue;The call to blk_init_queue is as we have seen before, only now we pass in thedevice-specific queues instead of the default queue for our major device number.This code also marks the queues as not having active heads.You might be wondering how the kernel manages to find the request queues,which are buried in a device-specific, private structure.

The key is the last line justshown, which sets the queue member in the global blk_dev structure. Thismember points to a function that has the job of finding the proper request queuefor a given device number. Devices using the default queue have no such function, but multiqueue devices must implement it. sbull’s queue function looks likethis:request_queue_t *sbull_find_queue(kdev_t device){int devno = DEVICE_NR(device);if (devno >= sbull_devs) {static int count = 0;if (count++ < 5) /* print the message at most five times */printk(KERN_WARNING "sbull: request for unknown device\n");return NULL;}return &sbull_devices[devno].queue;}Like the request function, sbull_find_queue must be atomic (no sleeping allowed).34322 June 2001 16:41http://openlib.org.uaChapter 12: Loading Block DriversEach queue has its own request function, though usually a driver will use the samefunction for all of its queues. The kernel passes the actual request queue into therequest function as a parameter, so the function can always figure out whichdevice is being operated on.

The multiqueue request function used in sbull looks alittle different from the ones we have seen so far because it manipulates therequest queue directly. It also drops the io_request_lock while performingtransfers to allow the kernel to execute other block operations. Finally, the codemust take care to avoid two separate perils: multiple calls of the request functionand conflicting access to the device itself.void sbull_request(request_queue_t *q){Sbull_Dev *device;struct request *req;int status;/* Find our device */device = sbull_locate_device (blkdev_entry_next_request(&q->queue_head));if (device->busy) /* no race here - io_request_lock held */return;device->busy = 1;/* Process requests in the queue */while(! list_empty(&q->queue_head)) {/* Pull the next request off the list. */req = blkdev_entry_next_request(&q->queue_head);blkdev_dequeue_request(req);spin_unlock_irq (&io_request_lock);spin_lock(&device->lock);/* Process all of the buffers in this (possibly clustered) request.

*/do {status = sbull_transfer(device, req);} while (end_that_request_first(req, status, DEVICE_NAME));spin_unlock(&device->lock);spin_lock_irq (&io_request_lock);end_that_request_last(req);}device->busy = 0;}Instead of using INIT_REQUEST, this function tests its specific request queuewith the list function list_empty. As long as requests exist, it removes each one inturn from the queue with blkdev_dequeue_r equest. Only then, once the removal iscomplete, is it able to drop io_request_lock and obtain the device-specificlock.

The actual transfer is done using sbull_transfer, which we have already seen.34422 June 2001 16:41http://openlib.org.uaHandling Requests: The Detailed ViewEach call to sbull_transfer handles exactly one buffer_head structure attachedto the request. The function then calls end_that_r equest_first to dispose of thatbuffer, and, if the request is complete, goes on to end_that_r equest_last to cleanup the request as a whole.The management of concurrency here is worth a quick look. The busy flag isused to prevent multiple invocations of sbull_r equest. Since sbull_r equest is alwayscalled with the io_request_lock held, it is safe to test and set the busy flagwith no additional protection.

(Otherwise, an atomic_t could have been used).The io_request_lock is dropped before the device-specific lock is acquired. Itis possible to acquire multiple locks without risking deadlock, but it is harder;when the constraints allow, it is better to release one lock before obtaininganother.end_that_r equest_first is called without the io_request_lock held.

Характеристики

Тип файла
PDF-файл
Размер
7,36 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6451
Авторов
на СтудИзбе
305
Средний доход
с одного платного файла
Обучение Подробнее