LINUX.ORG.RU

Выявлена дыра, позволяющая «уронить» компьютер с Linux под любым пользователем

 ,


0

2

В списке рассылки разработчиков ядра Linux (LKML) был обнародован код, позволяющий через вызов функции ядра socketpair() создать процесс, съедающий 100% процессорного времени и все файловые дескрипторы. Процесс, будучи запущенным от имени любого пользователя, может привести систему к состоянию полной неработоспособности.

Пробный патч, который, тем не менее, не устраняет проблему, опубликован здесь.

>>> Подробности

★★★★★

Проверено: post-factum ()
Последнее исправление: post-factum (всего исправлений: 2)

Ответ на: комментарий от tailgunner

> Но, пока ядра пишутся на Си, чем меньше кода будет выполняться в одном адресном пространстве с ядром, тем лучше для надежности.

Ядро находится во всех адресных пространствах %)))

sv75 ★★★★★
()
Ответ на: комментарий от sv75

> Или TCP будет в виде тредов, заснувших на вызове get_eth_frame?

Или на poll({{ eth0_fd, POLLIN}, {eth1_fd, POLLIN, ...}, n);

Предлагают вынести TCP из ядра. Работа с железом — в ядре.

А кто мешает и драйверы вынести? :)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Или на poll({{ eth0_fd, POLLIN}, {eth1_fd, POLLIN, ...}, n);

Если делать FD --- это смерть. TCP должен получать тупо кадр Eth.

Кстати, еще на копировании неслабо можем проиграть.

А кто мешает и драйверы вынести? :)

Драйвер можно. А обработчики прерываний нельзя. Ну и буфер для карточки (у нас там DMA?) тоже спорно.

sv75 ★★★★★
()
Ответ на: комментарий от sv75

>> Или на poll({{ eth0_fd, POLLIN}, {eth1_fd, POLLIN, ...}, n);

Если делать FD --- это смерть.

Надеюсь, это не ты писал из-под анонимуса O_o

TCP должен получать тупо кадр Eth.

Вообще-то я так и написал.

А кто мешает и драйверы вынести? :)

Драйвер можно. А обработчики прерываний нельзя.

Смотря что понимать под «обработчиком прерывания». Если кусок кода, вызываемый по IRQ, то нельзя, конечно.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Надеюсь, это не ты писал из-под анонимуса O_o

Э.... нет.

Вообще-то я так и написал.

Тогда это не fd %)

sv75 ★★★★★
()
Ответ на: комментарий от sv75

TCP должен получать тупо кадр Eth.

Вообще-то я так и написал.

Тогда это не fd %)

Это именно fd. Ролучается из (пока гипотетического) вызова open(«/dev/eth0»), становится готовым к чтению, когда приходит пакет.

man packet насчет того, как это работает сегодня.

tailgunner ★★★★★
()
Ответ на: комментарий от sv75

> Я могу тогда читать его *кусками*

Не думаю. Впрочем, как говорится, «Then don't do it». Тем более, что практического смысла это не имеет.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Не будем говорить абстрактно. Вот пример кода не для какого-то теоретического идеального микроядра, а для реального: Example 3: CMOS System Clock Там есть вызовы sys_inb и sys_outb. Каким образом гарантировать то, что никакой другой сервис, который, например, читает параметры оборудования из CMOS, не вызовет в это же время sys_outb в тот же порт? Какой будет правильная реализация такого кода?

Перед использованием sys_inb или sys_outb нужно будет заблокировать группу портов, с которыми мы собираемся работать. После использования - разблокировать. Если порт уже заблокирован другим процессом, этот процесс при попытке блокировки порта будет отправлен в очередь ожидающих разблокирования этого порта.

По твоей ссылке есть функция cmos_read_byte. Если убрать проверку на ошибки, и добавить предполагаемую блокировку, то пример драйвера, работающего в режиме пользователя, будет таким:

PRIVATE int cmos_read_byte(offset)
int offset;
{
  unsigned long value = 0;

  sys_lockport(CMOS_PORT);
  sys_lockport(CMOS_PORT + 1);
  sys_outb(CMOS_PORT, offset);
  sys_inb(CMOS_PORT + 1, &value);
  sys_unlockport(CMOS_PORT + 1);
  sys_unlockport(CMOS_PORT);
  return value;
}
morbo
()
Ответ на: комментарий от anonymous

>А какая разница? Если вместо одного переключения в рамках одного процесса выполняется десять переключений между несколькими процессами, то не важно, сколько там ядер - микроядро всегда будет в 10 раз медленнее. Десять последовательных переключений всегда в десять раз медленнее одного, на любом процессоре с любым числом ядер.

Я о том, что когда средний компьютер будет обладать процессором с 1000 ядер, большинство программ и так вынуждены будут стать либо многопоточными, либо многопроцессными. В таком случае ядро, ставшее многопоточным/многопроцессным не будет сильно выделяться на фоне большинства программ. Программы И ТАК станут чаще менять контекст процессора, так почему же именно переключение контекста между процессами ядра будет влиять на падение производительности больше, чем переключаения контекста между процессами пользовательских программ?

morbo
()
Ответ на: комментарий от anonymous

>Не забываем про цену. Цена такого решения: невозможность использовать несколько ядер,

Почему? Драйверы и подсистемы ядра получат возможность работать параллельно. В компьютере 100 устройств? Все 100 устройств будут обслуживаться своим процессом-драйвером, все устройства могут обслуживаться параллельно. При этом система станет очень асинхронной, т.к. каждый ресурс будет обслуживаться своим процессом. Подсистема VFS вообще может представлять собой группу процессов, по одному процессу на каждый жёсткий диск. Подсистема TCP/IP тоже моет представлять собой группу процессов, по одному процессу на каждую сетевую карту.

Произойдёт сбой в сетевой карте - автоматически перезапустится драйвер, перезапустится рабочий процесса TCP/IP, обслуживающий эту сетевую карту. Все программы, установившие соединения через этот процесс TCP/IP и эту сетевую карту получат сообщение об ошибке - недействительный дескриптор. Программы могут отработать эту ошибку как потерю связи и завершить работу или переустановить подключение. Всё стройно и логично. А главное - надёжно.

и потеря скорость в 5-10 раз даже в случае одного ядра.


Развитие процессоров идёт по сценарию увеличение количества ядер.

Это хорошо для всяких sshfs, fuse-smb и curlftpfs, где важна не скорость, а функции. Но совершенно недопустимо для основных файловых систем.


Потерю скорости ещё никто не замерял.


А UIO - это не то. Это просто интерфейс для работы между ядром и userspace. Но он все равно требует модуль ядра. С таким же успехом можно было и раньше писать драйвер из двух частей - модуль в ядре и процесс, который с ним общается. Ничего нового в этом нет.


А вот и нет. Ошибка в процессе в userspace не приведёт к повреждению структур ядра. Ошибка в модуле ядра в kernelspace может привести к повреждению структур ядра и отказу всей системы.

И сейчас можно получить некоторые плюшки от микроядерного подхода, разделив драйвер на kernelspace и userspace-части. Но в случае с микроядром kernelspace-часть будет унифицированной, а не писаться каждый раз для каждого нового драйвера. Эту унифицированную часть будут постоянно проверять и исправлять, т.к. она одна и используется практически во всех драйверах. Следовательно количество ошибок в ней будет со временем исчезающе мало, надёжность системы возрастёт многократно. А в случае когда у каждого драйвера есть своя kernelspace-часть, проверять и исправлять будут только заинтересованные люди, а их ровно столько, сколько людей использует этот драйвер.

Как новый перезапущенный драйвер узнает, куда посылать пакеты, отправленные по сокету с socketid 174? Все открытые дескрипторы перестанут работать. То есть придется перезапускать все приложения, которые открывали сокеты. Это и есть ребут.


Не все приложения, а лишь те, которые работали со сбойнувшим драйвером и которые не способны отработать ситуацию потери связи. Остальные программы либо продолжат работать, либо сообщат о потере связи, либо молча переустановят подключение.

Да. И в случае микроядра ошибка в USB тоже может стать фатальной для всей системы (для всех модулей, кроме ядра, после чего ядро, оставшееся без модулей, уйдет в ребут).


А с чего это ошибка в userspace-программе должна стать фатальной для ядра?

Только в случае микроядра кода будет больше, он будет сложнее.


Безосновательное утверждение. Он будет модульным, за счёт этого произойдёт изоляция сложности в отдельных модулях.

А значит и самих ошибок будет больше, и отловить ошибку будет труднее.


Пока что наоборот - отловить ошибку труднее в драйвере тогда, когда он работает в kernelspace. В случае микроядра можно будет между микроядром и драйвером внедрить специальную программу-прокси, которая сможет вести журнал общения микроядра и драйвера. Или в Solaris и FreeBSD зря изобретают DTrace?

пока ядра пишутся на Си, чем меньше кода будет выполняться в одном адресном пространстве с ядром, тем лучше для надежности.


Их больше не на чем писать.


Ты не понял, здесь претензия не к Си, а к общему адресному пространству. Не на тех словах акцент сделал.

morbo
()
Ответ на: комментарий от anonymous

>Есть еще одна разница. Доверие модулей ядра друг к другу связано с тем, что исходники всех модулей ядра лежат в одном месте. Не нужно слепо доверять, что все будут, например, вызывать указанную функцию именно с такими параметрами - можно проверить, и убедиться, что это так и есть.

Произошёл сбой в работе какого-то модуля, который повредил какую-то структуру в памяти ядра, произошёл kernel-panic. Какой модуль это сделал? Можешь начинать читать исходники всех драйверов в поисках ошибки. Или запускать ядро, добавляя каждый из модулей в blacklist и пытаться воспроизвести аварийную ситуацию.

То есть в данном случае это «доверие» обосновано. Остальные не могли таким похвастаться.


См. выше.

morbo
()
Ответ на: комментарий от sv75

>Я про TCP SYN flood!

Сетевая карта работает в режиме опроса. Когда придёт очередь работы драйвера, он обработает все пакеты за один запуск и передаст все пакеты системе TCP/IP. Принципиально это ничем не отличается от текущей ситуации. Ну потребуется на сто(тысячу) килобайт пакетов TCP SYN одно дополнительное переключение контекста. И что?

morbo
()
Ответ на: комментарий от tailgunner

>> Как новый перезапущенный драйвер узнает, куда посылать пакеты, отправленные по сокету с socketid 174?

Ему скажет ядро (ага, то самое, которое не упало).


Кстати, точно. Если сбой произойдёт в сетевом драйвере, а не в стеке TCP/IP, то все дескрипторы сокетов останутся валидными и программы вообще не заметят перезапуска сетевого драйвера.

morbo
()
Ответ на: комментарий от sv75

>> Но, пока ядра пишутся на Си, чем меньше кода будет выполняться в одном адресном пространстве с ядром, тем лучше для надежности.

Ядро находится во всех адресных пространствах %)))


Вот именно поэтому ядро и должно быть настолько мало, чтобы его можно было проверить вдоль и поперёк. Отсюда и взялась идея микроядра.

morbo
()
Ответ на: комментарий от morbo

> Сетевая карта работает в режиме опроса. Когда придёт очередь работы драйвера, он обработает все пакеты за один запуск и передаст все пакеты системе TCP/IP. Принципиально это ничем не отличается от текущей ситуации. Ну потребуется на сто(тысячу) килобайт пакетов TCP SYN одно дополнительное переключение контекста. И что?

А, у нас еще и буфер нужен «на сто(тысячу) килобайт пакетов TCP SYN»?

ну и данные ещё кстати тогда копируются *много* раз.

sv75 ★★★★★
()
Ответ на: комментарий от morbo

> здесь претензия не к Си, а к общему адресному пространству

Здесь претензия к _сочетанию_ факторов «Си» и «единое адресное пространство». Гарантированно безопасный язык вполне позволит запихнуть все компоненты в единое ядро - вон в Singularity вообще всё работает без защиты памяти.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Как они PD/PT кстати инициализируют там? %)

sv75 ★★★★★
()
Ответ на: комментарий от tailgunner

>> Цена такого решения: невозможность использовать несколько ядер, и потеря скорость в 5-10

Кто и как мерял?

Первые три теста в гугле, где сравнивались reiserfs, ext3, ntfs3g и еще что-то. Особенно отстает скорость записи. А что, есть другие данные?

Внезапно, интерфейс пользовательских драйверов (описанный в статье, ссылку на которую я давал) - это тоже интерфейс между ядром и userspace.

UIO - это интерфейс внутри одного драйвера, разделенного на две части - модуль ядра и userspace. Этот интерфейс сам по себе не необходим. Никто не мешает и без него писать драйвер из двух частей - модуля ядра и программы. А интерфейс, описанный в той статье, насколько я понимаю, остался в той статье. Когда автор закончил университет - он был успешно выброшен как ненужный.

Как новый перезапущенный драйвер узнает, куда посылать пакеты, отправленные по сокету с socketid 174?

Ему скажет ядро (ага, то самое, которое не упало).

А сокет, что, выделялся ядром? То есть сетевая подсистема была в ядре? А что же тогда делал драйвер? И чем тогда микроядро поможет в случае сабжа?

Вот примерно поэтому я и спрашивал тебя о том, пишешь ли ты драйверы. Итак, назови мне причину, по которой любой линуксовый драйвер не может полезть в порт 70.

Так ты же пишешь драйверы? Открой исходник ядра и посмотри, как там это гарантируется. Я даже подскажу где смотреть - модуль rtc.

Черт, совсем недавно падение USB-драйвера вызывало только неработоспособность мыши, а сейчас оно уже фатально для всей системы. Что, даже процессы, не использующие USB, тоже умрут?

Опять сравнение сказки и реальности. В сказке может умереть. В реальности этого не происходит. Мы можем сравнить реальность (миникс) и реальность (линукс). В линуксе при глюках USB на странном железе у меня отваливалась мышь, но остальное работало. А в миниксе на «странном» железе есть такая штука - циклическая перезагрузка, когда падает все, и ядро уходит в ребут.

Пример проблемы, невозможной с userspace-драйверами, я уже привел - сбои autofs из-за неправильной работы драйвера левого character device.

И тут сравнение сказочного микроядра и реального ядра линукса. Может тогда сравнивать сказку со сказкой? Микроядро может гарантировать, что работа с памятью в одном модуле не сможет повлиять на работу с памятью в другом, так? Хорошо. Монолитное ядро ТОЖЕ может это гарантировать. Причем, наверное, даже меньшей ценой, чем микроядро, поскольку не нужно будет выполнять переключение контекста, только защиту памяти. Так что, монолитное ядро лучше?

anonymous
()
Ответ на: комментарий от morbo

> По твоей ссылке есть функция cmos_read_byte. Если убрать проверку на ошибки, и добавить предполагаемую блокировку, то пример драйвера, работающего в режиме пользователя, будет таким: [...]

С sys_outb и sys_inb все понятно. А как будут реализованы функции sys_lockport и sys_unlockport? Это - функции моего драйвера? Функции ядра? Вызов другого драйвера?

Кстати, такое решение не гарантирует, что другой модуль не сможет выполнить запись в порт в то же время, но хотя бы дает возможность ему не сделать этого.

anonymous
()
Ответ на: комментарий от morbo

>> А какая разница?

когда средний компьютер будет обладать процессором с 1000 ядер, большинство программ и так вынуждены будут стать либо многопоточными, либо многопроцессными. В таком случае ядро [...] не будет сильно выделяться на фоне большинства программ.

Причем тут это? Да, на тысяче рядом стоящих компьютеров в среднем выполняется в тысячу раз больше переключений контекста. Мы же говорим не про среднее количество, а про время каждого отдельного вызова.

В монолитном ядре браузер, выполняющий функцию write, делает одно переключение контекста. В микроядре браузер, выполняющий функцию write, делает много переключений. То есть вызов write для браузера на микроядре будет всегда медленнее, чем на монолитном ядре. И это не зависит ни от числа потоков браузера, ни от числа процессоров.

anonymous
()
Ответ на: комментарий от anonymous

>>> Цена такого решения: невозможность использовать несколько ядер, и потеря скорость в 5-10

Кто и как мерял?

Первые три теста в гугле, где сравнивались reiserfs, ext3, ntfs3g и еще что-то.

Ссылку на тест. Что-то я не слышал о реализации reiserfs в виде модуля FUSE.

Как новый перезапущенный драйвер узнает, куда посылать пакеты, отправленные по сокету с socketid 174?

Ему скажет ядро (ага, то самое, которое не упало).

А сокет, что, выделялся ядром? То есть сетевая подсистема была в ядре?

Да. Попробуй читать то, что тебе пишут. И кстати... сетевая подсистема, которая вне ядра, тоже вполне может отследить падение драйвера и повторно подсоединиться к нему.

И чем тогда микроядро поможет в случае сабжа?

Еще раз повторяю - я говорю не о микроядрах, а о userspace-драйверах и ФС.

UIO - это интерфейс внутри одного драйвера, разделенного на две части - модуль ядра и userspace.

Учи матчасть. Модуль в ядре нужен только тогда, когда обрабатываются прерывания или используется DMA (и даже в случае прерываний - есть стандартный модуль uio_pci_generic, который передает прерывания из ядра в userspace, так что самому драйверу модуль ядра не нужен).

Итак, назови мне причину, по которой любой линуксовый драйвер не может полезть в порт 70.

Так ты же пишешь драйверы? Открой исходник ядра и посмотри, как там это гарантируется.

Я знаю, что системой это не гарантируется вообще никак - любой драйвер может полезть в порт 70. А то, что драйверы этого не делают и имеют некоторые соглашения о ресурсах - это добрая воля драйверов. Ровно так же можно сделать и с userspace-драйверами.

Черт, совсем недавно падение USB-драйвера вызывало только неработоспособность мыши, а сейчас оно уже фатально для всей системы. Что, даже процессы, не использующие USB, тоже умрут?

Опять сравнение сказки и реальности.

Сравнение двух сказок, причем обе рассказаны тобой.

Пример проблемы, невозможной с userspace-драйверами, я уже привел - сбои autofs из-за неправильной работы драйвера левого character device.

И тут сравнение сказочного микроядра и реального ядра линукса.

Если тебе хочется, сравни userspace-драйверы Minix3 и in-kernel драйверы Linux, И то, и другое - реальность.

Микроядро может гарантировать, что работа с памятью в одном модуле не сможет повлиять на работу с памятью в другом, так? Хорошо. Монолитное ядро ТОЖЕ может это гарантировать

Каким образом?

Жду ссылки на сравнение производительности ядерных ext3 и reiserfs с их аналогами на FUSE.

tailgunner ★★★★★
()
Ответ на: комментарий от morbo

> Произойдёт сбой в сетевой карте - перезапустится драйвер, перезапустится рабочий процесса TCP/IP. Все программы, установившие соединения через этот процесс сообщение об ошибке - недействительный дескриптор. Программы могут отработать эту ошибку и завершить работу или переустановить подключение.

Осталось переписать все работающие с сокетами программы в мире, чтобы они обрабатывали сообщение «недействительный дескриптор». :)

Кстати, процессов, выделявших дескрипторы, несколько будет? Если да, то кто и как будет по дескриптору определять, кому передать вызов write от очередного клиента?

> Потерю скорости ещё никто не замерял.

Сравнение между fuse ФС и native ФС? Да запросто: раз, два, три, четыре Все тесты показывают, что FUSE медленнее. Тут на ядерную ext4 иногда жалуются, что слишком медленно, а вы еще хотите замедлить?

> Ошибка в процессе в userspace не приведёт к повреждению структур ядра.

