alexey123_45
Jul 31 2017, 12:28
Здравствуйте
Столкнулся с такой проблемой: В ARM ядре из-под Linux пишу текстовый файл CSV формата на внешнюю SDHC карту, отформатированной в FAT32. Как только размер файла на диске становится примерно 39МБайт программа аварийно завершается и в файле вместо последних нескольких записей мусор. Проверял, на утечки памяти, не обнаружил, не может ли это быть связано с каким-то кэшированием?
Запись в файл идет на фоне обмена с DSP ядром через DSPLINK
Файл открываю так
resultFile = open(name, O_RDWR | O_CREAT | O_APPEND, 0640);
Записываю
test_a = write(resultFile, rec_buf, strlen(rec_buf));
Не сталкивался кто-нибудь с такой ситуацией?
aaarrr
Jul 31 2017, 15:00
Цитата(alexey123_45 @ Jul 31 2017, 15:28)

Запись в файл идет на фоне обмена с DSP ядром через DSPLINK
Проверьте, нет ли где перекрытия по карте памяти - это отличный источник разнообразных чудес.
Jury093
Jul 31 2017, 16:10
Цитата(alexey123_45 @ Jul 31 2017, 15:28)

Столкнулся с такой проблемой: В ARM ядре из-под Linux пишу текстовый файл CSV формата на внешнюю SDHC карту, отформатированной в FAT32. Как только размер файла на диске становится примерно 39МБайт программа аварийно завершается и в файле вместо последних нескольких записей мусор. Проверял, на утечки памяти, не обнаружил, не может ли это быть связано с каким-то кэшированием?
широкополосно:
- отключите на время обмен с DSP, если перестанет валиться, то копаете в том направление
- в линуксе из под того же пользователя командой
dd сгенерите запись файла допустим 100МБ на тот носитель (SDHC)
- в своей софтине добавьте отладочный блок с записью в отдельный файл транзакций рабочих записей, хотя бы
rec_buf, strlen(rec_buf) и объем свободной системной памяти
- как вариант, ошибка в исходниках, например, открываете файл, пишете и не закрываете, банальная утечка..
alexey123_45
Aug 2 2017, 10:44
Проверил, сделал простой тест
rec_len =2800;
char rec_buf[4096];
resultFile = open(name, O_RDWR | O_CREAT | O_APPEND, 0640);
while(dsp_message_count<30000)
{
test_a = write(resultFile, rec_buf, rec_len);
printf("Write to file = %d,%d,%d\n",test_a, resultFile, dsp_message_count);
//usleep(100000);
dsp_message_count +=1;
}
close(resultFile);
Посмотрел расход памяти, пока файл пишется свободная память уменьшается, но когда приложение перестает работать, т.е. отрабатывает close(resultFile); и приложение закрывается, объем свободной памяти не восстанавливается, это правильная работа?
Расход памяти смотрел через вторую консоль free -b
Память задействуется под буферизацию, криминала в этом нет.
alexey123_45
Aug 2 2017, 11:36
Просто мне кажется странным, что памяти расходуется примерно половина объема.
Нет ли по этой причине наползания на память другой программы?
А функция close не предполагает очистку буферов?
Цитата(alexey123_45 @ Aug 2 2017, 14:36)

Просто мне кажется странным, что памяти расходуется примерно половина объема.
Чем больше памяти отдается на кэширование, тем легче живется системе.
Цитата(alexey123_45 @ Aug 2 2017, 14:36)

Нет ли по этой причине наползания на память другой программы?
Только в случае неправильной конфигурации памяти: в какой-то момент расширяющийся кэш перекрывается
с памятью DSP. До этого момента все как бы в порядке.
Цитата(alexey123_45 @ Aug 2 2017, 14:36)

А функция close не предполагает очистку буферов?
Нет. В том и смысл кэширования, чтобы держать в неиспользуемой памяти относительно полезную нагрузку.
alexey123_45
Aug 2 2017, 11:54
Конфигурацию памяти я взял из документации, собственно там сказано, что linux эти адреса не использует. И в примерах SDK конфигурируется именно это адресное пространство. А если как-то принудительно очищать кэш или ограничить его размер?
Просто судя по статистике расхода памяти память в примере, описанном выше расходуется с 108 МБ до 21МБ.
Надо сопоставить, что передается ядру в mem=, и что прописано в конфигурации DSP/BIOS.
alexey123_45
Aug 2 2017, 12:13
Посмотрю, но все-таки по поводу расхода памяти. Просто мне надо писать несколько суток непрерывно, и крутится еще несколько программ, вот до какого момента будет кэшироваться?
Дисковый кэш - это не есть прямой расход памяти. Как только она понадобится "для дела", то освободится.
Цитата(alexey123_45 @ Aug 2 2017, 14:36)

