Estou trabalhando em uma aplicação C++ no Ubuntu 20.04 que usa PCIe DMA para transferir dados de um buffer de espaço do usuário para o hardware. O buffer é mapeado para uma região fixa de 1K de memória física por meio de uma biblioteca personalizada (plib->copyDataToBuffer). Depois de chamar fork() e executar um processo filho (que apenas chama um programa externo e sai), notei que as gravações subsequentes no buffer pelo processo pai não são refletidas na memória física — o kernel ainda vê os dados antigos de antes da bifurcação.
Detalhes principais: O buffer de 1K é mapeado especificamente para DMA; ele é fixado e mapeado para um endereço físico conhecido.
Antes do fork(), uma chamada para plib->copyDataToBuffer atualiza corretamente a memória física.
Após fork(), o processo pai chama plib->copyDataToBuffer novamente com novos dados, e msync retorna sucesso, mas o conteúdo da memória física permanece inalterado.
O processo filho não toca no buffer; ele apenas executa um comando não relacionado via execvp.
Minhas suposições e preocupações: fork() causa COW (Copy-on-Write), mas como somente o pai grava no buffer, eu esperava que o conteúdo atualizado refletisse na memória física.
O comportamento do COW ou o remapeamento de memória pós-bifurcação podem estar interferindo nas regiões de memória mapeadas por DMA?
Confirmei que plib->copyDataToBuffer executa a gravação corretamente de uma perspectiva de software, mas o conteúdo real da memória física (verificado a partir do espaço do kernel) permanece obsoleto.
Pergunta: Por que a memória física que dá suporte ao meu buffer DMA retém dados obsoletos após um fork() + exec em um processo filho, mesmo que o pai grave novos dados depois?
Quais são as melhores práticas para garantir atualizações consistentes de memória física para buffers DMA em chamadas fork()?