← Documents Documentation/trace/rv/da_monitor_instrumentation.rst GitHub 원문 ↗

Linux 6.18.37 · Tracing

결정적 오토마타 계측

dot2k가 생성한 결정적 오토마타 monitor에서 kernel event를 model event로 변환하고 callback·초기 동기화·probe attach와 detach를 완성하는 방법을 설명합니다.

Source pathDocumentation/trace/rv/da_monitor_instrumentation.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

da_monitor_instrumentation.rst:1-171

dot2k가 생성한 결정적 오토마타 monitor에서 kernel event를 model event로 변환하고 callback·초기 동기화·probe attach와 detach를 완성하는 방법을 설명합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 Deterministic Automata Instrumentation
2 ======================================
3
4 The RV monitor file created by dot2k, with the name "$MODEL_NAME.c"
5 includes a section dedicated to instrumentation.
6
7 In the example of the wip.dot monitor created on [1], it will look like::
8
9 /*
10 * This is the instrumentation part of the monitor.
11 *
12 * This is the section where manual work is required. Here the kernel events
13 * are translated into model's event.
14 *
15 */
16 static void handle_preempt_disable(void *data, /* XXX: fill header */)
17 {
18 da_handle_event_wip(preempt_disable_wip);
19 }
20
21 static void handle_preempt_enable(void *data, /* XXX: fill header */)
22 {
23 da_handle_event_wip(preempt_enable_wip);
24 }
25
26 static void handle_sched_waking(void *data, /* XXX: fill header */)
27 {
28 da_handle_event_wip(sched_waking_wip);
29 }
30
31 static int enable_wip(void)
32 {
33 int retval;
34
35 retval = da_monitor_init_wip();
36 if (retval)
37 return retval;
38
39 rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_disable);
40 rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_enable);
41 rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_sched_waking);
42
43 return 0;
44 }
45
46 The comment at the top of the section explains the general idea: the
47 instrumentation section translates *kernel events* into the *model's
48 event*.
49
50 Tracing callback functions
51 --------------------------
52
53 The first three functions are the starting point of the callback *handler
54 functions* for each of the three events from the wip model. The developer
55 does not necessarily need to use them: they are just starting points.
56
57 Using the example of::
58
59 void handle_preempt_disable(void *data, /* XXX: fill header */)
60 {
61 da_handle_event_wip(preempt_disable_wip);
62 }
63
64 The preempt_disable event from the model connects directly to the
65 preemptirq:preempt_disable. The preemptirq:preempt_disable event
66 has the following signature, from include/trace/events/preemptirq.h::
67
68 TP_PROTO(unsigned long ip, unsigned long parent_ip)
69
70 Hence, the handle_preempt_disable() function will look like::
71
72 void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip)
73
74 In this case, the kernel event translates one to one with the automata
75 event, and indeed, no other change is required for this function.
76
77 The next handler function, handle_preempt_enable() has the same argument
78 list from the handle_preempt_disable(). The difference is that the
79 preempt_enable event will be used to synchronize the system to the model.
80
81 Initially, the *model* is placed in the initial state. However, the *system*
82 might or might not be in the initial state. The monitor cannot start
83 processing events until it knows that the system has reached the initial state.
84 Otherwise, the monitor and the system could be out-of-sync.
85
86 Looking at the automata definition, it is possible to see that the system
87 and the model are expected to return to the initial state after the
88 preempt_enable execution. Hence, it can be used to synchronize the
89 system and the model at the initialization of the monitoring section.
90
91 The start is informed via a special handle function, the
92 "da_handle_start_event_$(MONITOR_NAME)(event)", in this case::
93
94 da_handle_start_event_wip(preempt_enable_wip);
95
96 So, the callback function will look like::
97
98 void handle_preempt_enable(void *data, unsigned long ip, unsigned long parent_ip)
99 {
100 da_handle_start_event_wip(preempt_enable_wip);
101 }
102
103 Finally, the "handle_sched_waking()" will look like::
104
105 void handle_sched_waking(void *data, struct task_struct *task)
106 {
107 da_handle_event_wip(sched_waking_wip);
108 }
109
110 And the explanation is left for the reader as an exercise.
111
112 enable and disable functions
113 ----------------------------
114
115 dot2k automatically creates two special functions::
116
117 enable_$(MONITOR_NAME)()
118 disable_$(MONITOR_NAME)()
119
120 These functions are called when the monitor is enabled and disabled,
121 respectively.
122
123 They should be used to *attach* and *detach* the instrumentation to the running
124 system. The developer must add to the relative function all that is needed to
125 *attach* and *detach* its monitor to the system.
126
127 For the wip case, these functions were named::
128
129 enable_wip()
130 disable_wip()
131
132 But no change was required because: by default, these functions *attach* and
133 *detach* the tracepoints_to_attach, which was enough for this case.
134
135 Instrumentation helpers
136 -----------------------
137
138 To complete the instrumentation, the *handler functions* need to be attached to a
139 kernel event, at the monitoring enable phase.
140
141 The RV interface also facilitates this step. For example, the macro "rv_attach_trace_probe()"
142 is used to connect the wip model events to the relative kernel event. dot2k automatically
143 adds "rv_attach_trace_probe()" function call for each model event in the enable phase, as
144 a suggestion.
145
146 For example, from the wip sample model::
147
148 static int enable_wip(void)
149 {
150 int retval;
151
152 retval = da_monitor_init_wip();
153 if (retval)
154 return retval;
155
156 rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_enable);
157 rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_sched_waking);
158 rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_disable);
159
160 return 0;
161 }
162
163 The probes then need to be detached at the disable phase.
164
165 [1] The wip model is presented in::
166
167 Documentation/trace/rv/deterministic_automata.rst
168
169 The wip monitor is presented in::
170
171 Documentation/trace/rv/da_monitor_synthesis.rst
172

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

dot2k 생성 계측 골격

1-49

`dot2k`가 만드는 `$MODEL_NAME.c` 이름의 RV monitor 파일에는 계측 전용 절이 포함된다. 앞서 만든 `wip.dot` monitor의 생성 결과는 kernel event를 model event로 변환하는 callback과 enable 함수의 골격을 제공한다.

  /*
   * This is the instrumentation part of the monitor.
   *
   * This is the section where manual work is required. Here the kernel events
   * are translated into model's event.
   *
   */
  static void handle_preempt_disable(void *data, /* XXX: fill header */)
  {
	da_handle_event_wip(preempt_disable_wip);
  }

  static void handle_preempt_enable(void *data, /* XXX: fill header */)
  {
	da_handle_event_wip(preempt_enable_wip);
  }

  static void handle_sched_waking(void *data, /* XXX: fill header */)
  {
	da_handle_event_wip(sched_waking_wip);
  }

  static int enable_wip(void)
  {
	int retval;

	retval = da_monitor_init_wip();
	if (retval)
		return retval;

	rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_disable);
	rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_enable);
	rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_sched_waking);

	return 0;
  }

절 머리의 주석이 전체 원칙을 설명한다. 계측 절은 *kernel event*를 *model's event*로 번역하며, 이 부분에는 개발자의 수동 작업이 필요하다.

RV 계측 변환 경로
kernel eventtrace probe callback
handle_*()argument와 조건 해석
model eventda_handle_event_*()
automaton transition새 monitor state

kernel tracepoint를 callback으로 받아 결정적 오토마타의 event handler에 전달한다.

wip 생성 골격
구성생성 예개발자 작업
event handler`handle_preempt_disable()` 등tracepoint 원형과 변환 로직 채우기
monitor init`da_monitor_init_wip()`반환 오류 처리
probe attach`rv_attach_trace_probe()`실제 tracepoint 지정

dot2k가 제안하는 callback과 초기화 지점을 정리한다.

Deterministic Automata Instrumentation
======================================

The RV monitor file created by dot2k, with the name "$MODEL_NAME.c"
includes a section dedicated to instrumentation.

In the example of the wip.dot monitor created on [1], it will look like::

  /*
   * This is the instrumentation part of the monitor.
   *
   * This is the section where manual work is required. Here the kernel events
   * are translated into model's event.
   *
   */
  static void handle_preempt_disable(void *data, /* XXX: fill header */)
  {
	da_handle_event_wip(preempt_disable_wip);
  }

  static void handle_preempt_enable(void *data, /* XXX: fill header */)
  {
	da_handle_event_wip(preempt_enable_wip);
  }

  static void handle_sched_waking(void *data, /* XXX: fill header */)
  {
	da_handle_event_wip(sched_waking_wip);
  }

  static int enable_wip(void)
  {
	int retval;

	retval = da_monitor_init_wip();
	if (retval)
		return retval;

	rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_disable);
	rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_enable);
	rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_sched_waking);

	return 0;
  }

The comment at the top of the section explains the general idea: the
instrumentation section translates *kernel events* into the *model's
event*.

Tracing callback 함수

50-111

