public inbox for kdevops@lists.linux.dev
 help / color / mirror / Atom feed
From: Luis Chamberlain <mcgrof@kernel.org>
To: Chuck Lever <cel@kernel.org>, Daniel Gomez <da.gomez@kruces.com>,
	kdevops@lists.linux.dev
Cc: Luis Chamberlain <mcgrof@kernel.org>, Claude AI <noreply@anthropic.com>
Subject: [PATCH 23/23] reboot-limit: add kexec comparison feature
Date: Mon, 11 Aug 2025 15:24:50 -0700	[thread overview]
Message-ID: <20250811222452.2213071-24-mcgrof@kernel.org> (raw)
In-Reply-To: <20250811222452.2213071-1-mcgrof@kernel.org>

Add comprehensive support for comparing regular reboots vs kexec reboots
in the reboot-limit workflow. This enables users to test both reboot
types sequentially and compare their performance characteristics.

New defconfigs:
- reboot-limit-kexec: Configure for kexec-only testing
- reboot-limit-compare: Configure for comparison mode testing

New Kconfig options:
- REBOOT_LIMIT_TYPE_COMPARE_BOTH: Test both regular and kexec reboots
- REBOOT_LIMIT_DATA_REGULAR/KEXEC: Separate data paths for comparison

Workflow enhancements:
- Sequential testing: regular reboot first, then kexec
- Separate statistics collection for each reboot type
- Enhanced data organization with regular/ and kexec/ subdirectories

Analysis improvements:
- Automatic comparison mode detection
- Side-by-side performance analysis
- Speedup calculation and visualization
- Comprehensive comparative graphs showing both boot types

Usage:
  make defconfig-reboot-limit-compare
  make bringup
  make reboot-limit-tests
  make reboot-limit-graph

Generated-by: Claude AI
Signed-off-by: Claude AI <noreply@anthropic.com>
---
 defconfigs/reboot-limit-compare               |  36 ++
 defconfigs/reboot-limit-kexec                 |  32 ++
 playbooks/roles/gen_hosts/tasks/main.yml      |  13 +
 playbooks/roles/gen_hosts/templates/hosts.j2  |  55 ++-
 playbooks/roles/gen_nodes/tasks/main.yml      |  32 ++
 .../reboot-limit/tasks/do-reboot-compare.yml  | 126 +++++++
 .../roles/reboot-limit/tasks/do-reboot.yml    |  28 +-
 .../reboot-limit/tasks/handle-reboot-data.yml |  94 ++++++
 playbooks/roles/reboot-limit/tasks/main.yml   |  84 ++++-
 .../demos/reboot-limit/analyze_results.py     | 314 +++++++++++++++++-
 workflows/demos/reboot-limit/Kconfig          |  31 ++
 workflows/demos/reboot-limit/Makefile         |  13 +
 12 files changed, 828 insertions(+), 30 deletions(-)
 create mode 100644 defconfigs/reboot-limit-compare
 create mode 100644 defconfigs/reboot-limit-kexec
 create mode 100644 playbooks/roles/reboot-limit/tasks/do-reboot-compare.yml
 create mode 100644 playbooks/roles/reboot-limit/tasks/handle-reboot-data.yml

diff --git a/defconfigs/reboot-limit-compare b/defconfigs/reboot-limit-compare
new file mode 100644
index 00000000..7f88cf02
--- /dev/null
+++ b/defconfigs/reboot-limit-compare
@@ -0,0 +1,36 @@
+# Demo defconfig for reboot-limit workflow with comparison testing
+#
+# This enables the reboot-limit workflow to compare regular reboots
+# vs kexec reboots with separate performance monitoring and analysis.
+
+# Enable workflows and reboot-limit workflow
+CONFIG_WORKFLOWS=y
+CONFIG_WORKFLOWS_TESTS=y
+CONFIG_WORKFLOWS_TESTS_DEMOS=y
+CONFIG_WORKFLOWS_DEDICATED_WORKFLOW=y
+CONFIG_WORKFLOWS_REBOOT_LIMIT=y
+
+# Enable baseline and dev testing
+CONFIG_KDEVOPS_BASELINE_AND_DEV=y
+
+# Enable data collection for analysis
+CONFIG_REBOOT_LIMIT_ENABLE_DATA_COLLECTION=y
+CONFIG_REBOOT_LIMIT_ENABLE_SYSTEMD_ANALYZE=y
+
+# Enable loop testing for continuous operation
+CONFIG_REBOOT_LIMIT_ENABLE_LOOP=y
+CONFIG_REBOOT_LIMIT_LOOP_STEADY_STATE_GOAL=100
+
+# Set a reasonable number of reboots per test run
+CONFIG_REBOOT_LIMIT_BOOT_MAX=100
+
+# Use comparison mode to test both regular and kexec reboots
+CONFIG_REBOOT_LIMIT_TYPE_COMPARE_BOTH=y
+
+# We'll build our kernel
+CONFIG_WORKFLOW_LINUX_CUSTOM=y
+CONFIG_BOOTLINUX=y
+CONFIG_BOOTLINUX_9P=y
+
+# Enable A/B testing with different kernel references
+CONFIG_BOOTLINUX_AB_DIFFERENT_REF=y
diff --git a/defconfigs/reboot-limit-kexec b/defconfigs/reboot-limit-kexec
new file mode 100644
index 00000000..e6416a2f
--- /dev/null
+++ b/defconfigs/reboot-limit-kexec
@@ -0,0 +1,32 @@
+# Demo defconfig for reboot-limit workflow with kexec
+#
+# This enables the reboot-limit workflow for system stability testing
+# through continuous kexec reboots with performance monitoring.
+
+# Enable workflows and reboot-limit workflow
+CONFIG_WORKFLOWS=y
+CONFIG_WORKFLOWS_TESTS=y
+CONFIG_WORKFLOWS_TESTS_DEMOS=y
+CONFIG_WORKFLOWS_DEDICATED_WORKFLOW=y
+CONFIG_WORKFLOWS_REBOOT_LIMIT=y
+
+# Enable data collection for analysis
+CONFIG_REBOOT_LIMIT_ENABLE_DATA_COLLECTION=y
+CONFIG_REBOOT_LIMIT_ENABLE_SYSTEMD_ANALYZE=y
+
+# Enable loop testing for continuous operation
+CONFIG_REBOOT_LIMIT_ENABLE_LOOP=y
+CONFIG_REBOOT_LIMIT_LOOP_STEADY_STATE_GOAL=100
+
+# Set a reasonable number of reboots per test run
+CONFIG_REBOOT_LIMIT_BOOT_MAX=100
+
+# Use kexec reboot method for faster rebooting
+CONFIG_REBOOT_LIMIT_TYPE_SYSTEMD_KEXEC=y
+
+# Enable baseline and development nodes for A/B testing
+CONFIG_KDEVOPS_BASELINE_AND_DEV=y
+
+# Storage configuration
+CONFIG_LIBVIRT_EXTRA_STORAGE_DRIVE_SIZE_SET_CUSTOM=y
+CONFIG_LIBVIRT_EXTRA_STORAGE_DRIVE_SIZE=20
diff --git a/playbooks/roles/gen_hosts/tasks/main.yml b/playbooks/roles/gen_hosts/tasks/main.yml
index 0a742d89..15c1ddbb 100644
--- a/playbooks/roles/gen_hosts/tasks/main.yml
+++ b/playbooks/roles/gen_hosts/tasks/main.yml
@@ -351,6 +351,19 @@
     - kdevops_workflow_enable_mmtests
     - ansible_hosts_template.stat.exists
 