А функция close не предполагает очистку буферов?
Это скорее очистка буфера не предполагает отдачу его памяти в системный пул. Может отдавать, а может и нет. В зависимости от реализации.
alexey123_45
Aug 2 2017, 12:52
Цитата
Надо сопоставить, что передается ядру в mem=, и что прописано в конфигурации DSP/BIOS.
Посмотрел - длины и начальные адреса совпадают
alexey123_45
Aug 4 2017, 06:39
Извиняюсь, невнимательно посчитал адреса, действительно в конфинурации DSPLINK зарезервирован диапазон адресов 0xC3E00000-0xC4000000, а в DSP 0xC3E00000-0xC4001000, видимо в этом причина
Цитата(alexey123_45 @ Aug 4 2017, 09:39)

Извиняюсь, невнимательно посчитал адреса, действительно в конфинурации DSPLINK зарезервирован диапазон адресов 0xC3E00000-0xC4000000, а в DSP 0xC3E00000-0xC4001000, видимо в этом причина
Так резервировать надо в одном файле. Например - командном файле линкёра. Чтобы не было подобных чудес.
alexey123_45
Aug 7 2017, 07:49
Я поправил адреса, но меня это не спасло. Я запустил пример из состава SDK, c ним такая же картина.
Выдается такое
BUG: Bad page state in process file_write pfn:c3f02
page:c04e4040 count:0 mapcount:0 mapping: (null) index:0x0
page flags: 0x200(arch_)
Backtrace:[<c0035730>] (dump_backtrace+0x0/0x114) from [<c0336dd0>] (dump_stack+0x18/0x1c)
r7:00000007
r6:c70ac000
r5:c04e4040
r4:c0458384
[<c0336db8>] (dump_stack+0x0/0x1c) from [<c0084e68>] (bad_page+0xd0/0xfc)
[<c0084d98>] (bad_page+0x0/0xfc) from [<c0086564>] (get_page_from_freelist+0x390/0x4c4)
r5:c04e4040
r4:c04e4040
[<c00861d4>] (get_page_from_freelist+0x0/0x4c4) from [<c008678c>] (__alloc_pages_nodemask+0xf4/0x51c)
[<c0086698>] (__alloc_pages_nodemask+0x0/0x51c) from [<c0080d00>] (find_or_create_page+0x40/0x88)
[<c0080cc0>] (find_or_create_page+0x0/0x88) from [<c00d7f10>] (__getblk+0x150/0x2e4)
[<c00d7dc0>] (__getblk+0x0/0x2e4) from [<c012a5bc>] (fat_mirror_bhs+0x70/0x118)
[<c012a54c>] (fat_mirror_bhs+0x0/0x118) from [<c012aca4>] (fat_alloc_clusters+0x314/0x370)
[<c012a990>] (fat_alloc_clusters+0x0/0x370) from [<c012db30>] (fat_get_block+0x138/0x278)
[<c012d9f8>] (fat_get_block+0x0/0x278) from [<c00d9578>] (__block_write_begin+0x1c4/0x4d4)
[<c00d93b4>] (__block_write_begin+0x0/0x4d4) from [<c00d9a28>] (block_write_begin+0x50/0x80)
[<c00d99d8>] (block_write_begin+0x0/0x80) from [<c00d9da0>] (cont_write_begin+0x348/0x394)
r6:02849000
r5:c70ac000
r4:00000000
[<c00d9a58>] (cont_write_begin+0x0/0x394) from [<c012dde4>] (fat_write_begin+0x5c/0x84)
[<c012dd88>] (fat_write_begin+0x0/0x84) from [<c007f5ac>] (generic_file_buffered_write+0xe8/0x230)
r7:00000000
r6:02849000
r5:000008ca
r4:000008ca
alexey123_45
Aug 18 2017, 07:23
Все разобрался: необходимо еще было переопределить параметр mem в bootargs
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.