처음 세 함수는 wip model의 세 event에 대응하는 callback handler의 출발점이다. 반드시 그대로 사용할 필요는 없고 개발자가 완성할 수 있도록 제공되는 골격이다.

Using the example of::

 void handle_preempt_disable(void *data, /* XXX: fill header */)
 {
        da_handle_event_wip(preempt_disable_wip);
 }

model의 `preempt_disable` event는 `preemptirq:preempt_disable` kernel event와 직접 연결된다. `include/trace/events/preemptirq.h`에 정의된 이 tracepoint 원형은 다음과 같다.

  TP_PROTO(unsigned long ip, unsigned long parent_ip)

따라서 callback `handle_preempt_disable()`의 완성된 함수 원형은 다음과 같다.

  void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip)

이 경우 kernel event와 automaton event가 일대일로 대응하므로 함수 본문은 더 바꿀 필요가 없다.

다음 `handle_preempt_enable()`도 `handle_preempt_disable()`과 같은 argument 목록을 사용한다. 차이는 `preempt_enable` event를 system과 model의 동기화에 사용한다는 점이다.

model은 처음에 initial state에 놓이지만 실제 system이 initial state에 있는지는 알 수 없다. system이 initial state에 도달했음을 알기 전에는 monitor가 event 처리를 시작할 수 없다. 그렇지 않으면 monitor와 system의 상태가 어긋날 수 있다.

automaton 정의를 보면 `preempt_enable` 실행 뒤 system과 model이 initial state로 돌아올 것으로 예상된다. 따라서 monitoring 절을 초기화할 때 이 event를 동기화 지점으로 사용할 수 있다.

시작은 특별한 handler 함수 `da_handle_start_event_$(MONITOR_NAME)(event)`로 알린다. wip에서는 다음 호출을 사용한다.

  da_handle_start_event_wip(preempt_enable_wip);
  void handle_preempt_enable(void *data, unsigned long ip, unsigned long parent_ip)
  {
        da_handle_start_event_wip(preempt_enable_wip);
  }

마지막 `handle_sched_waking()`은 `struct task_struct *task`를 받고 `sched_waking_wip` event를 일반 event handler로 전달한다. 원문은 그 대응 이유의 설명을 독자 연습으로 남긴다.

  void handle_sched_waking(void *data, struct task_struct *task)
  {
        da_handle_event_wip(sched_waking_wip);
  }
model과 system 초기 동기화
model = initial statesystem state는 미확정
preempt_enable 관측system이 initial state에 도달
da_handle_start_event_wipmonitor 시작·동기화
후속 kernel eventsda_handle_event_wip로 처리

초기 상태가 확인되기 전에는 일반 event 처리를 시작하지 않는다.

Tracing callback functions
--------------------------

The first three functions are the starting point of the callback *handler
functions* for each of the three events from the wip model. The developer
does not necessarily need to use them: they are just starting points.

Using the example of::

 void handle_preempt_disable(void *data, /* XXX: fill header */)
 {
        da_handle_event_wip(preempt_disable_wip);
 }

The preempt_disable event from the model connects directly to the
preemptirq:preempt_disable. The preemptirq:preempt_disable event
has the following signature, from include/trace/events/preemptirq.h::

  TP_PROTO(unsigned long ip, unsigned long parent_ip)

Hence, the handle_preempt_disable() function will look like::

  void handle_preempt_disable(void *data, unsigned long ip, unsigned long parent_ip)

In this case, the kernel event translates one to one with the automata
event, and indeed, no other change is required for this function.

The next handler function, handle_preempt_enable() has the same argument
list from the handle_preempt_disable(). The difference is that the
preempt_enable event will be used to synchronize the system to the model.

Initially, the *model* is placed in the initial state. However, the *system*
might or might not be in the initial state. The monitor cannot start
processing events until it knows that the system has reached the initial state.
Otherwise, the monitor and the system could be out-of-sync.

Looking at the automata definition, it is possible to see that the system
and the model are expected to return to the initial state after the
preempt_enable execution. Hence, it can be used to synchronize the
system and the model at the initialization of the monitoring section.

The start is informed via a special handle function, the
"da_handle_start_event_$(MONITOR_NAME)(event)", in this case::

  da_handle_start_event_wip(preempt_enable_wip);

So, the callback function will look like::

  void handle_preempt_enable(void *data, unsigned long ip, unsigned long parent_ip)
  {
        da_handle_start_event_wip(preempt_enable_wip);
  }

