Строка 479
Функция page_writeback_init () инициализирует значение, контролируемое, когда грязные страницы записываются обратно на диск. Грязные страницы записываются на диск не сразу; они записываются по прошествии некоторого времени или после того, как некоторая часть в процентах памяти будет помечена как грязная. Эта функция init пытается определить оптимальное количество страниц, которые должны быть помечены как грязные, перед запуском фоновой и специальной записей. Фоновая запись грязных страниц занимает намного меньше процессорного времени, чем специальная запись грязных страниц:
488 489 490 491 492
mm/page-writeback.с
Если в машине много верхней памяти, рейтинг нижней памяти снижается до значения порога грязной памяти по умолчанию, предлагая больше места грязной верхней памяти, чем количество buffer_heads. */
493 void init page_writeback_init(void)
494 {
495 long buffer_pages = nr_free_buffer_pages();
496 long correction; 497
498 total_pages = nr_free_pagecache_pages();
499
500 correction = (100 * 4 * buffer_pages) / total_pages;
501
502 if (correction < 100) {
503 dirty_background_ratio *= correction;
504 dirty_background_ratio /= 100;
505 vm_dirty_ratio *= correction;
50 6 vm_dirty_ratio /= 100;
507 }
508 mod_timer(&wb_timer, jiffies +
(dirty_writeback_centisecs * HZ) / 100);
509 set_ratelimit();
510 register_cpu_notifier(&ratelimit_nb);
511 }
Строки 495-507
Если мы работаем на машине с большим кешем страниц по сравнению с количеством буферов страниц, мы уменьшаем порог записи грязных страниц. Если мы выбираем не снижать порог, который увеличивает частоту записи при каждой записи, мы будем использовать чрезмерное количество buf fer_heads. [Это означает и комментарий перед page_writevack ().]
Фоновая запись по умолчанию dirty_background_ratio начинается, когда грязными становятся 10 % страниц. Специальная запись, vm_dirty_ratio начинается при 40 % грязных страниц.
Строка 508
Мы модифицируем время записи, wb_timer, для периодического запуска (каждые 5 с по умолчанию).
Строка 509
Вызывается отлично документированная set_ratelimit (). Предоставим слово встроенным комментариям.
450 /*
451 * Если ratelimit_pages слишком высок, то у нас может случиться
452 * переизбыток грязных данных, если несколько процессов выполняет
453 * запись в одно и то же время. Если он слишком мал, машина SMP
454 * часто вызывает (дорогостоящую) get_writeback_state.
455 *
456 * Здесь мы устанавливаем ratelimit_pages до уровня, на котором все
457 * процессоры имеют одинаковый уровень грязной памяти, и мы не можем
458 * превысить 3% (1/32) от порога грязных страниц до прекращения
459 * записи.
460 * Этот предел нельзя задавать слишком большим. Из за-того, что он
461 * также контролирует размер памяти с помощью вызова
462 * balance_dirty_pages() для записи. Если оно слишком велико,
463 * вызывающей код каждый раз должен блокировать очередь ввода-вывода.
464 * Предел равен 4 Мб, а вызывающий balance_dirty_pages()
465 * код записывает до максимальных 6 Мб. */ 466
467 static void set_ratelimit(void)
468 {
469 ratelimit_pages = total_pages / (num_online_cpus() * 32);
470 if (ratelimit_pages < 16)
471 ratelimit_pages =16;
472 if (ratelimit_pages * PAGE_CACHE_SIZE > 4096 * 1024)
473 ratelimit_pages = (4096 * 1024) / PAGE_CACHE_SIZE;
474 }
Строка 510
Последняя команда, page_writeback_init (), регистрирует блок уведомителя рейтинга, ratelimit_nb, с уведомлением процессора. Блок уведомителя рейтинга вызывает ratelimit_handler () при уведомлении и, в свою очередь, вызывает set_ratelimit (). Это сделано для пересчета retelimit_pages, когда изменяется количество включенных процессоров.
mm/page-writeback.с
483 static struct notifier_block ratelimit_nb = {
484 .notifier_call = ratelimit_handler,
485 .next = NULL,
486 };
416 if (pdflush_operation(wb_kupdate, 0) < 0)
417 mod_timer(&wb_timer, jiffies + HZ); /* delay 1 second */
418 }
Строки 416-417
По истечении таймера ядро активизирует pdf lush_operation (), которая будит один из потоков pdf lush для выполнения настоящей записи грязных страниц на диск. Если pdf lush_operation () не может разбудить ни один из потоков pdf lush, она сообщает таймеру записи сработать снова через 1 с для повторной попытки пробуждения потока pdflush. (См. более подробную информацию о pdflush в гл. 9, «Сборка ядра Linux».)