+- name: Generate the Ansible hosts file for a dedicated reboot-limit setup
+  tags: [ 'hosts' ]
+  template:
+    src: "{{ kdevops_hosts_template }}"
+    dest: "{{ ansible_cfg_inventory }}"
+    force: yes
+    trim_blocks: True
+    lstrip_blocks: True
+  when:
+    - kdevops_workflows_dedicated_workflow
+    - workflows_reboot_limit
+    - ansible_hosts_template.stat.exists
+
 - name: Verify if final host file exists
   stat:
     path: "{{ ansible_cfg_inventory }}"
diff --git a/playbooks/roles/gen_hosts/templates/hosts.j2 b/playbooks/roles/gen_hosts/templates/hosts.j2
index ca6adcfc..f89fae48 100644
--- a/playbooks/roles/gen_hosts/templates/hosts.j2
+++ b/playbooks/roles/gen_hosts/templates/hosts.j2
@@ -6,52 +6,87 @@ Each workflow which has its own custom ansible host file generated should use
 its own jinja2 template file and define its own ansible task for its generation.
 #}
 {% if kdevops_workflows_dedicated_workflow %}
+{% if workflows_reboot_limit %}
+[all]
+localhost ansible_connection=local
+{{ kdevops_host_prefix }}-reboot-limit
+{% if kdevops_baseline_and_dev %}
+{{ kdevops_host_prefix }}-reboot-limit-dev
+{% endif %}
+
+[all:vars]
+ansible_python_interpreter = "{{ kdevops_python_interpreter }}"
+
+[baseline]
+{{ kdevops_host_prefix }}-reboot-limit
+
+[baseline:vars]
+ansible_python_interpreter = "{{ kdevops_python_interpreter }}"
+
+{% if kdevops_baseline_and_dev %}
+[dev]
+{{ kdevops_host_prefix }}-reboot-limit-dev
+
+[dev:vars]
+ansible_python_interpreter = "{{ kdevops_python_interpreter }}"
+
+{% endif %}
+[reboot-limit]
+{{ kdevops_host_prefix }}-reboot-limit
+{% if kdevops_baseline_and_dev %}
+{{ kdevops_host_prefix }}-reboot-limit-dev
+{% endif %}
+
+[reboot-limit:vars]
+ansible_python_interpreter = "{{ kdevops_python_interpreter }}"
+{% else %}
 [all]
 localhost ansible_connection=local
 write-your-own-template-for-your-workflow-and-task
+{% endif %}
 {% else %}
 [all]
 localhost ansible_connection=local
-{{ kdevops_hosts_prefix }}
+{{ kdevops_host_prefix }}
 {% if kdevops_baseline_and_dev == True %}
-{{ kdevops_hosts_prefix }}-dev
+{{ kdevops_host_prefix }}-dev
 {% endif %}
 {% if kdevops_enable_iscsi %}
-{{ kdevops_hosts_prefix }}-iscsi
+{{ kdevops_host_prefix }}-iscsi
 {% endif %}
 {% if kdevops_nfsd_enable %}
-{{ kdevops_hosts_prefix }}-nfsd
+{{ kdevops_host_prefix }}-nfsd
 {% endif %}
 [all:vars]
 ansible_python_interpreter =  "{{ kdevops_python_interpreter }}"
 [baseline]
-{{ kdevops_hosts_prefix }}
+{{ kdevops_host_prefix }}
 [baseline:vars]
 ansible_python_interpreter =  "{{ kdevops_python_interpreter }}"
 [dev]
 {% if kdevops_baseline_and_dev %}
-{{ kdevops_hosts_prefix }}-dev
+{{ kdevops_host_prefix }}-dev
 {% endif %}
 [dev:vars]
 ansible_python_interpreter =  "{{ kdevops_python_interpreter }}"
 {% if kdevops_enable_iscsi %}
 [iscsi]
-{{ kdevops_hosts_prefix }}-iscsi
+{{ kdevops_host_prefix }}-iscsi
 [iscsi:vars]
 ansible_python_interpreter =  "{{ kdevops_python_interpreter }}"
 {% endif %}
 {% if kdevops_nfsd_enable %}
 [nfsd]
-{{ kdevops_hosts_prefix }}-nfsd
+{{ kdevops_host_prefix }}-nfsd
 [nfsd:vars]
 ansible_python_interpreter =  "{{ kdevops_python_interpreter }}"
 {% endif %}
 [service]
 {% if kdevops_enable_iscsi %}
-{{ kdevops_hosts_prefix }}-iscsi
+{{ kdevops_host_prefix }}-iscsi
 {% endif %}
 {% if kdevops_nfsd_enable %}
-{{ kdevops_hosts_prefix }}-nfsd
+{{ kdevops_host_prefix }}-nfsd
 {% endif %}
 [service:vars]
 ansible_python_interpreter =  "{{ kdevops_python_interpreter }}"
diff --git a/playbooks/roles/gen_nodes/tasks/main.yml b/playbooks/roles/gen_nodes/tasks/main.yml
index 4192ae89..119d262e 100644
--- a/playbooks/roles/gen_nodes/tasks/main.yml
+++ b/playbooks/roles/gen_nodes/tasks/main.yml
@@ -558,6 +558,38 @@
     - kdevops_workflow_enable_mmtests
     - ansible_nodes_template.stat.exists
 
+- name: Generate the reboot-limit kdevops nodes file using {{ kdevops_nodes_template }} as jinja2 source template
+  tags: [ 'hosts' ]
+  vars:
+    node_template: "{{ kdevops_nodes_template | basename }}"
+    nodes: "{{ [kdevops_host_prefix + '-reboot-limit'] }}"
+    all_generic_nodes: "{{ [kdevops_host_prefix + '-reboot-limit'] }}"
+  template:
+    src: "{{ node_template }}"
+    dest: "{{ topdir_path }}/{{ kdevops_nodes }}"
+    force: yes
+  when:
+    - kdevops_workflows_dedicated_workflow
+    - workflows_reboot_limit
+    - ansible_nodes_template.stat.exists
+    - not kdevops_baseline_and_dev
+
+- name: Generate the reboot-limit kdevops nodes file with dev hosts using {{ kdevops_nodes_template }} as jinja2 source template
+  tags: [ 'hosts' ]
+  vars:
+    node_template: "{{ kdevops_nodes_template | basename }}"
+    nodes: "{{ [kdevops_host_prefix + '-reboot-limit', kdevops_host_prefix + '-reboot-limit-dev'] }}"
+    all_generic_nodes: "{{ [kdevops_host_prefix + '-reboot-limit', kdevops_host_prefix + '-reboot-limit-dev'] }}"
+  template:
+    src: "{{ node_template }}"
+    dest: "{{ topdir_path }}/{{ kdevops_nodes }}"
+    force: yes
+  when:
+    - kdevops_workflows_dedicated_workflow
+    - workflows_reboot_limit
+    - ansible_nodes_template.stat.exists
+    - kdevops_baseline_and_dev
+
 - name: Get the control host's timezone
   ansible.builtin.command: "timedatectl show -p Timezone --value"
   register: kdevops_host_timezone
diff --git a/playbooks/roles/reboot-limit/tasks/do-reboot-compare.yml b/playbooks/roles/reboot-limit/tasks/do-reboot-compare.yml
new file mode 100644
index 00000000..43404dc2
--- /dev/null
+++ b/playbooks/roles/reboot-limit/tasks/do-reboot-compare.yml
@@ -0,0 +1,126 @@
+---
+# This task performs both regular and kexec reboots sequentially for comparison
+- name: Print uname for each host
+  tags: [ 'run_tests' ]
+  debug: var=ansible_kernel
+
+- name: Hint to our watchdog our reboot-limit comparison tests are about to kick off
+  local_action: file path="{{ reboot_limit_local_results_dir }}/.begin" state=touch
+  tags: [ 'run_tests' ]
+  run_once: true
+
+# Phase 1: Regular reboot test
+- name: Starting Phase 1 - Regular reboot test ({{ reboot_num }} of {{ reboot_limit_max }})
+  debug:
+    msg: "Starting regular reboot test - reboot {{ reboot_num }} of {{ reboot_limit_max }}"
+  tags: [ 'run_tests' ]
+
+- name: Run the regular reboot test using the ansible reboot module
+  become: yes
+  become_method: sudo
+  reboot:
+    post_reboot_delay: 10
+  tags: [ 'run_tests' ]
+
+- name: Handle regular reboot count and data collection
+  include_tasks: handle-reboot-data.yml
+  vars:
+    reboot_type: "regular"
+    data_path: "{{ reboot_limit_data_regular }}"
+  tags: [ 'run_tests' ]
+
+# Phase 2: Kexec reboot test
+- name: Starting Phase 2 - Kexec reboot test ({{ reboot_num }} of {{ reboot_limit_max }})
+  debug:
+    msg: "Starting kexec reboot test - reboot {{ reboot_num }} of {{ reboot_limit_max }}"
+  tags: [ 'run_tests' ]
+
+# Kexec preparation tasks
+- name: Get current kernel version for kexec
+  command: uname -r
+  register: current_kernel_version
+  tags: [ 'run_tests' ]
+
+- name: Check for kernel image locations for kexec
+  stat:
+    path: "{{ kernel_path }}"
+  register: kernel_stat
+  loop:
+    - "/boot/vmlinuz-{{ current_kernel_version.stdout }}"
+    - "/boot/vmlinux-{{ current_kernel_version.stdout }}"
+    - "/boot/kernel-{{ current_kernel_version.stdout }}"
+  loop_control:
+    loop_var: kernel_path
+  when:
+    - current_kernel_version is defined
+  tags: [ 'run_tests' ]
+
+- name: Set kernel path for kexec
+  set_fact:
+    kexec_kernel_path: "{{ kernel_item.stat.path }}"
+  loop: "{{ kernel_stat.results }}"
+  loop_control:
+    loop_var: kernel_item
+  when:
+    - kernel_item.stat.exists
+  tags: [ 'run_tests' ]
+
+- name: Check for initrd/initramfs locations for kexec
+  stat:
+    path: "{{ initrd_path }}"
+  register: initrd_stat
+  loop:
+    - "/boot/initrd.img-{{ current_kernel_version.stdout }}"
+    - "/boot/initramfs-{{ current_kernel_version.stdout }}.img"
+    - "/boot/initrd-{{ current_kernel_version.stdout }}"
+    - "/boot/initrd-{{ current_kernel_version.stdout }}.img"
+  loop_control:
+    loop_var: initrd_path
+  when:
+    - current_kernel_version is defined
+  tags: [ 'run_tests' ]
+
+- name: Set initrd path for kexec
+  set_fact:
+    kexec_initrd_path: "{{ initrd_item.stat.path }}"
+  loop: "{{ initrd_stat.results }}"
+  loop_control:
+    loop_var: initrd_item
+  when:
+    - initrd_item.stat.exists
+  tags: [ 'run_tests' ]
+
+- name: Read current kernel command line for kexec
+  slurp:
+    src: /proc/cmdline
+  register: cmdline_content
+  tags: [ 'run_tests' ]
+
+- name: Load kernel into kexec
+  become: yes
+  become_method: sudo
+  command: >
+    kexec -l {{ kexec_kernel_path }}
+    --initrd={{ kexec_initrd_path }}
+    --command-line="{{ cmdline_content.content | b64decode | trim }}"
+  when:
+    - kexec_kernel_path is defined
+    - kexec_initrd_path is defined
+  tags: [ 'run_tests' ]
+
+- name: Run the kexec reboot test using systemctl kexec
+  become: yes
+  become_method: sudo
+  reboot:
+    msg: "Rebooting system via systemctl kexec for reboot-limit comparison test"
+    reboot_command: "systemctl kexec"
+    post_reboot_delay: 10
+    reboot_timeout: 300
+  tags: [ 'run_tests' ]
+
+- name: Handle kexec reboot count and data collection
+  include_tasks: handle-reboot-data.yml
+  vars:
+    reboot_type: "kexec"
+    data_path: "{{ reboot_limit_data_kexec }}"
+  tags: [ 'run_tests' ]
diff --git a/playbooks/roles/reboot-limit/tasks/do-reboot.yml b/playbooks/roles/reboot-limit/tasks/do-reboot.yml
index ec2c29df..7b38f9dc 100644
--- a/playbooks/roles/reboot-limit/tasks/do-reboot.yml
+++ b/playbooks/roles/reboot-limit/tasks/do-reboot.yml
@@ -39,12 +39,14 @@
 
 - name: Check for kernel image locations for kexec
   stat:
-    path: "{{ item }}"
+    path: "{{ kernel_path }}"
   register: kernel_stat
-  with_items:
+  loop:
     - "/boot/vmlinuz-{{ current_kernel_version.stdout }}"
     - "/boot/vmlinux-{{ current_kernel_version.stdout }}"
     - "/boot/kernel-{{ current_kernel_version.stdout }}"
+  loop_control:
+    loop_var: kernel_path
   when:
     - reboot_limit_test_type == "systemctl_kexec"
     - current_kernel_version is defined
@@ -52,22 +54,26 @@
 
 - name: Set kernel path for kexec
   set_fact:
-    kexec_kernel_path: "{{ item.stat.path }}"
-  with_items: "{{ kernel_stat.results }}"
+    kexec_kernel_path: "{{ kernel_item.stat.path }}"
+  loop: "{{ kernel_stat.results }}"
+  loop_control:
+    loop_var: kernel_item
   when:
     - reboot_limit_test_type == "systemctl_kexec"
-    - item.stat.exists
+    - kernel_item.stat.exists
   tags: [ 'run_tests' ]
 
 - name: Check for initrd/initramfs locations for kexec
   stat:
-    path: "{{ item }}"
+    path: "{{ initrd_path }}"
   register: initrd_stat
-  with_items:
+  loop:
     - "/boot/initrd.img-{{ current_kernel_version.stdout }}"
     - "/boot/initramfs-{{ current_kernel_version.stdout }}.img"
     - "/boot/initrd-{{ current_kernel_version.stdout }}"
     - "/boot/initrd-{{ current_kernel_version.stdout }}.img"
+  loop_control:
+    loop_var: initrd_path
   when:
     - reboot_limit_test_type == "systemctl_kexec"
     - current_kernel_version is defined
@@ -75,11 +81,13 @@
 
 - name: Set initrd path for kexec
   set_fact:
-    kexec_initrd_path: "{{ item.stat.path }}"
-  with_items: "{{ initrd_stat.results }}"
+    kexec_initrd_path: "{{ initrd_item.stat.path }}"
+  loop: "{{ initrd_stat.results }}"
+  loop_control:
+    loop_var: initrd_item
   when:
     - reboot_limit_test_type == "systemctl_kexec"
-    - item.stat.exists
+    - initrd_item.stat.exists
   tags: [ 'run_tests' ]
 
 - name: Read current kernel command line for kexec
diff --git a/playbooks/roles/reboot-limit/tasks/handle-reboot-data.yml b/playbooks/roles/reboot-limit/tasks/handle-reboot-data.yml
new file mode 100644
index 00000000..6bbdbb3c
--- /dev/null
+++ b/playbooks/roles/reboot-limit/tasks/handle-reboot-data.yml
@@ -0,0 +1,94 @@
+---
+# Handles reboot counting and data collection for a specific reboot type
+# Variables expected:
+#   reboot_type: "regular" or "kexec"
+#   data_path: path where to store data for this reboot type
+
+- name: Set reboot type specific file paths
+  set_fact:
+    reboot_type_analyze_file: "{{ data_path }}/{{ ansible_ssh_host }}/{{ reboot_limits_systemctl_analyze_log }}"
+    reboot_type_count_file: "{{ data_path }}/{{ ansible_ssh_host }}/{{ reboot_limits_count_log }}"
+  tags: [ 'run_tests' ]
+
+- name: Create the data collection directory for {{ reboot_type }} reboot type
+  become: yes
+  become_method: sudo
+  file:
+    path: "{{ data_path }}/{{ ansible_ssh_host }}"
+    state: directory
+  tags: [ 'run_tests' ]
+
+- name: Check if the {{ reboot_type }} reboot count file exists
+  become: yes
+  become_method: sudo
+  stat:
+    path: "{{ reboot_type_count_file }}"
+  register: reboot_type_count_file_stat
+  tags: [ 'run_tests' ]
+
+- name: Read last {{ reboot_type }} boot count
+  become: yes
+  become_method: sudo
+  slurp:
+    src: "{{ reboot_type_count_file }}"
+  register: reboot_type_last_count
+  when:
+    - reboot_type_count_file_stat.stat.exists
+  tags: [ 'run_tests' ]
+
+- name: Set the current {{ reboot_type }} boot count into a variable
+  set_fact:
+    reboot_type_count: "{{ reboot_type_last_count['content'] | b64decode | int }}"
+  tags: [ 'run_tests' ]
+  when:
+    - reboot_type_count_file_stat.stat.exists
+
+- name: Adjust the {{ reboot_type }} boot count if we rebooted OK
+  set_fact:
+    reboot_type_count: "{{ reboot_type_count | int + 1 }}"
+  tags: [ 'run_tests' ]
+  when:
+    - reboot_type_count_file_stat.stat.exists
+
+- name: Set the current {{ reboot_type }} boot count when no prior test exists
+  set_fact:
+    reboot_type_count: 1
+  tags: [ 'run_tests' ]
+  when:
+    - not reboot_type_count_file_stat.stat.exists
+
+- name: Write current {{ reboot_type }} boot count to file ({{ reboot_type_count }})
+  become: yes
+  become_method: sudo
+  copy:
+    content: "{{ reboot_type_count }}"
+    dest: "{{ reboot_type_count_file }}"
+  tags: [ 'run_tests' ]
+
+- name: Wait for boot up to complete before running systemd-analyze for {{ reboot_type }}
+  become: yes
+  become_method: sudo
+  command: "systemctl is-system-running --wait"
+  when:
+    - reboot_limit_enable_systemd_analyze|bool
+  tags: [ 'run_tests' ]
+
+- name: Collect systemctl-analyze results for {{ reboot_type }}
+  become: yes
+  become_method: sudo
+  command: "systemd-analyze"
+  register: systemd_analyze_cmd
+  when:
+    - reboot_limit_enable_systemd_analyze|bool
+  tags: [ 'run_tests' ]
+
+- name: Append systemctl-analyze output for {{ reboot_type }}
+  become: yes
+  become_method: sudo
+  tags: [ 'run_tests' ]
+  lineinfile:
+    path: "{{ reboot_type_analyze_file }}"
+    line: "{{ systemd_analyze_cmd.stdout }}"
+    create: yes
+  when:
+    - reboot_limit_enable_systemd_analyze|bool
diff --git a/playbooks/roles/reboot-limit/tasks/main.yml b/playbooks/roles/reboot-limit/tasks/main.yml
index 7bf0f573..5cd5e088 100644
--- a/playbooks/roles/reboot-limit/tasks/main.yml
+++ b/playbooks/roles/reboot-limit/tasks/main.yml
@@ -24,6 +24,25 @@
   file:
     path: "{{ reboot_limit_data }}/{{ ansible_ssh_host }}"
     state: directory
+  when: not reboot_limit_compare_both_enabled|default(false)|bool
+  tags: [ 'install', 'first_run' ]
+
+- name: Create the regular reboot data collection directory for comparison mode
+  become: yes
+  become_method: sudo
+  file:
+    path: "{{ reboot_limit_data_regular }}/{{ ansible_ssh_host }}"
+    state: directory
+  when: reboot_limit_compare_both_enabled|default(false)|bool
+  tags: [ 'install', 'first_run' ]
+
+- name: Create the kexec reboot data collection directory for comparison mode
+  become: yes
+  become_method: sudo
+  file:
+    path: "{{ reboot_limit_data_kexec }}/{{ ansible_ssh_host }}"
+    state: directory
+  when: reboot_limit_compare_both_enabled|default(false)|bool
   tags: [ 'install', 'first_run' ]
 
 - name: Set the file to collect systemctl-analyze results