Finally, the "handle_sched_waking()" will look like::

  void handle_sched_waking(void *data, struct task_struct *task)
  {
        da_handle_event_wip(sched_waking_wip);
  }

And the explanation is left for the reader as an exercise.

enable과 disable 함수

112-134

`dot2k`는 `enable_$(MONITOR_NAME)()`과 `disable_$(MONITOR_NAME)()`이라는 두 특별 함수를 자동 생성한다.

dot2k automatically creates two special functions::

  enable_$(MONITOR_NAME)()
  disable_$(MONITOR_NAME)()

각 함수는 monitor를 활성화하거나 비활성화할 때 호출된다. 실행 중인 system에 계측을 *attach*하고 *detach*하는 데 사용해야 하며, 개발자는 monitor 연결과 해제에 필요한 모든 동작을 해당 함수에 추가해야 한다.

wip의 함수 이름은 `enable_wip()`과 `disable_wip()`이다.

For the wip case, these functions were named::

 enable_wip()
 disable_wip()

이 사례에서는 기본 함수가 `tracepoints_to_attach`를 attach·detach하는 것만으로 충분했으므로 별도 변경이 필요하지 않았다.

monitor 수명 주기
enable_wip()automaton 초기화
tracepoint attachmonitor event 처리 시작
monitor activecallback 실행
disable_wip()tracepoint detach

enable과 disable 경계에서 계측 자원을 대칭적으로 연결하고 해제한다.

enable and disable functions
----------------------------

dot2k automatically creates two special functions::

  enable_$(MONITOR_NAME)()
  disable_$(MONITOR_NAME)()

These functions are called when the monitor is enabled and disabled,
respectively.

They should be used to *attach* and *detach* the instrumentation to the running
system. The developer must add to the relative function all that is needed to
*attach* and *detach* its monitor to the system.

For the wip case, these functions were named::

 enable_wip()
 disable_wip()

But no change was required because: by default, these functions *attach* and
*detach* the tracepoints_to_attach, which was enough for this case.

계측 helper

135-171

계측을 완성하려면 monitoring enable 단계에서 handler 함수를 kernel event에 연결해야 한다. RV interface는 이 작업을 위한 helper를 제공한다.

`rv_attach_trace_probe()` macro는 wip model event와 대응 kernel event를 연결한다. `dot2k`는 제안용으로 각 model event마다 enable 단계에 이 함수 호출을 자동 추가한다.

  static int enable_wip(void)
  {
        int retval;

        retval = da_monitor_init_wip();
        if (retval)
                return retval;

        rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_enable);
        rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_sched_waking);
        rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_disable);

        return 0;
  }

`da_monitor_init_wip()`에 실패하면 오류를 반환하고, 성공하면 각 callback을 tracepoint에 attach한다. disable 단계에서는 이 probe들을 반드시 detach해야 한다.

계측 helper 처리
da_monitor_init_wip()오류면 즉시 반환
rv_attach_trace_probe() × 3kernel event와 handler 연결
monitor 실행model event 전달
disable 단계모든 probe detach

초기화 성공 뒤에만 probe를 연결하고 disable 때 반대 순서로 해제한다.

원문은 wip model의 설명으로 `Documentation/trace/rv/deterministic_automata.rst`를, wip monitor의 설명으로 `Documentation/trace/rv/da_monitor_synthesis.rst`를 가리킨다. source path 표기는 원문 그대로 보존한다.

[1] The wip model is presented in::

  Documentation/trace/rv/deterministic_automata.rst

The wip monitor is presented in::

  Documentation/trace/rv/da_monitor_synthesis.rst
Instrumentation helpers
-----------------------

To complete the instrumentation, the *handler functions* need to be attached to a
kernel event, at the monitoring enable phase.

The RV interface also facilitates this step. For example, the macro "rv_attach_trace_probe()"
is used to connect the wip model events to the relative kernel event. dot2k automatically
adds "rv_attach_trace_probe()" function call for each model event in the enable phase, as
a suggestion.

For example, from the wip sample model::

  static int enable_wip(void)
  {
        int retval;

        retval = da_monitor_init_wip();
        if (retval)
                return retval;

        rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_enable);
        rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_sched_waking);
        rv_attach_trace_probe("wip", /* XXX: tracepoint */, handle_preempt_disable);

        return 0;
  }

The probes then need to be detached at the disable phase.

[1] The wip model is presented in::

  Documentation/trace/rv/deterministic_automata.rst

The wip monitor is presented in::

  Documentation/trace/rv/da_monitor_synthesis.rst