В Win98 - приводила. Может дело не в том, kernel-space это или user-space, а в защите памяти?

> И сейчас можно получить некоторые плюшки от микроядерного подхода, разделив драйвер на kernelspace и userspace-части. Но в случае с микроядром kernelspace-часть будет унифицированной, а не писаться каждый раз для каждого нового драйвера.

Эта фраза не соответствует практике. А раз неверна она, то неверно и следствие:

> Следовательно количество ошибок в ней будет со временем исчезающе мало, надёжность системы возрастёт многократно.

Практика показывает, что в миниксе апи меняется даже между минорными релизами. В результате на машинах, где предыдущая версия minix запускалась, новая уходит в циклический ребут.

>> Да. И в случае микроядра ошибка в USB тоже может стать фатальной для всей системы (для всех модулей, кроме ядра, после чего ядро, оставшееся без модулей, уйдет в ребут).

> А с чего это ошибка в userspace-программе должна стать фатальной для ядра?

Не для ядра, а для системы. Это одна из ошибок теоретиков микроядерной архитектуры. Вы привыкли, что у монолитного ядра, вроде Linux, «стабильность системы» == «стабильность ядра». А для микроядра это не так.

В микроядере «стабильность системы» == «стабильность ядра и всех его модулей». Модули зависят друг от друга длинными цепочками. Упадет один - остальные попадают как доминошки.

Гипотетический пример: падает модуль usb устройства, возвращая некорректное состояние шины, из-за этого падает модуль usbsound, проверяющий наличие USB-колонок, за ним виснет soundcore, пославший сообщение в usbsound, но не получивший ответа. Этот вис детектится модулем watchdog и тот дает команду перезапустить soundcore. Ядро его убивает, затем пробует его считать с диска и загрузить снова. Для чтения она дает команду sata-модулю, который перед чтением важного модуля с диска делает sync, пытаясь также сбросить буферы и на воткнутую флешку (тоже sata), но usb умер, флешки нет, и sata тоже падает. Остается только ядро. Ядро живое. А система умерла.

Чтобы таких примеров не было - надо очень постараться. Каждый модуль должен корректно обрабатывать падение ЛЮБОГО из модулей, с которым он взаимодействует. Каждый вызов должен быть написан с учетом того, что функция НИКОГДА не вернет результат.

Если в монолитном ядре проблема - не запортить чужие данные, то в микроядре еще большая проблема - не упасть при передаче данных, проблема, которой в монолите нет. Не запороть чужие данные легко - этому все программисты учатся с самого начала. А вот написание фактически устойчивой распределенной системы - это могут единицы. Тут и большая сложность кода и увеличение объема этого кода.

anonymous
()
Ответ на: комментарий от morbo

> Сетевая карта работает в режиме опроса. Когда придёт очередь работы драйвера, он обработает все пакеты за один запуск и передаст все пакеты системе TCP/IP. Принципиально это ничем не отличается от текущей ситуации. Ну потребуется на сто(тысячу) килобайт пакетов TCP SYN одно дополнительное переключение контекста. И что?

«Принципиально это ничем не отличается от текущей ситуации.»

Отличается. Сейчас сетевая карта не хранит сто(тысячу) килобайт пакетов.

Кстати, точно. Если сбой произойдёт в сетевом драйвере, а не в стеке TCP/IP, то все дескрипторы сокетов останутся валидными и программы вообще не заметят перезапуска сетевого драйвера.

В этом случае сетевая подсистема должна быть в ядре. И тогда от сабжевой проблемы это уже не спасет.

anonymous
()
Ответ на: комментарий от tailgunner

> Ссылку на тест. Что-то я не слышал о реализации reiserfs в виде модуля FUSE.

Ссылки - в соседнем сообщении. Напоминаю, в ответ на «ядро могут завалить только баги в FUSE, а не в 100500 файловых системах», я говорю о том, что цена этого - потеря скорости. То есть система, работающая через FUSE, работает медленнее, чем родная ядерная. Неужели это не очевидно?

> Я знаю, что системой это не гарантируется вообще никак - любой драйвер может полезть в порт 70.

То есть код ты не смотрел? Ну как хочешь...

> Ровно так же можно сделать и с userspace-драйверами.

Также - нельзя. Даже дать драйверам возможность блокировать ресурсы - не просто. Например, надо учесть, что драйвер мог заблокировать порт и упасть. Вот вся прелесть микроядер. Функция, которая может не вернуться... мечта тестера-мазохиста.

> Сравнение двух сказок, причем обе рассказаны тобой.

Эти «сказки» были ответом на «сказки» про autofs.

>> Микроядро может гарантировать, что работа с памятью в одном модуле не сможет повлиять на работу с памятью в другом, так? Хорошо. Монолитное ядро ТОЖЕ может это гарантировать

> Каким образом?

Да куча способов. Например, так же, как это делает микроядро, только без создания процесса - заданием параметров защиты памяти. Можно и с созданием процесса - в ядре есть потоки. Например, Mondriaan Memory Protection - очередное академическое исследование, которое даже в LKML не упоминалось. И наконец, если автор модуля боится повредить чужую память, он может использовать для работы с памятью мелкий самописный аллокатор с проверками.

> Еще раз повторяю - я говорю не о микроядрах, а о userspace-драйверах и ФС.

Да? Значит я неверно понял фразу:

Микроядро не является «серебряной пулей», но многие проблемы всё же решает.

Мне только было интересно, какие же проблемы оно решает.

А про драйвера - выносить их ВСЕ в userspace нельзя, если конечно нет желания сильно потерять в скорости, не говоря о сложности реализации. Сейчас файловая система работает быстро потому, что драйвер контроллера, кеш, ФС и менеджер памяти видят друг друга. Передаются только указатели. Убрать это - и каждое обращение к диску будет означать кучи копирований и переключений.

Та же ситуация с драйверами сетевых карт. Даже монолитные ядра не успевают обрабатывать поток от гигабитной сетевухи на старых процессорах. Стоит вынести драйвер в userspace, и буферы придется гонять между процессом, сокетом, драйвером и картой, копируя его по многу раз. Скорость упадет не на проценты, а в разы.

Это не только теория. Практическая ситуация с гигабитными драйверами в миниксе это подтверждает. Вообще, с гигабитом в миниксе все не очень хорошо, но как минимум одно исследование гуглится. Там хорошо видно, что ГИГАБИТ с трудом вытягивает 10MB/sec.

anonymous
()
Ответ на: комментарий от anonymous

>> Ссылку на тест. Что-то я не слышал о реализации reiserfs в виде модуля FUSE.

Ссылки - в соседнем сообщении.