@@ -40,7 +59,7 @@
     reboot_limit_count_file: "{{ reboot_limit_data}}/{{ ansible_ssh_host }}/{{ reboot_limits_count_log }}"
   tags: [ 'read_count', 'vars' ]
 
-- name: Delete old results directory files if a reset was called
+- name: Delete old results directory files if a reset was called (single mode)
   become: yes
   become_method: sudo
   file:
@@ -51,6 +70,25 @@
     - "{{ reboot_limit_count_file }}"
   loop_control:
     label: "{{ item | regex_replace(reboot_limit_data | regex_escape()) | regex_replace('^/', '') }}"
+  when: not reboot_limit_compare_both_enabled|default(false)|bool
+  tags: [ 'reset' ]
+
+- name: Delete old results directory files if a reset was called (comparison mode - regular)
+  become: yes
+  become_method: sudo
+  file:
+    path: "{{ reboot_limit_data_regular }}/{{ ansible_ssh_host }}"
+    state: absent
+  when: reboot_limit_compare_both_enabled|default(false)|bool
+  tags: [ 'reset' ]
+
+- name: Delete old results directory files if a reset was called (comparison mode - kexec)
+  become: yes
+  become_method: sudo
+  file:
+    path: "{{ reboot_limit_data_kexec }}/{{ ansible_ssh_host }}"
+    state: absent
+  when: reboot_limit_compare_both_enabled|default(false)|bool
   tags: [ 'reset' ]
 
 - name: Set the path where we collect our local reboot-limit results
@@ -68,12 +106,23 @@
   run_once: true
   tags: [ 'first_run' ]
 
-- name: Run the reboot loop
+- name: Run the reboot loop (single mode)
   include_tasks: do-reboot.yml
   with_sequence: count={{ reboot_limit_max }}
+  loop_control:
+    loop_var: reboot_num
+  when: not reboot_limit_compare_both_enabled|default(false)|bool
+  tags: [ 'run_tests' ]
+
+- name: Run the reboot comparison loop (both regular and kexec)
+  include_tasks: do-reboot-compare.yml
+  with_sequence: count={{ reboot_limit_max }}
+  loop_control:
+    loop_var: reboot_num
+  when: reboot_limit_compare_both_enabled|default(false)|bool
   tags: [ 'run_tests' ]
 
-- name: Copy the latest results over when we're done
+- name: Copy the latest results over when we're done (single mode)
   tags: [ 'copy_results' ]
   become: yes
   become_flags: 'su - -c'
@@ -87,3 +136,32 @@
     - "{{ reboot_limit_count_file }}"
   loop_control:
     label: "{{ item | regex_replace(reboot_limit_data | regex_escape()) | regex_replace('^/', '') }}"
+  when: not reboot_limit_compare_both_enabled|default(false)|bool
+
+- name: Copy the regular reboot results in comparison mode
+  tags: [ 'copy_results' ]
+  become: yes
+  become_flags: 'su - -c'
+  become_method: sudo
+  fetch:
+    src: "{{ reboot_limit_data_regular }}/{{ ansible_ssh_host }}/{{ item }}"
+    dest: "{{ reboot_limit_local_results_dir }}/regular/{{ ansible_ssh_host }}/{{ item }}"
+    flat: yes
+  with_items:
+    - "{{ reboot_limits_systemctl_analyze_log }}"
+    - "{{ reboot_limits_count_log }}"
+  when: reboot_limit_compare_both_enabled|default(false)|bool
+
+- name: Copy the kexec reboot results in comparison mode
+  tags: [ 'copy_results' ]
+  become: yes
+  become_flags: 'su - -c'
+  become_method: sudo
+  fetch:
+    src: "{{ reboot_limit_data_kexec }}/{{ ansible_ssh_host }}/{{ item }}"
+    dest: "{{ reboot_limit_local_results_dir }}/kexec/{{ ansible_ssh_host }}/{{ item }}"
+    flat: yes
+  with_items:
+    - "{{ reboot_limits_systemctl_analyze_log }}"
+    - "{{ reboot_limits_count_log }}"
+  when: reboot_limit_compare_both_enabled|default(false)|bool
diff --git a/scripts/workflows/demos/reboot-limit/analyze_results.py b/scripts/workflows/demos/reboot-limit/analyze_results.py
index bfd6f41a..1f87330e 100755
--- a/scripts/workflows/demos/reboot-limit/analyze_results.py
+++ b/scripts/workflows/demos/reboot-limit/analyze_results.py
@@ -27,6 +27,9 @@ class RebootLimitAnalyzer:
     def __init__(self, results_dir: str):
         self.results_dir = Path(results_dir)
         self.hosts_data: Dict[str, Dict] = {}
+        self.comparison_mode = False
+        self.regular_data: Dict[str, Dict] = {}
+        self.kexec_data: Dict[str, Dict] = {}
 
     def parse_systemd_analyze_line(self, line: str) -> Optional[Dict[str, float]]:
         """
@@ -88,10 +91,28 @@ class RebootLimitAnalyzer:
 
     def load_all_data(self):
         """Load data for all hosts in the results directory."""
-        # Look for host directories
-        for item in self.results_dir.iterdir():
-            if item.is_dir():
-                self.hosts_data[item.name] = self.load_host_data(item)
+        # Check if we're in comparison mode (regular/ and kexec/ subdirs exist)
+        regular_dir = self.results_dir / "regular"
+        kexec_dir = self.results_dir / "kexec"
+
+        if regular_dir.exists() and kexec_dir.exists():
+            self.comparison_mode = True
+            print("Detected comparison mode: analyzing both regular and kexec reboots")
+
+            # Load regular reboot data
+            for item in regular_dir.iterdir():
+                if item.is_dir():
+                    self.regular_data[item.name] = self.load_host_data(item)
+
+            # Load kexec reboot data
+            for item in kexec_dir.iterdir():
+                if item.is_dir():
+                    self.kexec_data[item.name] = self.load_host_data(item)
+        else:
+            # Standard single mode
+            for item in self.results_dir.iterdir():
+                if item.is_dir():
+                    self.hosts_data[item.name] = self.load_host_data(item)
 
     def calculate_statistics(self, times: List[float]) -> Dict[str, float]:
         """Calculate statistical measures for a list of times."""
@@ -108,6 +129,13 @@ class RebootLimitAnalyzer:
 
     def plot_boot_times(self, output_file: str = "reboot_limit_analysis.png"):
         """Generate plots for boot time analysis."""
+        if self.comparison_mode:
+            self.plot_comparison_analysis(output_file)
+        else:
+            self.plot_single_mode_analysis(output_file)
+
+    def plot_single_mode_analysis(self, output_file: str):
+        """Generate plots for single mode analysis."""
         if not self.hosts_data:
             print("No data to plot")
             return
@@ -221,8 +249,190 @@ class RebootLimitAnalyzer:
         plt.savefig(output_file, dpi=300, bbox_inches="tight")
         print(f"Saved plot to {output_file}")
 
+    def plot_comparison_analysis(self, output_file: str):
+        """Generate streamlined comparison plot combining all hosts' regular vs kexec data."""
+        if not self.regular_data and not self.kexec_data:
+            print("No comparison data to plot")
+            return
+
+        # Ensure the output directory exists
+        output_path = Path(output_file)
+        if output_path.parent != Path("."):
+            output_path.parent.mkdir(parents=True, exist_ok=True)
+
+        # Combine data from all hosts
+        all_regular_times = []
+        all_kexec_times = []
+        host_labels = []
+
+        # Collect all data points from all hosts
+        all_hosts = sorted(set(self.regular_data.keys()) | set(self.kexec_data.keys()))
+
+        for host in all_hosts:
+            regular_data = self.regular_data.get(host, {"boot_times": []})
+            kexec_data = self.kexec_data.get(host, {"boot_times": []})
+
+            regular_times = regular_data.get("boot_times", [])
+            kexec_times = kexec_data.get("boot_times", [])
+
+            # Add host data to combined arrays
+            if regular_times:
+                regular_totals = [bt["total"] for bt in regular_times]
+                all_regular_times.extend(regular_totals)
+                host_labels.extend([f"{host}-regular"] * len(regular_totals))
+
+            if kexec_times:
+                kexec_totals = [bt["total"] for bt in kexec_times]
+                all_kexec_times.extend(kexec_totals)
+
+        # Create single comprehensive comparison plot
+        fig, ax = plt.subplots(1, 1, figsize=(12, 8))
+
+        # Plot combined data
+        if all_regular_times:
+            regular_boot_numbers = list(range(1, len(all_regular_times) + 1))
+            ax.plot(
+                regular_boot_numbers,
+                all_regular_times,
+                "b-",
+                linewidth=2,
+                label="Regular Reboot",
+                alpha=0.8,
+                marker="o",
+                markersize=4,
+            )
+
+        if all_kexec_times:
+            kexec_boot_numbers = list(range(1, len(all_kexec_times) + 1))
+            ax.plot(
+                kexec_boot_numbers,
+                all_kexec_times,
+                "g-",
+                linewidth=2,
+                label="Kexec Reboot",
+                alpha=0.8,
+                marker="s",
+                markersize=4,
+            )
+
+        # Calculate and display combined statistics
+        if all_regular_times and all_kexec_times:
+            regular_stats = self.calculate_statistics(all_regular_times)
+            kexec_stats = self.calculate_statistics(all_kexec_times)
+
+            if regular_stats and kexec_stats:
+                # Add mean lines
+                ax.axhline(
+                    y=regular_stats["mean"],
+                    color="blue",
+                    linestyle="--",
+                    alpha=0.7,
+                    linewidth=2,
+                    label=f"Regular Mean: {regular_stats['mean']:.2f}s",
+                )
+                ax.axhline(
+                    y=kexec_stats["mean"],
+                    color="green",
+                    linestyle="--",
+                    alpha=0.7,
+                    linewidth=2,
+                    label=f"Kexec Mean: {kexec_stats['mean']:.2f}s",
+                )
+
+                # Add shaded confidence regions
+                ax.fill_between(
+                    range(1, max(len(all_regular_times), len(all_kexec_times)) + 1),
+                    regular_stats["mean"] - regular_stats["stdev"],
+                    regular_stats["mean"] + regular_stats["stdev"],
+                    alpha=0.2,
+                    color="blue",
+                    label=f"Regular ±1σ: {regular_stats['stdev']:.2f}s",
+                )
+
+                ax.fill_between(
+                    range(1, max(len(all_regular_times), len(all_kexec_times)) + 1),
+                    kexec_stats["mean"] - kexec_stats["stdev"],
+                    kexec_stats["mean"] + kexec_stats["stdev"],
+                    alpha=0.2,
+                    color="green",
+                    label=f"Kexec ±1σ: {kexec_stats['stdev']:.2f}s",
+                )
+
+                # Calculate performance improvement
+                speedup = (
+                    regular_stats["mean"] / kexec_stats["mean"]
+                    if kexec_stats["mean"] > 0
+                    else 0
+                )
+                time_saved = regular_stats["mean"] - kexec_stats["mean"]
+                percent_improvement = (
+                    (regular_stats["mean"] - kexec_stats["mean"])
+                    / regular_stats["mean"]
+                ) * 100
+
+                # Create comprehensive statistics text
+                stats_text = f"PERFORMANCE COMPARISON\n"
+                stats_text += f"{'='*25}\n"
+                stats_text += f"Regular Boot:\n"
+                stats_text += f"  Mean: {regular_stats['mean']:.2f}s\n"
+                stats_text += f"  Range: {regular_stats['min']:.2f}s - {regular_stats['max']:.2f}s\n"
+                stats_text += f"  Samples: {len(all_regular_times)}\n\n"
+                stats_text += f"Kexec Boot:\n"
+                stats_text += f"  Mean: {kexec_stats['mean']:.2f}s\n"
+                stats_text += (
+                    f"  Range: {kexec_stats['min']:.2f}s - {kexec_stats['max']:.2f}s\n"
+                )
+                stats_text += f"  Samples: {len(all_kexec_times)}\n\n"
+                stats_text += f"IMPROVEMENT:\n"
+                stats_text += f"  Speedup: {speedup:.2f}x faster\n"
+                stats_text += f"  Time Saved: {time_saved:.2f}s per boot\n"
+                stats_text += f"  Improvement: {percent_improvement:.1f}%\n\n"
+                stats_text += f"Combined Hosts: {', '.join(all_hosts)}"
+
+                # Position statistics box
+                ax.text(
+                    0.02,
+                    0.98,
+                    stats_text,
+                    transform=ax.transAxes,
+                    verticalalignment="top",
+                    fontsize=10,
+                    bbox=dict(
+                        boxstyle="round,pad=0.5", facecolor="lightblue", alpha=0.8
+                    ),
+                )
+
+        # Customize plot appearance
+        ax.set_xlabel("Boot Sequence", fontsize=12, fontweight="bold")
+        ax.set_ylabel("Boot Time (seconds)", fontsize=12, fontweight="bold")
+        ax.set_title(
+            "Regular vs Kexec Boot Performance Comparison\n(Combined Data from All Hosts)",
+            fontsize=14,
+            fontweight="bold",
+        )
+        ax.legend(loc="upper right", fontsize=10)
+        ax.grid(True, alpha=0.3)
+        ax.xaxis.set_major_locator(ticker.MaxNLocator(integer=True))
+
+        # Improve visual styling
+        ax.spines["top"].set_visible(False)
+        ax.spines["right"].set_visible(False)
+        ax.spines["left"].set_linewidth(0.5)
+        ax.spines["bottom"].set_linewidth(0.5)
+
+        plt.tight_layout()
+        plt.savefig(output_file, dpi=300, bbox_inches="tight", facecolor="white")
+        print(f"Saved comparison plot to {output_file}")
+
     def print_summary(self):
         """Print a summary of the analysis to stdout."""
