Alocação de troca do Solaris com memória compartilhada mlocked

3

Estou tendo dificuldades em entender como as alocações de troca do Solaris 10 x86 funcionam no presença de mlock ed share memory.

Eu escrevi um pequeno programa que:

  • Obtém um segmento 1G SHM ( shmget )
  • Anexa ao processo ( shmat )
  • Bloqueia uma parte disso ( mlock , a primeira rodada não bloqueia nada, depois 512M, depois a coisa toda)
  • Escreva na última e na primeira página da região do SHM
  • Escreve progressivamente no segmento inteiro
  • Liberar o bloqueio (se houver)
  • Desanexa e limpa.

Imprime os valores de swap -s em MB após cada ação.

A saída é a seguinte:

  • Round 1, no mlock : (os valores à direita são relativos à primeira leitura)
pid:    2221    mlock size:     0
header:      alloc  resvd   used   free [+/-  alloc  resvd   used   free]
  init:        325    130    456   2873 [+/-      0      0      0      0]
shmget:        326   1154   1480   1849 [+/-      1   1024   1024  -1024]
 shmat:        326   1154   1480   1849 [+/-      1   1024   1024  -1024]
touchE:        326   1154   1480   1849 [+/-      1   1024   1024  -1024]
touchS:        326   1154   1480   1849 [+/-      1   1024   1024  -1024]
  set1:        582    898   1480   1848 [+/-    257    768   1024  -1025]
  set2:        838    642   1480   1848 [+/-    513    512   1024  -1025]
  set3:       1093    386   1480   1847 [+/-    768    256   1024  -1026]
  set4:       1350    130   1480   1847 [+/-   1025      0   1024  -1026]
   set:       1350    130   1480   1847 [+/-   1025      0   1024  -1026]
 shmdt:       1350    130   1480   1847 [+/-   1025      0   1024  -1026]
shmctl:        326    130    456   2871 [+/-      1      0      0     -2]

Aqui tudo bem. A coluna free foi no máximo ~ 1G menor do que na inicialização.

  • Round 2, mlock os primeiros 512M do segmento compartilhado:
 pid:    2221    mlock size:     536870912
 header:      alloc  resvd   used   free [+/-  alloc  resvd   used   free]
   init:        326    130    456   2871 [+/-      0      0      0      0]
 shmget:        326   1154   1480   1847 [+/-      0   1024   1024  -1024]
  shmat:        326   1154   1480   1847 [+/-      0   1024   1024  -1024]
  mlock:        838    642   1480   1334 [+/-    512    512   1024  -1537] <<<<
 touchE:        838    642   1480   1334 [+/-    512    512   1024  -1537]
 touchS:        838    642   1480   1334 [+/-    512    512   1024  -1537]
   set1:        838    642   1480   1334 [+/-    512    512   1024  -1537]
   set2:        838    642   1480   1334 [+/-    512    512   1024  -1537]
   set3:       1094    386   1480   1334 [+/-    768    256   1024  -1537]
   set4:       1350    130   1480   1334 [+/-   1024      0   1024  -1537]
    set:       1350    130   1480   1334 [+/-   1024      0   1024  -1537] <<<<
munlock:       1350    130   1480   1846 [+/-   1024      0   1024  -1025]
  shmdt:       1350    130   1480   1847 [+/-   1024      0   1024  -1024]
 shmctl:        326    130    456   2871 [+/-      0      0      0      0]
  • Round 3, mlock todo o segmento:
 pid:    2221    mlock size:     1073741824
 header:      alloc  resvd   used   free [+/-  alloc  resvd   used   free]
   init:        326    130    456   2871 [+/-      0      0      0      0]
 shmget:        326   1154   1480   1847 [+/-      0   1024   1024  -1024]
  shmat:        326   1154   1480   1847 [+/-      0   1024   1024  -1024]
  mlock:       1350    130   1480    822 [+/-   1024      0   1024  -2049] <<<<
 touchE:       1350    130   1480    822 [+/-   1024      0   1024  -2049]
 touchS:       1350    130   1480    822 [+/-   1024      0   1024  -2049]
   set1:       1350    130   1480    822 [+/-   1024      0   1024  -2049]
   set2:       1350    130   1480    822 [+/-   1024      0   1024  -2049]
   set3:       1350    130   1480    822 [+/-   1024      0   1024  -2049]
   set4:       1350    130   1480    822 [+/-   1024      0   1024  -2049]
    set:       1350    130   1480    822 [+/-   1024      0   1024  -2049] <<<<
munlock:       1350    130   1480   1846 [+/-   1024      0   1024  -1025]
  shmdt:       1350    130   1480   1847 [+/-   1024      0   1024  -1024]
 shmctl:        326    130    456   2871 [+/-      0      0      0      0]

Nas últimas duas rodadas, a coluna free desce um direito extra de 512M ou 1G após o mlock , mas antes que qualquer página seja realmente tocada. Esta "contabilidade dupla" desaparece após a chamada munlock .

Alguém pode explicar esse comportamento? mlocked páginas são reservadas na memória RAM real ou na loja de apoio ou algo parecido?

SunOS myhost 5.10 Generic_142910-17 i86pc i386 i86pc
    
por Mat 14.08.2011 / 20:02

1 resposta

3

Se você usar o DISM , certifique-se de ter muito espaço na sua troca.

Quando você shmat um membro do SHM segmento com SHM_SHARE_MMU (que não é o padrão), você obtém um segmento ISM , que é automaticamente bloqueado na memória (não paginável). O custo desse mapeamento, na memória virtual, é apenas o tamanho da região SHM alocada. (Como não pode ser paginado, não é necessário reservar swap). mlock não tem efeito nessas páginas, elas já estão bloqueadas.

Se você anexar o segmento com SHM_PAGEABLE ou sem atributo, você receberá um segmento DISM . Aquele é pagável. O custo inicial é o mesmo. Mas, se você mlock dessa memória, a zona mlock ed será contabilizada novamente para seu uso de RAM bloqueado. Portanto, o custo da memória virtual é (whole mapping + mlocked zone) .

É como se, com SHM_PAGEABLE , o mapeamento fosse criado "in swap" e as zonas que você bloqueia exigem reserva adicional "in ram" (o armazenamento de apoio para essas páginas bloqueadas não é liberado ou não reservado).

Então, o que eu estava vendo é normal, como projetado.

Algumas informações sobre isso podem ser encontradas em SGA Dynamic SGA do banco de dados Oracle no Oracle Solaris com DISM (280k PDF). Trecho:

Since DISM memory is not automatically locked, swap space must be allocated for the whole segment. [...]. But it could become a problem if system administrators are unaware of the need to provide swap space for DISM.

(Eu era um desses administradores inconscientes ...)

Dica: use pmap -xa para ver que tipo de segmento você tem.

  • ISM :
 Address  Kbytes     RSS    Anon  Locked Mode   Mapped File
...
80000000 1048576 1048576 1048576 1048576 rwxsR    [ ism shmid=0x16 ]
                                             ^      ^^^

Observe o R nos bits de modo: nenhuma reserva para este mapeamento.

  • DISM :
 Address  Kbytes     RSS    Anon  Locked Mode   Mapped File
...
80000000 1048576 1048576 1048576 1048576 rwxs-    [ dism shmid=0xa ]
                                             ^      ^^^^
    
por 15.08.2011 / 12:15