Там сравниваются _разные_ реализации NTFS в userspace и ядре, это не очень интересно, потому что реализации тупо разные. Вот если бы сравнивались ext3 и ext3-fuse, reiserfs и reiserfs-fuse, да хоть fat32-fuse - было бы интересно, а так... Кстати, в тестах IOZone read и MP3 Encoding даже NTFS-3g выступила вполне достойно.

Я знаю, что системой это не гарантируется вообще никак - любой драйвер может полезть в порт 70.

То есть код ты не смотрел? Ну как хочешь...

Я смотрел код. Там есть request_region, и что? Если я не сделал request_region, ядро всё равно не помешает мне выдать inb или outb на порт RTC. У него просто нет такой возможности.

Сравнение двух сказок, причем обе рассказаны тобой.

Эти «сказки» были ответом на «сказки» про autofs.

Ну да, если ты не видел, воспроизвести не смог - значит, сказка. Ты не страус часом?

Стоит вынести драйвер в userspace, и буферы придется гонять между процессом, сокетом, драйвером и картой, копируя его по многу раз. Скорость упадет не на проценты, а в разы.

Это не только теория. Практическая ситуация с гигабитными драйверами в миниксе это подтверждает.

*shrug* Причем тут миникс? Ну, написал студент драйвер, выяснил, что в Minix3 проблемы. Какое это отношение имеет к Linux? Где доказательства, что проблемы неразрешимы? Ответы «никакого» и «никаких».

tailgunner ★★★★★
()
Ответ на: комментарий от sv75

>А, у нас еще и буфер нужен «на сто(тысячу) килобайт пакетов TCP SYN»?

ну и данные ещё кстати тогда копируются *много* раз.


Этот буфер будет областью shared memory, к которой нужные процессы будут иметь доступ только на чтение, а нужные - на чтение и запись.

Объём данных, подвергающихся копированию, равен и в случае монолитного ядра и в случае микроядра с процессами. Поэтому и в случае с монолитным ядром данные тоже копируются *много* раз.

morbo
()
Ответ на: комментарий от anonymous

>А сокет, что, выделялся ядром? То есть сетевая подсистема была в ядре? А что же тогда делал драйвер? И чем тогда микроядро поможет в случае сабжа?

Сокет выделялся сетевой подсистемой - процессом, который при падении процесса-драйвера продолжает работать.

morbo
()
Ответ на: комментарий от anonymous

>С sys_outb и sys_inb все понятно. А как будут реализованы функции sys_lockport и sys_unlockport? Это - функции моего драйвера? Функции ядра? Вызов другого драйвера?

Это функции ядра. А твой драйвер - обычный процесс, работающий в режиме userspace и делающий системные вызовы sys_outb, sys_inb, sys_lockport и sys_unlockport.

Кстати, такое решение не гарантирует, что другой модуль не сможет выполнить запись в порт в то же время, но хотя бы дает возможность ему не сделать этого.


Гарантирует, потому что модуль - это процесс, работающий в userspace. А ввод-вывод в порты может осуществлять только ядро системы. Но ядро ведёт список блокировок портов ввода-вывода, поэтому не даст одному процессу осуществлять ввод-вывод по тем портам, которые уже были заблокированы другим процессом.

morbo
()
Ответ на: комментарий от anonymous

>В монолитном ядре браузер, выполняющий функцию write, делает одно переключение контекста. В микроядре браузер, выполняющий функцию write, делает много переключений. То есть вызов write для браузера на микроядре будет всегда медленнее, чем на монолитном ядре. И это не зависит ни от числа потоков браузера, ни от числа процессоров.

Ты не замечал, что в последнее время становится популярным делить браузер на несколько процессов? Чем из большего количества процессов состоит браузер, тем больше будет переключений контекста. Вне зависимости от того, какое ядро у системы.

В системах с небольшим количеством процессорных ядер и с большинством однопроцессных программ выгодно как можно реже переключать контекст.

В системах с большим количеством процессорных ядер выгодно поделить всю работу и выполнять её одновременно на нескольких процессорных ядрах, поэтому программы будут преимущественно многопоточными или многопроцессными. А в ситуации, когда все программы уже многопоточные и переключают контекст процессора значительно чаще, уже почти не будет разницы между монолитным ядром и микроядром с большим количеством процессов.

morbo
()
Ответ на: комментарий от anonymous

>Отличается. Сейчас сетевая карта не хранит сто(тысячу) килобайт пакетов.

А как же тогда работает режим так называемый polling в FreeBSD? Работает не для всех сетевых карт, но

Кстати, точно. Если сбой произойдёт в сетевом драйвере, а не в стеке TCP/IP, то все дескрипторы сокетов останутся валидными и программы вообще не заметят перезапуска сетевого драйвера.


В этом случае сетевая подсистема должна быть в ядре. И тогда от сабжевой проблемы это уже не спасет.


Почему это сетевая подсистема должна работать в ядре? Это всего-лишь программа, реализующая удобную абстракцию. Если бы она управляла аппаратными ресурсами компьютера - доступом к памяти, к процессорам, к портам ввода-вывода, аппаратным прерываниям, каналам прямого доступа к памяти, тогда её присутствие в ядре было бы необходимо.

morbo
()
Ответ на: комментарий от anonymous

>Также - нельзя. Даже дать драйверам возможность блокировать ресурсы - не просто. Например, надо учесть, что драйвер мог заблокировать порт и упасть. Вот вся прелесть микроядер. Функция, которая может не вернуться... мечта тестера-мазохиста.

Диспетчер процессов находится в ядре. Если процесс упал, все ресурсы, занятые эти процессом, автоматически освобождаются.

Драйвер заблокировал порт и упал? Блокировка снимается. Программа открыла файл и упала - файл закрывается. Разница есть? Разницы нет.

И наконец, если автор модуля боится повредить чужую память, он может использовать для работы с памятью мелкий самописный аллокатор с проверками.


самописный


Велосипедостроение в действии?

А про драйвера - выносить их ВСЕ в userspace нельзя, если конечно нет желания сильно потерять в скорости, не говоря о сложности реализации. Сейчас файловая система работает быстро потому, что драйвер контроллера, кеш, ФС и менеджер памяти видят друг друга. Передаются только указатели. Убрать это - и каждое обращение к диску будет означать кучи копирований и переключений.


Та же ситуация с драйверами сетевых карт. Даже монолитные ядра не успевают обрабатывать поток от гигабитной сетевухи на старых процессорах. Стоит вынести драйвер в userspace, и буферы придется гонять между процессом, сокетом, драйвером и картой, копируя его по многу раз. Скорость упадет не на проценты, а в разы.


Конечно, между микроядрами и монолитными ядрами есть ещё много промежуточных техник и решений. Сначала монолитные ядра будут превращаться в модульные, потом модули будут планироваться внутри ядра как процессы ядра, потом их память будет защищаться друг от друга в нужных местах. Потом часть процессов будут перемещены из пространства ядра в пространство пользователя - получится уже гибридное ядро. Потом гибридному ядру останется сделать несколько шагов в сторону микроядра - вынести все оставшиеся процессы в пространство пользователя. Это произойдёт, если издержки на смену контекста замедлят полученную систему не на порядок, а процентов на 10.

Кстати, почему-то никого особо не смущает система виртуализации Xen - а это и есть прообраз будущей микроядерной системы. Там ведь тоже осуществляется планирование процессов-операционных систем, распределение памяти и разграничение доступа к аппаратным ресурсам. Но никто и не думал о Xen в таком контексте. Подумайте. Движение в сторону микроядра может происходить во встречных направлениях.

morbo
()
Ответ на: комментарий от morbo

> Этот буфер будет областью shared memory, к которой нужные процессы будут иметь доступ только на чтение, а нужные - на чтение и запись.

Ну только это не микро ядро вроде бы будет, там предполагались асинхронные сообщения же?

Поэтому и в случае с монолитным ядром данные тоже копируются *много* раз.

В рабочих стека TCP/IP всё копируется теоретически минимальное число раз.

sv75 ★★★★★
()
Ответ на: комментарий от tailgunner

> Там сравниваются _разные_ реализации NTFS в userspace и ядре, это не очень интересно, потому что реализации тупо разные.

Очевидно, реализация в ядре и в fuse всегда будут разные. В этом и смысл сравнения - проверить, какая реализация будет быстрее. Пока что FUSE всегда медленнее.

> Вот если бы сравнивались ext3 и ext3-fuse, reiserfs и reiserfs-fuse, да хоть fat32-fuse - было бы интересно, а так...

Так все равно они будут разные. Хотя, если хочется - проведи эксперимент, сравни vfat с fatfuse или libfat. Про первую автор итак пишет, что она раз в шесть медленнее.

> Кстати, в тестах IOZone read и MP3 Encoding даже NTFS-3g выступила вполне достойно.

Логично, когда мало вызовов, или когда скорость итак низкая (при кодировании mp3 она определенно низкая), то и тормоза заметны не будут.

> Я смотрел код. Там есть request_region, и что? Если я не сделал request_region, ядро всё равно не помешает мне выдать inb или outb на порт RTC. У него просто нет такой возможности.

Ну да, да... А еще там есть spin_lock_irq и spin_unlock_irq, и они гарантируют, что никто ничего не вызовет. Но в ядре они могут быть, а в юзерспейсе - нет.

> Причем тут миникс? Какое это отношение имеет к Linux?

Это подтверждение теории, только и всего. Теория говорит: если выносить драйвера в userspace то могут быть проблемы со сложностью и БУДУТ проблемы с производительностью. Практика реализация драйверов в userspace на примере minix-а подтверждает: проблемы ЕСТЬ. :)

> Где доказательства, что проблемы неразрешимы?

Доказательство чего? Того, что нельзя выполнить переключение контекста без переключения контекста? Того, что нельзя скопировать область памяти из одного процесса в другой не копируя память?

anonymous
()
Ответ на: комментарий от morbo

> Этот буфер будет областью shared memory, к которой нужные процессы будут иметь доступ только на чтение, а нужные - на чтение и запись.

Если во всех драйверах вся память будет shared memory, то зачем было выделять их в отдельные процессы? Пусть бы работали в ядре, там вся память итак shared. :)

Объём данных, подвергающихся копированию, равен и в случае монолитного ядра и в случае микроядра с процессами.

Если бы все было так просто. Объем «полезных» данных у них одинаковый, но память они используют по-разному. Из простых примеров - кеш в линуксе. В линуксе используется логичный подход - вся неиспользуемая программами память отдается под кеш. Действительно, если память все равно есть, зачем ей простаивать. А если какая-то программа просит еще памяти, то самая ненужная часть кеша освобождается. Просто и гениально. В монолитном ядре.

Теперь представим, что у нас микроядро, причем вся память кеша смаплена в shared memory разных процессов файловых систем. Они ее активно используют, читают, пишут, наверное как-то передают указатели друг другу и драйверам, когда надо считать очередной файл, и т.д.

Пока оставим вопрос того, как файловые системы будут общаться с драйверами - это отдельная головная боль. Рассмотрим только вопрос памяти. Новый процесс попросил память. Каким образом система ее выделит? С точки зрения ядра - вся память занята процессами. Как попросить кучу разных процессов освободить память? Причем не просто память, а shared memory? Да и как вообще определить, какие процессы надо просить?

anonymous
()
Ответ на: комментарий от morbo

> Сокет выделялся сетевой подсистемой - процессом, который при падении процесса-драйвера продолжает работать.

Тогда это почти ничего не меняет в случае сабжевой проблемы. Ведь тогда точно так же такой процесс повис бы, причем сожрав памяти перед этим, а затем он бы упал, и, может быть, перезапустился, но вместе с ним пришлось бы перезапускать и все работающие с сокетами программы, потому что их дескрипторы вдруг перестали существовать.

С дескрипторами, кстати, в этом случае будет отдельный вопрос. Например, такой процесс означает, что он обслуживает только дескрипторы сокетов, так? Дескрипторы файлов обслуживает другой процесс? То есть с вероятностью близкой к 100% файловый дескриптор, выданный мне при открытии очередного файла, будет совпадать с сетевым дескриптором, выданным при открытии сокета?

anonymous
()
Ответ на: комментарий от anonymous

>> Там сравниваются _разные_ реализации NTFS в userspace и ядре, это не очень интересно, потому что реализации тупо разные.

Очевидно, реализация в ядре и в fuse всегда будут разные.

Очевидно, что Солнце вращается вокруг Земли.

если хочется - проведи эксперимент, сравни vfat с fatfuse или libfat.

Я немного представляю себе сложность этого эксперимента, так что нет, спасибо. Кроме того, он не имеет смысла - FUSE уже в ядре и ее никто не собирается выбрасывать.

Про первую автор итак пишет, что она раз в шесть медленнее.

«FatFuse is a linux fuse implementation capable of reading FAT16 and FAT32 filesytems. It is written in python».

«Version 0.4.0 22 March 2007»

Т.е. ФС, написанная на Питоне, и заброшенная 3 года на версии 0.4, всего в 6 раз медленнее ядерного драйвера. Не так уж плохо.

Ну да, да... А еще там есть spin_lock_irq и spin_unlock_irq, и они гарантируют

Бугага. Я не сделал вызова request_region, и spinlock_lock вызывать не стану. Ты правда не понимаешь, что порт 70 защищен от внутриядерного кода только добровольным соглашением драйверов?

Теория говорит: если выносить драйвера в userspace то могут быть проблемы со сложностью и БУДУТ проблемы с производительностью.

Теория говорит, что производительность будет ниже. Насколько ниже - теория умалчивает.

Того, что нельзя скопировать область памяти из одного процесса в другой не копируя память?

Эх... и этот человек спорит о userspace-драйверах.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

>Ну да, да... А еще там есть spin_lock_irq и spin_unlock_irq, и они гарантируют, что никто ничего не вызовет. Но в ядре они могут быть, а в юзерспейсе - нет.

Есть код, который имеет непосредственный доступ к оборудованию - он будет в ядре. А есть код, который будет обращаться к оборудованию через посредника - ядро. Этот код и будет в userspace. То, что spin_lock_irq нельзя _выполнить_ в userspace не означает, что код, выполняющий _вызов_ этой функции, должен быть тоже внесён в ядро. То, что нельзя выполнить в userspace, можно попросить сделать у ядра.

morbo
()
Ответ на: комментарий от anonymous

>Если во всех драйверах вся память будет shared memory, то зачем было выделять их в отдельные процессы? Пусть бы работали в ядре, там вся память итак shared. :)

Затем, что к этой области shared memory будут иметь доступ только те драйверы, которым она нужна для работы. Сейчас же все драйверы имеют доступ ко всей памяти.

Если бы все было так просто. Объем «полезных» данных у них одинаковый, но память они используют по-разному. Из простых примеров - кеш в линуксе. В линуксе используется логичный подход - вся неиспользуемая программами память отдается под кеш. Действительно, если память все равно есть, зачем ей простаивать. А если какая-то программа просит еще памяти, то самая ненужная часть кеша освобождается. Просто и гениально. В монолитном ядре.


Теперь представим, что у нас микроядро, причем вся память кеша смаплена в shared memory разных процессов файловых систем. Они ее активно используют, читают, пишут, наверное как-то передают указатели друг другу и драйверам, когда надо считать очередной файл, и т.д.


Пока оставим вопрос того, как файловые системы будут общаться с драйверами - это отдельная головная боль. Рассмотрим только вопрос памяти. Новый процесс попросил память. Каким образом система ее выделит? С точки зрения ядра - вся память занята процессами. Как попросить кучу разных процессов освободить память? Причем не просто память, а shared memory? Да и как вообще определить, какие процессы надо просить?


Стоп-стоп-стоп, помедленнее. Когда кому-то понадобится память, у кого она будет отнята в случае монолитного ядра? У системы кэширования. В случае с микроядром нужно будет просить освободить память только систему кэширования. Если кэш уже используется каким-то модулем ядра, то кэш тоже нельзя будет внезапно освободить.

Потом, кэш - это не обязательно память используемая прямо сейчас каким-то процессом. Это в том числе память, которая была занята в спекулятивных целях, в надежде что она потребуется _скоро_. Вот её-то можно в любой момент попросить освободить у системы кэширования. Система кэширования скажет драйверам диска - запишите эти страницы на диск, или просто пометит страницы памяти, как не используемые, если запись страниц на диск не требуется.

Точно так же будет работать и подсистема кэширования в микроядре - она будет постоянно общаться с системой управления памятью, которая находится в ядре.

morbo
()
Ответ на: комментарий от sv75

>Ну только это не микро ядро вроде бы будет, там предполагались асинхронные сообщения же?

Что такое «асинхронные» и что такое «сообщения».

Сообщения - это просто альтернатива блокировкам. Если обработчик сообщения один, то все отправители становятся в очередь ожидания готовности обработчика.

Асинхронность - это возможность сделать запрос и продолжить работу, не дожидаясь выполнения запроса и результатов его выполнения. Она достижима и в случае с сообщениями и в случае с системными вызовами.

Ни сообщения, ни их асинхронность не предполагают, что большой объём данных будет передаваться в теле сообщения. Также как и ни системные вызовы ни асинхронные системные вызовы не предполагают передачу большого объёма данных через стек.

В рабочих стека TCP/IP всё копируется теоретически минимальное число раз.


Слепая вера такая слепая...

morbo
()
Ответ на: комментарий от anonymous

>Тогда это почти ничего не меняет в случае сабжевой проблемы. Ведь тогда точно так же такой процесс повис бы, причем сожрав памяти перед этим, а затем он бы упал, и, может быть, перезапустился, но вместе с ним пришлось бы перезапускать и все работающие с сокетами программы, потому что их дескрипторы вдруг перестали существовать.

Если дескриптор стал недействительным, то любые операции с ним будут завершаться с сообщением об ошибке «несуществующий дескриптор». Эту ситуацию можно обрабатывать точно так же, как ситуацию «ошибка чтения» или «ошибка записи» или «потеря связи».

Если в программе не предусмотрена ситуация обрыва соединения или ошибка чтения файла, то такая программа свалится в любом случае. Будь то монолитное ядро или микроядро с сервисами.


С дескрипторами, кстати, в этом случае будет отдельный вопрос. Например, такой процесс означает, что он обслуживает только дескрипторы сокетов, так? Дескрипторы файлов обслуживает другой процесс? То есть с вероятностью близкой к 100% файловый дескриптор, выданный мне при открытии очередного файла, будет совпадать с сетевым дескриптором, выданным при открытии сокета?


Читайте предыдущие сообщения. Я уже сказал, что дескриптор сокета или дескриптор файла может состоять из двух частей - идентификатор службы и собственно дескриптор, уникальный в пределах этой службы. Программа вообще может не замечать этого факта, а небольшая прослойка, изображающая POSIX для устаревших программ, будет сама прозрачным для программы образом направлять запросы к нужному сервису.

morbo
()
Ответ на: комментарий от morbo

> Слепая вера такая слепая...

Я как-то неделю потратил на выяснение этой проблемы. Ставил хуки в ядерном memcpy.

sv75 ★★★★★
()
Ответ на: комментарий от morbo

> Сообщения ... не предполагают, что большой объём данных будет передаваться в теле сообщения.

Ага, ага. Они предполагают shared memory и синхронизацию для доступа ней семафорами, ну конечно же!

В общем, было бы интересно узнать как сделано стек TCP в Миникс. Как узнаете, можете рассказать. А пока у вас пустое теоретизирование без доказательств.

sv75 ★★★★★
()
Ответ на: комментарий от morbo

> Драйвер заблокировал порт и упал? Блокировка снимается. Программа открыла файл и упала - файл закрывается. Разница есть? Разницы нет.

