Обработчик прерываний
Обработчик прерываний драйвера блочного устройства активизируется по окончании пересылки данных с использованием механизма DMA. Он должен проверить, все ли данные в запросе были пересланы. Если это так, обработчик прерываний вызывает процедуру-стратега для обслуживания следующего запроса из диспетчерной очереди. В противном случае обработчик прерываний обновляет соответствующее поле дескриптора запроса и вызывает процедуру-стратега для обслуживания следующей порции данных.
Приведем типичный фрагмент обработчика прерываний нашего драйвера устройства foo:
irqreturn_t foo_interrupt(int irq, void dev_id, struct pt_regs regs)
{
struct foo_dev_t p = (struct foo_dev_t ) dev_id; struct request_queue rq = p->gd->rq;
[.]
if (!end_that_request_first(rq, uptodate, nr_sectors)) { blkdev_dequeue_request(rq); end_that_request_last(rq);
}
rq->request_fn(rq);
[.]
return IRQ_HANDLED;
}
Задача по завершению запроса разбивается на две функции, названные
end_that_request_first И end_that_request_last .
Функция end that request first принимает в качестве аргумента дескриптор запроса, флаг, показывающий успешное завершение DMA-пересылки, и количество пересланных секторов (функция end that request chunk работает аналогично, но вместо количества секторов принимает количество переданных байтов). Функция сканирует дескрипторы bio в запросе и сегменты внутри каждого bio, а затем обновляет поля дескриптора запроса следующим образом:
- устанавливает поле bio так, чтобы оно указывало на первый незавершенный bio в запросе;
- устанавливает поле bi idx незавершенного bio так, чтобы оно указывало на первый незавершенный сегмент;
- устанавливает поле bv offset и bv ien незавершенного сегмента так, чтобы они определяли данные, подлежащие пересылке.
Кроме того, функция вызывает bio endio для каждого полностью переданного bio.
Функция end that request first о возвращает 0, если все данные запроса пересланы, в противном случае она возвращает 1. Если возвращена единица, обработчик прерываний снова запускает процедуру-стратега, которая продолжает обработку того же запроса. В противном случае обработчик прерываний удаляет запрос из очереди запросов (как правило, с помощью функции blkdev dequeue request ()), вызывает вспомогательную функцию end_that_ request iast о и снова запускает процедуру-стратега для обработки следующего запроса из диспетчерной очереди.
Функция end that request iast о обновляет статистику обращений к диску, удаляет дескриптор запроса из диспетчерной очереди планировщика rq->elevator, возобновляет ВЫПОЛНеНИе процессов, спящих” В поле waiting дескриптора запроса, и освобождает этот дескриптор.
Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница