Skip to content

Commit

Permalink
Make subbuffer size configurable with Trace action (#51)
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher Wecht <cwecht@mailbox.org>
Co-authored-by: Christophe Bedard <christophe.bedard@apex.ai>
  • Loading branch information
cwecht and christophebedard committed Apr 14, 2023
1 parent 88be07d commit 67d3579
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,17 @@ def _check_trace_action(
tmpdir,
session_name: str = 'my-session-name',
events_ust: List[str] = ['ros2:*', '*'],
subbuffer_size_ust: int = 524288,
subbuffer_size_kernel: int = 1048576,
) -> None:
self.assertEqual(session_name, action.session_name)
self.assertEqual(tmpdir, action.base_path)
self.assertTrue(action.trace_directory.startswith(tmpdir))
self.assertEqual([], action.events_kernel)
self.assertEqual(events_ust, action.events_ust)
self.assertTrue(pathlib.Path(tmpdir).exists())
self.assertEqual(subbuffer_size_ust, action.subbuffer_size_ust)
self.assertEqual(subbuffer_size_kernel, action.subbuffer_size_kernel)

def test_action(self) -> None:
self.assertIsNone(os.environ.get('LD_PRELOAD'))
Expand All @@ -85,6 +89,8 @@ def test_action(self) -> None:
'ros2:*',
'*',
],
subbuffer_size_ust=524288,
subbuffer_size_kernel=1048576,
)
self._assert_launch_no_errors([action])
self._check_trace_action(action, tmpdir)
Expand All @@ -104,6 +110,8 @@ def test_action_frontend_xml(self) -> None:
base-path="{}"
events-kernel=""
events-ust="ros2:* *"
subbuffer-size-ust="524288"
subbuffer-size-kernel="1048576"
/>
</launch>
""".format(tmpdir)
Expand All @@ -130,6 +138,8 @@ def test_action_frontend_yaml(self) -> None:
base-path: {}
events-kernel: ""
events-ust: ros2:* *
subbuffer-size-ust: 524288
subbuffer-size-kernel: 1048576
""".format(tmpdir)
)

Expand Down Expand Up @@ -158,6 +168,8 @@ def test_action_context_per_domain(self) -> None:
'kernel': [],
'userspace': ['vpid', 'vtid'],
},
subbuffer_size_ust=524288,
subbuffer_size_kernel=1048576,
)
self._assert_launch_no_errors([action])
self._check_trace_action(action, tmpdir)
Expand Down Expand Up @@ -202,6 +214,8 @@ def test_action_substitutions(self) -> None:
TextSubstitution(text='vtid'),
],
},
subbuffer_size_ust=524288,
subbuffer_size_kernel=1048576,
)
self._assert_launch_no_errors([session_name_arg, action])
self._check_trace_action(action, tmpdir)
Expand Down Expand Up @@ -234,6 +248,8 @@ def test_action_ld_preload(self) -> None:
'lttng_ust_pthread:*',
'lttng_ust_dl:*',
],
subbuffer_size_ust=524288,
subbuffer_size_kernel=1048576,
)
node_ping_action = Node(
package='test_tracetools',
Expand Down
32 changes: 31 additions & 1 deletion tracetools_launch/tracetools_launch/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ def __init__(
context_fields:
Union[Iterable[SomeSubstitutionsType], Dict[str, Iterable[SomeSubstitutionsType]]]
= names.DEFAULT_CONTEXT,
subbuffer_size_ust: int = 8 * 4096,
subbuffer_size_kernel: int = 32 * 4096,
**kwargs,
) -> None:
"""
Expand All @@ -139,6 +141,10 @@ def __init__(
if it's a list or a set, the context fields are enabled for both kernel and userspace;
if it's a dictionary: { domain type string -> context fields list }
with the domain type string being either 'kernel' or 'userspace'
:param subbuffer_size_ust: the size of the subbuffers (defaults to 8 times the usual page
size)
:param subbuffer_size_kernel: the size of the subbuffers (defaults to 32 times the usual
page size)
"""
super().__init__(**kwargs)
self.__logger = logging.get_logger(__name__)
Expand All @@ -157,6 +163,8 @@ def __init__(
if isinstance(context_fields, dict) \
else [normalize_to_list_of_substitutions(field) for field in context_fields]
self.__ld_preload_actions: List[LdPreload] = []
self.__subbuffer_size_ust = subbuffer_size_ust
self.__subbuffer_size_kernel = subbuffer_size_kernel

@property
def session_name(self):
Expand All @@ -182,6 +190,14 @@ def events_kernel(self):
def context_fields(self):
return self.__context_fields

@property
def subbuffer_size_ust(self):
return self.__subbuffer_size_ust

@property
def subbuffer_size_kernel(self):
return self.__subbuffer_size_kernel

@classmethod
def _parse_cmdline(
cls,
Expand Down Expand Up @@ -270,6 +286,14 @@ def parse(cls, entity: Entity, parser: Parser):
if context_fields is not None:
kwargs['context_fields'] = cls._parse_cmdline(context_fields, parser) \
if context_fields else []
subbuffer_size_ust = entity.get_attr(
'subbuffer-size-ust', data_type=int, optional=True, can_be_str=False)
if subbuffer_size_ust is not None:
kwargs['subbuffer_size_ust'] = subbuffer_size_ust
subbuffer_size_kernel = entity.get_attr(
'subbuffer-size-kernel', data_type=int, optional=True, can_be_str=False)
if subbuffer_size_kernel is not None:
kwargs['subbuffer_size_kernel'] = subbuffer_size_kernel

return cls, kwargs

Expand Down Expand Up @@ -380,6 +404,8 @@ def _setup(self) -> bool:
ros_events=self.__events_ust,
kernel_events=self.__events_kernel,
context_fields=self.__context_fields,
subbuffer_size_ust=self.__subbuffer_size_ust,
subbuffer_size_kernel=self.__subbuffer_size_kernel,
)
if self.__trace_directory is None:
return False
Expand All @@ -388,6 +414,8 @@ def _setup(self) -> bool:
self.__logger.debug(f'Kernel events: {self.__events_kernel}')
self.__logger.debug(f'Context fields: {self.__context_fields}')
self.__logger.debug(f'LD_PRELOAD: {self.__ld_preload_actions}')
self.__logger.debug(f'UST subbuffer size: {self.__subbuffer_size_ust}')
self.__logger.debug(f'Kernel subbuffer size: {self.__subbuffer_size_kernel}')
return True

def _destroy(self, event: Event, context: LaunchContext) -> None:
Expand All @@ -403,5 +431,7 @@ def __repr__(self):
f'events_ust={self.__events_ust}, '
f'events_kernel={self.__events_kernel}, '
f'context_fields={self.__context_fields}, '
f'ld_preload_actions={self.__ld_preload_actions})'
f'ld_preload_actions={self.__ld_preload_actions}, '
f'subbuffer_size_ust={self.__subbuffer_size_ust}, '
f'subbuffer_size_kernel={self.__subbuffer_size_kernel})'
)
13 changes: 8 additions & 5 deletions tracetools_trace/tracetools_trace/tools/lttng_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ def setup(
context_fields: Union[List[str], Set[str], Dict[str, List[str]]] = DEFAULT_CONTEXT,
channel_name_ust: str = 'ros2',
channel_name_kernel: str = 'kchan',
subbuffer_size_ust: int = 8 * 4096,
subbuffer_size_kernel: int = 32 * 4096,
) -> Optional[str]:
"""
Set up LTTng session, with events and context.
Expand All @@ -91,6 +93,10 @@ def setup(
if it's a dictionary: { domain type string -> context fields list }
:param channel_name_ust: the UST channel name
:param channel_name_kernel: the kernel channel name
:param subbuffer_size_ust: the size of the subbuffers for userspace events (defaults to 8 times
the usual page size)
:param subbuffer_size_kernel: the size of the subbuffers for kernel events (defaults to 32
times the usual page size, since there can be way more kernel events than UST events)
:return: the full path to the trace directory, or `None` if initialization failed
"""
# Check if there is a session daemon running
Expand Down Expand Up @@ -142,10 +148,9 @@ def setup(
channel_ust.name = channel_name_ust
# Discard, do not overwrite
channel_ust.attr.overwrite = 0
# 2 sub-buffers of 8 times the usual page size
# We use 2 sub-buffers because the number of sub-buffers is pointless in discard mode,
# and switching between sub-buffers introduces noticeable CPU overhead
channel_ust.attr.subbuf_size = 8 * 4096
channel_ust.attr.subbuf_size = subbuffer_size_ust
channel_ust.attr.num_subbuf = 2
# Ignore switch timer interval and use read timer instead
channel_ust.attr.switch_timer_interval = 0
Expand All @@ -162,9 +167,7 @@ def setup(
channel_kernel.name = channel_name_kernel
# Discard, do not overwrite
channel_kernel.attr.overwrite = 0
# 2 sub-buffers of 32 times the usual page size, since
# there can be way more kernel events than UST events
channel_kernel.attr.subbuf_size = 32 * 4096
channel_kernel.attr.subbuf_size = subbuffer_size_kernel
channel_kernel.attr.num_subbuf = 2
# Ignore switch timer interval and use read timer instead
channel_kernel.attr.switch_timer_interval = 0
Expand Down

0 comments on commit 67d3579

Please sign in to comment.