Все верно, разницы нет, пока то, что блокирует программа, управляется ядром. То есть пока речь идет о взаимодействии ядра и программы. Разницы нет для монолитного ядра. Но для микроядра взаимодействие происходит не только между программами и ядром, но еще и между программами и программами. То есть одна программа должна будет блокировать ресурсы другой программы (да хоть те же сегменты shared memory). В этом проблема - во взаимодействии, оно значительно усложняется.

Велосипедостроение в действии?

Велосипедостроением это будет если есть другие такие же реализации. Но тогда и самому писать не придется, можно взять готовую. А если аналога нет - то нет и «велосипеда».

Конечно, между микроядрами и монолитными ядрами есть ещё много промежуточных техник и решений. ... останется сделать несколько шагов в сторону микроядра

Пока что мы делаем все наоборот. :) Мы медленно превращаем микроядро в монолитное. Сначала мы переносим в ядро менеджер блокировок и управление памятью. Позже у нас там появится paging. И мы уже упоминали, что драйвера будут работать через shared memory. Следом мы перенесем в ядро файловый кеш, как часть менеджера памяти. Потом там же окажется работа с дескрипторами, иначе нельзя будет прозрачно реализовать работу с файлами и сокетами. Последними туда переползут драйвера и файловые системы, чтобы обеспечить нужную производительность, все равно они итак работали через огромные куски shared memory. И мы получим Линукс. :)

Кстати, почему-то никого особо не смущает система виртуализации Xen

А причем тут Xen? Он выполняет другие функции. В частности он не дает двум гостям использовать общий аппаратный ресурс. В линуксе я могу запусить две копии glxgears, и они обе будут рендериться на видеокарте. А в xen-е два гостя могут использовать аппаратные возможности рендеринга одной видеокарты?

anonymous
()
Ответ на: комментарий от tailgunner

> Я немного представляю себе сложность этого эксперимента, так что нет, спасибо.

В чем же сложность? Вон, phoronix тестирует, ничего сложного. Тестируются же не сферические файловые системы в вакууме, а реальные.

Я не сделал вызова request_region, и spinlock_lock вызывать не стану. Ты правда не понимаешь, что порт 70 защищен от внутриядерного кода только добровольным соглашением драйверов?

Ну не сделал, и ладно. Тогда в твоем драйвере будет баг. А на остальные драйвера это не повлияет, и они будут работать корректно, и даже твой кривой драйвер не сможет испортить им работу.

Теория говорит, что производительность будет ниже. Насколько ниже - теория умалчивает.

На этот вопрос и отвечает практика. Причем по всем параметрам примерно одинаковые результаты, и по сравнению minix-linux в скорости сети, и по сравнению fuse-native в скорости ФС - скорость падает в разы.

anonymous
()
Ответ на: комментарий от morbo

> Когда кому-то понадобится память, у кого она будет отнята в случае монолитного ядра? У системы кэширования. В случае с микроядром нужно будет просить освободить память только систему кэширования.

В случае монолитного ядра кеш может действительно освободить соответствующий сегмент. А с микроядром и shared memory так не выйдет. Даже если кеш сделает detach соответствующей области памяти - это не освободит ее, до тех пор, пока все драйвера, файловые системы и другие тоже не «закроют» этот сегмент. Получается, нет гарантированного способа освободить такую память.

Потом, кэш - это не обязательно память используемая прямо сейчас каким-то процессом.

Это не важно. Важно только то, что эта память сейчас может быть смаплена в нескольких процессах - в процессе драйвера, который считал ее с диска (ведь кто-то ж ее считал?), в процессе кеша и процессе файловой системы. Или даже нескольких файловых систем. А может и нескольких драйверов, ведь у нас же общий кеш для USB и IDE? Освободить память, которая занята неизвестно кем - вот проблема.

или просто пометит страницы памяти, как не используемые

Кеш - это процесс? Тогда не пометит. В лучшем случае - сделает detach&close и будет надеяться, что больше ни у кого эта память не смаплена.

Точно так же будет работать и подсистема кэширования в микроядре - она будет постоянно общаться с системой управления памятью, которая находится в ядре.

Таак. Мы подходим к интересному месту: менеджер памяти В ЯДРЕ зависит от ПРОЦЕССА кеширования. Падает кеш - падает и ядро? Или дисковый кеш - тоже часть ядра (не путать с paging-ом, до него мы еше доберемся)?

anonymous
()
Ответ на: комментарий от anonymous

>> Я не сделал вызова request_region, и spinlock_lock вызывать не стану. Ты правда не понимаешь, что порт 70 защищен от внутриядерного кода только добровольным соглашением драйверов?

Ну не сделал, и ладно. Тогда в твоем драйвере будет баг. А на остальные драйвера это не повлияет, и они будут работать корректно, и даже твой кривой драйвер не сможет испортить им работу.

даже твой кривой драйвер не сможет испортить им работу.

даже твой кривой драйвер не сможет испортить им работу.

Грустно.

tailgunner ★★★★★
()
Ответ на: комментарий от morbo

> Если дескриптор стал недействительным, то любые операции с ним будут завершаться с сообщением об ошибке «несуществующий дескриптор». Эту ситуацию можно обрабатывать точно так же, как ситуацию «ошибка чтения» или «ошибка записи» или «потеря связи».

Не так. Эту ситуацию нужно обрабатывать ДОПОЛНИТЕЛЬНО к тем ситуациям ошибки чтения и др. Если программа этого не делает... А многие не делают.

Если в программе не предусмотрена ситуация обрыва соединения или ошибка чтения файла, то такая программа свалится в любом случае. Будь то монолитное ядро или микроядро с сервисами.

В большинстве программ предусмотрены ошибки чтения и обрыва соединения. Но мало кто предполагал, что сокет, который был действительным в одном вызове sendto, вдруг станет недействительным в следующем.

Я уже сказал, что дескриптор сокета или дескриптор файла может состоять из двух частей - идентификатор службы и собственно дескриптор, уникальный в пределах этой службы.

Не может. Тогда не будет работать вызов select. Дескриптор должны быть натуральным числом, и чем меньше - тем лучше. Замечу, что select - это ядерный вызов.

anonymous
()
Ответ на: комментарий от tailgunner

> Грустно.

А что грустного? Наоборот, это же хорошо. Функция spin_lock_irq что-то делает, не просто так она имеет такое имя. :)

anonymous
()
Ответ на: комментарий от sv75

> Я как-то неделю потратил на выяснение этой проблемы. Ставил хуки в ядерном memcpy.

Какой проблемы, если не секрет? Мне интересны вопросы производительности сетевых вызовов.

PS: а ядерный memmove проверялся? ;)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.