Hyper-V e Ping Negativo

Por Alessandro Gonçalves

Acabei de trabalhar em um incidente bem interessante, onde o cliente apontava problemas de conectividade de uma máquina virtual com a rede externa e o mais interessante... A resposta de um ping retornava um resultado NEGATIVO.

Como pode a resposta do ping aparecer deste jeito:

 

Reply from 192.168.0.1: bytes=32 time<1ms TTL=127

Reply from 192.168.0.1: bytes=32 time<1ms TTL=127

Reply from 192.168.0.1: bytes=32 time<1ms TTL=127

Reply from 192.168.0.1: bytes=32 time<1ms TTL=127

Reply from 192.168.0.1: bytes=32 time=120ms TTL=127

Reply from 192.168.0.1: bytes=32 time=-118ms TTL=127

Reply from 192.168.0.1: bytes=32 time=-118ms TTL=127

Reply from 192.168.0.1: bytes=32 time=-118ms TTL=127

Reply from 192.168.0.1: bytes=32 time=-118ms TTL=127

Reply from 192.168.0.1: bytes=32 time=-118ms TTL=127

Reply from 192.168.0.1: bytes=32 time=-118ms TTL=127

 

Um comportamento muito estranho diria eu... Como pode uma resposta de ping retornar como time= -118ms.

A causa deste fenômeno está no TSC (Time Stamp Counters). Essas estruturas do processador são usadas como fonte de manutenção de tempo para alguns tipos de operação do sistema operacional, como operações de rede. Em uma situação de multicore/multiprocessor podemos encontrar uma falta de sincronismo entre estas estruturas (TSC drift) levando a problemas de comunicação de rede e monitoramento de performance, pois cada core terá um Time Stamp próprio.

Além do comportamento inusitado do ping também podemos ter eventos como:

Type: Error
Server: SERVER01
Event ID: 1054
Source: Userenv
User: NT AUTHORITY\SYSTEM
Description: Windows cannot obtain the domain controller name for your computer network. (An unexpected network error occurred.) Group Policy processing aborted.

Esta situação pode ocorrer em máquinas físicas, mas é mais acentuada em máquinas virtuais com múltiplos processadores.

Basicamente isso ocorre em processadores mais avançados com dispositivos de power management, onde há o ajuste independente entre o performance state (P-state) e o power state (C-state). Esse ajuste pode levar a taxa de incremento do TSC em cada core seja modificada de maneira diferente.

Como cada core possui um valor independente para o TSC , calcula-se a diferença entre os valores e supõe-se que a diferença seja constante. O fenômeno de "TSC drift" ocorre quando essa diferença não é mais uma constante e começa a variar, neste ponto dizemos que os cores não estão mais "sincronizados".

Por isso aplicações devem evitar utilizar TSC diretamente - através da instrução RDTSC - para funções de time keeping e utilizar chamadas do sistema operacional para tal. Ao utilizar TSC diretamente aplicações não estão protegidas contra TSC drift e não se beneficiam da lógica do sistema operacional para evitar esses problemas. Além disso aplicações que utilizam a função RDTSC podem experimentar problemas de performance em sistemas multicore, especialmente games.

Em relação ao Hyper-V, esse problema tem se manifestado em máquinas virtuais multiprocessados devido ao fato de o TSC ser virtualizado para cada processador virtual, e geralmente o valor do TSC continua a ser incrementado enquanto o processador virtual está suspenso. A virtualização do TSC é implementada através de um offset adicionado ao TSC do processador lógico. O hypervisor tentará prevenir o valor de se alterar quando o processador virtual for agendado a rodar em diferentes processadores lógicos, porém não pode evitar de que a taxa de alteração de TSC seja modificada devido a alterações no C-state e P-state do processador.

Quando enfrentamos essa situação em uma máquina virtual com múltiplos processadores, devemos fazer com que o sistema operacional utilize um modelo de timekeeping diferente. Atingimos esse objetivo ao adicionar o seguinte switch ao boot.ini - /usepmtimer. Essa opção faz com que o sistema operacional utilize o PM_TIMER ao invés de TSC como modo de timekeeping.

Então apenas para recapitular, sempre temos que analisar o custo benefício de termos máquinas virtuais com múltiplos processadores. Se tivermos máquinas virtuais com SMP e enfrentando problemas de acesso a rede, o teste do ping negativo pode apontar o problema de TSC drift e a solução passa por utilizarmos uma função de timekeeping diferente ao adicionar no boot.ini o switch /usepmtimer .

Aqui estão alguns links com artigos relacionados a essa situação de TSC drift:

  • 938448 A Windows Server 2003-based server may experience time-stamp counter drift if the server uses dual-core AMD Opteron processors or multiprocessor AMD Opteron processors
  • 895980 Programs that use the QueryPerformanceCounter function may perform poorly in Windows Server 2000, in Windows Server 2003, and in Windows
  • 896256 Computers that are running Windows XP Service Pack 2 and that are equipped with multiple processors that support processor power management features may experience decreased performance
  • 909944 Game performance may be poor on a Windows XP-based computer that is using a dual-core processor
  • 931279 SQL Server timing values may be incorrect when you use utilities or technologies that change CPU frequencies
  • Negative ping times in Windows VM's - whats up? (blog)
  • Explanation for the USEPMTIMER switch in the boot.ini (blog)