+        if self.comparison_mode:
+            self.print_comparison_summary()
+        else:
+            self.print_single_mode_summary()
+
+    def print_single_mode_summary(self):
+        """Print summary for single mode analysis."""
         for host, data in self.hosts_data.items():
             print(f"\n{'=' * 60}")
             print(f"Host: {host}")
@@ -255,6 +465,79 @@ class RebootLimitAnalyzer:
             else:
                 print("  No boot time data available")
 
+    def print_comparison_summary(self):
+        """Print summary for comparison mode analysis."""
+        all_hosts = set(self.regular_data.keys()) | set(self.kexec_data.keys())
+
+        for host in sorted(all_hosts):
+            print(f"\n{'=' * 80}")
+            print(f"Host: {host} - COMPARISON ANALYSIS")
+            print(f"{'=' * 80}")
+
+            regular_data = self.regular_data.get(
+                host, {"boot_times": [], "boot_count": 0}
+            )
+            kexec_data = self.kexec_data.get(host, {"boot_times": [], "boot_count": 0})
+
+            print(f"\nREGULAR REBOOT RESULTS:")
+            print(f"  Total boots: {regular_data['boot_count']}")
+
+            if regular_data["boot_times"]:
+                regular_total_times = [bt["total"] for bt in regular_data["boot_times"]]
+                regular_stats = self.calculate_statistics(regular_total_times)
+
+                print(f"  Samples analyzed: {len(regular_total_times)}")
+                if regular_stats:
+                    print(f"  Mean: {regular_stats['mean']:.2f}s")
+                    print(f"  StdDev: {regular_stats['stdev']:.2f}s")
+                    print(
+                        f"  Range: {regular_stats['max'] - regular_stats['min']:.2f}s"
+                    )
+            else:
+                print("  No boot time data available")
+                regular_stats = None
+
+            print(f"\nKEXEC REBOOT RESULTS:")
+            print(f"  Total boots: {kexec_data['boot_count']}")
+
+            if kexec_data["boot_times"]:
+                kexec_total_times = [bt["total"] for bt in kexec_data["boot_times"]]
+                kexec_stats = self.calculate_statistics(kexec_total_times)
+
+                print(f"  Samples analyzed: {len(kexec_total_times)}")
+                if kexec_stats:
+                    print(f"  Mean: {kexec_stats['mean']:.2f}s")
+                    print(f"  StdDev: {kexec_stats['stdev']:.2f}s")
+                    print(f"  Range: {kexec_stats['max'] - kexec_stats['min']:.2f}s")
+            else:
+                print("  No boot time data available")
+                kexec_stats = None
+
+            # Comparison analysis
+            if regular_stats and kexec_stats:
+                print(f"\nCOMPARISON ANALYSIS:")
+                speedup = (
+                    regular_stats["mean"] / kexec_stats["mean"]
+                    if kexec_stats["mean"] > 0
+                    else 0
+                )
+                time_saved = regular_stats["mean"] - kexec_stats["mean"]
+
+                print(f"  Kexec Speedup: {speedup:.2f}x faster")
+                print(f"  Time Saved per Boot: {time_saved:.2f}s")
+                print(f"  Regular Mean: {regular_stats['mean']:.2f}s")
+                print(f"  Kexec Mean: {kexec_stats['mean']:.2f}s")
+
+                if speedup > 1.1:
+                    print(f"  ✓ Kexec provides significant speedup!")
+                elif speedup > 1.0:
+                    print(f"  → Kexec provides minor speedup")
+                else:
+                    print(f"  ⚠ Regular reboot is faster")
+            else:
+                print(f"\nCOMPARISON ANALYSIS:")
+                print(f"  Cannot compare - missing data for one or both reboot types")
+
 
 def main():
     parser = argparse.ArgumentParser(
@@ -287,10 +570,27 @@ def main():
     analyzer = RebootLimitAnalyzer(args.results_dir)
     analyzer.load_all_data()
 
-    if not analyzer.hosts_data:
+    # Check if we have data (either single mode or comparison mode)
+    has_data = False
+    if analyzer.comparison_mode:
+        if analyzer.regular_data or analyzer.kexec_data:
+            has_data = True
+    else:
+        if analyzer.hosts_data:
+            has_data = True
+
+    if not has_data:
         print(f"No host data found in '{args.results_dir}'")
-        print("Make sure you've run 'make reboot-limit-baseline' first")
-        sys.exit(1)
+        if analyzer.comparison_mode:
+            print(
+                "Make sure you've run 'make reboot-limit-tests' with comparison mode enabled"
+            )
+        else:
+            print(
+                "Make sure you've run 'make reboot-limit-baseline' or 'make reboot-limit-tests' first"
+            )
+        print("This is normal if you haven't run any tests yet.")
+        sys.exit(0)  # Exit cleanly when no data exists
 
     # Print summary
     analyzer.print_summary()
diff --git a/workflows/demos/reboot-limit/Kconfig b/workflows/demos/reboot-limit/Kconfig
index 91fcd122..ecafe4bd 100644
--- a/workflows/demos/reboot-limit/Kconfig
+++ b/workflows/demos/reboot-limit/Kconfig
@@ -32,6 +32,14 @@ config REBOOT_LIMIT_TYPE_SYSTEMD_KEXEC
 	help
 	  This will try to reboot instead using systemctl kexec.
 
+config REBOOT_LIMIT_TYPE_COMPARE_BOTH
+	bool "Compare regular reboot vs kexec"
+	help
+	  This will test both regular reboot (ansible) and kexec reboot
+	  sequentially to compare their performance characteristics.
+	  Regular reboot will be tested first, followed by kexec reboot.
+	  Statistics will be collected separately for each reboot type.
+
 endchoice
 
 config REBOOT_LIMIT_TEST_TYPE
@@ -39,6 +47,13 @@ config REBOOT_LIMIT_TEST_TYPE
 	default "ansible" if REBOOT_LIMIT_TYPE_ANSIBLE
 	default "systemctl_reboot" if REBOOT_LIMIT_TYPE_SYSTEMD_REBOOT
 	default "systemctl_kexec" if REBOOT_LIMIT_TYPE_SYSTEMD_KEXEC
+	default "compare_both" if REBOOT_LIMIT_TYPE_COMPARE_BOTH
+
+config REBOOT_LIMIT_COMPARE_BOTH_ENABLED
+	bool
+	default y if REBOOT_LIMIT_TYPE_COMPARE_BOTH
+	help
+	  Internal configuration variable to track when comparison mode is enabled.
 
 config REBOOT_LIMIT_BOOT_MAX
 	int "How many reboots should we do to consider reboots OK?"
@@ -119,6 +134,22 @@ config REBOOT_LIMIT_DATA
 	  of each node. Note that {{data_path}} corresponds to the location set
 	  by the configuration option CONFIG_WORKFLOW_DATA_PATH.
 
+config REBOOT_LIMIT_DATA_REGULAR
+	string "Where to place regular reboot statistics in comparison mode"
+	default "{{data_path}}/reboot-limit/regular"
+	depends on REBOOT_LIMIT_COMPARE_BOTH_ENABLED
+	help
+	  This is the target location for regular (ansible) reboot statistics
+	  when running in comparison mode.
+
+config REBOOT_LIMIT_DATA_KEXEC
+	string "Where to place kexec reboot statistics in comparison mode"
+	default "{{data_path}}/reboot-limit/kexec"
+	depends on REBOOT_LIMIT_COMPARE_BOTH_ENABLED
+	help
+	  This is the target location for kexec reboot statistics
+	  when running in comparison mode.
+
 config REBOOT_LIMIT_ENABLE_SYSTEMD_ANALYZE
 	bool "Enable data collection of systemd-analyze results"
 	default y
diff --git a/workflows/demos/reboot-limit/Makefile b/workflows/demos/reboot-limit/Makefile
index 384442f4..680eed88 100644
--- a/workflows/demos/reboot-limit/Makefile
+++ b/workflows/demos/reboot-limit/Makefile
@@ -47,6 +47,14 @@ ifeq (y,$(CONFIG_REBOOT_LIMIT_ENABLE_DATA_COLLECTION))
 REBOOT_LIMIT_DATA :=$(subst ",,$(CONFIG_REBOOT_LIMIT_DATA))
 REBOOT_LIMIT_ARGS += reboot_limit_data=\"$(REBOOT_LIMIT_DATA)\"
 
+ifeq (y,$(CONFIG_REBOOT_LIMIT_COMPARE_BOTH_ENABLED))
+REBOOT_LIMIT_DATA_REGULAR :=$(subst ",,$(CONFIG_REBOOT_LIMIT_DATA_REGULAR))
+REBOOT_LIMIT_DATA_KEXEC :=$(subst ",,$(CONFIG_REBOOT_LIMIT_DATA_KEXEC))
+REBOOT_LIMIT_ARGS += reboot_limit_data_regular=\"$(REBOOT_LIMIT_DATA_REGULAR)\"
+REBOOT_LIMIT_ARGS += reboot_limit_data_kexec=\"$(REBOOT_LIMIT_DATA_KEXEC)\"
+REBOOT_LIMIT_ARGS += reboot_limit_compare_both_enabled=True
+endif
+
 # This is an example of how to map a boolean from kconfig into ansible
 ifeq (y,$(CONFIG_REBOOT_LIMIT_ENABLE_SYSTEMD_ANALYZE))
 REBOOT_LIMIT_ARGS += reboot_limit_enable_systemd_analyze=True
@@ -75,6 +83,11 @@ endif
 # the extra_vars.yaml file.
 WORKFLOW_ARGS += $(REBOOT_LIMIT_ARGS)
 
+# Export workflow enabled flag for ansible
+ifeq (y,$(CONFIG_WORKFLOWS_REBOOT_LIMIT))
+WORKFLOW_ARGS += workflows_reboot_limit=True
+endif
+
 # The default is our workflow does not have loop testing enabled
 REBOOT_LIMIT_LOOP := false
 REBOOT_LIMIT_LOOP_KOTD := false
-- 
2.47.2


  parent reply	other threads:[~2025-08-11 22:24 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-11 22:24 [PATCH 00/23] remove old kernel-ci and enhance reboot-limit Luis Chamberlain
2025-08-11 22:24 ` [PATCH 01/23] fstests: remove CONFIG_KERNEL_CI support Luis Chamberlain
2025-08-11 22:24 ` [PATCH 02/23] fstests: remove kernel-ci script symlinks Luis Chamberlain
2025-08-11 22:24 ` [PATCH 03/23] blktests: remove CONFIG_KERNEL_CI support Luis Chamberlain
2025-08-11 22:24 ` [PATCH 04/23] gitr: " Luis Chamberlain
2025-08-11 22:24 ` [PATCH 05/23] ltp: " Luis Chamberlain
2025-08-11 22:24 ` [PATCH 06/23] nfstest: " Luis Chamberlain
2025-08-11 22:24 ` [PATCH 07/23] pynfs: " Luis Chamberlain
2025-08-11 22:24 ` [PATCH 08/23] reboot-limit: convert CONFIG_KERNEL_CI to internal loop feature Luis Chamberlain
2025-08-11 22:24 ` [PATCH 09/23] kconfig: remove CONFIG_KERNEL_CI infrastructure Luis Chamberlain
2025-08-11 22:24 ` [PATCH 10/23] scripts: remove kernel-ci loop infrastructure Luis Chamberlain
2025-08-11 22:24 ` [PATCH 11/23] reboot-limit: simplify what gets selected Luis Chamberlain
2025-08-11 22:24 ` [PATCH 12/23] reboot-limit: add graph visualization support for results Luis Chamberlain
2025-08-11 22:24 ` [PATCH 13/23] reboot-limit: save graphs in organized results/graphs directory Luis Chamberlain
2025-08-11 22:24 ` [PATCH 14/23] docs: add comprehensive reboot-limit workflow documentation Luis Chamberlain
2025-08-11 22:24 ` [PATCH 15/23] reboot-limit: add kexec-tools dependency installation Luis Chamberlain
2025-08-11 22:24 ` [PATCH 16/23] reboot-limit: add A/B testing support targets Luis Chamberlain
2025-08-11 22:24 ` [PATCH 17/23] reboot-limit: fix kexec and reboot connection handling Luis Chamberlain
2025-08-11 22:24 ` [PATCH 18/23] reboot-limit: add COUNT parameter to override reboot count Luis Chamberlain
2025-08-11 22:24 ` [PATCH 19/23] reboot-limit: fix wait_for tasks using wrong host reference Luis Chamberlain
2025-08-11 22:24 ` [PATCH 20/23] reboot-limit: use ansible reboot module for all reboot types Luis Chamberlain
2025-08-11 22:24 ` [PATCH 21/23] reboot-limit: fix COUNT parameter to properly override reboot count Luis Chamberlain
2025-08-11 22:24 ` [PATCH 22/23] reboot-limit: handle empty dev group gracefully Luis Chamberlain
2025-08-11 22:24 ` Luis Chamberlain [this message]
2025-08-12 15:06 ` [PATCH 00/23] remove old kernel-ci and enhance reboot-limit Chuck Lever
2025-08-13  1:28   ` Luis Chamberlain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250811222452.2213071-24-mcgrof@kernel.org \
    --to=mcgrof@kernel.org \
    --cc=cel@kernel.org \
    --cc=da.gomez@kruces.com \
    --cc=kdevops@lists.linux.dev \
    --cc=noreply@anthropic.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox