Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Race on dlog_flush_vm_buffer #28

Closed
efenniht opened this issue Aug 18, 2019 · 8 comments
Closed

Race on dlog_flush_vm_buffer #28

efenniht opened this issue Aug 18, 2019 · 8 comments

Comments

@efenniht
Copy link
Collaborator

현재 이 함수의 구현은 writer의 락이 함수가 끝날 때까지 잡혀있는 것을 전제로 하고 있는데 이것은 잘못된 가정입니다. 다음과 같이 고쳐야 합니다.

/// Send the contents of the given VM's log buffer to the log, preceded by the
/// VM ID and followed by a newline.
pub fn dlog_flush_vm_buffer(id: spci_vm_id_t, buffer: &mut [c_char]) {
    use core::fmt::Write;
    let mut writer = WRITER.lock();

    writer.write_str("VM ");
    writer.write_fmt(format_args!("{}", id));
    writer.write_str(": ");

    for c in buffer.iter_mut() {
        writer.write_char(*c as char);
        *c = '\0' as u32 as u8;
    }

    writer.write_char('\n');
}
@efenniht
Copy link
Collaborator Author

한편 이걸 고쳐도 race가 남아 있어서 뭔가 했는데, 테스트 코드에서 디버깅 로그를 출력할 때 사용하는 api_debug_log 함수는 락을 한 글자마다 겁니다. 이것은 로그 버퍼에 대한 락을 거는 api를 제공하거나 log_buffer를 VCPU마다 두거나 둘 중 하나의 방법으로 해결해야 합니다.

@efenniht
Copy link
Collaborator Author

추후에 #14 와 같이 해결하기.

@efenniht
Copy link
Collaborator Author

참고: 원래 코드에서는 락이 제대로 걸려 있었다

@jeehoonkang
Copy link
Member

  • 죄송합니다...
  • race는 어떻게 찾으셨나요? 디버깅 메소돌로지가 궁금합니다..

@efenniht
Copy link
Collaborator Author

  • 제가 잘못 옮긴 코드입니다;; 저의 잘못입니다...
  • VCpuexecution_lock 또한 SpinLock<VCpuState> 처럼 만들고 있었는데요. 실패한 테스트의 로그에 출력 당시의 race가 남아 있어서 알게 되었습니다.

@efenniht
Copy link
Collaborator Author

Closes as #27 is closed. api_debug_log가 한 글자마다 락을 거는 것은 생각해보면 vm 내부에서 알아서 synchronize 할 일입니다. Hafnium 버그라고 보기에는 어려운 듯.

@jeehoonkang
Copy link
Member

제가 마지막 코멘트를 잘 이해 못했습니다... 혹시 좀더 자세히 설명 요청드려도 될까요?

@efenniht
Copy link
Collaborator Author

  • 테스트 코드와 Hafnium 코드 모두 동일한 dlog를 사용합니다.
  • dlog 함수 안에서 호출하는 plat_console_putchar 가 테스트 코드에서는 api_debug_log를 호출하고 Hafnium 내부에서는 UART에 씁니다.
  • 그리고 dlog 함수 중에는 lock함수로 락을 거는데, 이 lock 함수는 테스트 코드에서는 락을 걸지 않습니다.
  • 그래서 테스트 코드에서는 dlog가 다수의 vcpu에서 호출될 경우 race가 생깁니다.

그런데 테스트 코드에서 두 vcpu 사이를 동기화하는 것은 복잡한 일이므로 그냥 이렇게 만든 듯 합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants