Merge "tp: add is_kthread as a process.arg when parsing procfs packets" into main
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index 4ff5cc6..6b6e2ec 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -226,6 +226,7 @@
 SystemProbesParser::SystemProbesParser(TraceProcessorContext* context)
     : context_(context),
       utid_name_id_(context->storage->InternString("utid")),
+      is_kthread_id_(context->storage->InternString("is_kthread")),
       arm_cpu_implementer(
           context->storage->InternString("arm_cpu_implementer")),
       arm_cpu_architecture(
@@ -670,6 +671,12 @@
         context_->process_tracker->SetStartTsIfUnset(upid, *start_ts);
       }
     }
+
+    // Linux v6.4+: explicit field for whether this is a kernel thread.
+    if (proc.has_is_kthread()) {
+      context_->process_tracker->AddArgsTo(upid).AddArg(
+          is_kthread_id_, Variadic::Boolean(proc.is_kthread()));
+    }
   }
 
   for (auto it = ps.threads(); it; ++it) {
diff --git a/src/trace_processor/importers/proto/system_probes_parser.h b/src/trace_processor/importers/proto/system_probes_parser.h
index b1aebce..018a459 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.h
+++ b/src/trace_processor/importers/proto/system_probes_parser.h
@@ -50,6 +50,7 @@
   TraceProcessorContext* const context_;
 
   const StringId utid_name_id_;
+  const StringId is_kthread_id_;
 
   // Arm CPU identifier string IDs
   const StringId arm_cpu_implementer;
diff --git a/test/trace_processor/diff_tests/parser/process_tracking/tests.py b/test/trace_processor/diff_tests/parser/process_tracking/tests.py
index d8694d6..70fccd3 100644
--- a/test/trace_processor/diff_tests/parser/process_tracking/tests.py
+++ b/test/trace_processor/diff_tests/parser/process_tracking/tests.py
@@ -451,3 +451,49 @@
         "count(utid)"
         0
       """))
+
+  # Test explicit kernel thread detection on Linux v6.4+.
+  def test_process_is_kthread_from_procfs(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet {
+          first_packet_on_sequence: true
+          timestamp: 1088821452006028
+          incremental_state_cleared: true
+          process_tree {
+            processes {
+              pid: 618
+              ppid: 2
+              uid: 0
+              cmdline: "kworker/R-cryptd"
+              cmdline_is_comm: true
+              is_kthread: true
+            }
+            processes {
+              pid: 710
+              ppid: 5995
+              uid: 33
+              cmdline: "/usr/sbin/apache2"
+              cmdline: "-k"
+              cmdline: "start"
+              is_kthread: false
+            }
+            collection_end_timestamp: 1088821520810204
+          }
+          trusted_uid: 304336
+          trusted_packet_sequence_id: 3
+          trusted_pid: 1137063
+          previous_packet_dropped: true
+        }
+        """),
+        query="""
+        select p.pid, EXTRACT_ARG(arg_set_id, 'is_kthread') as is_kthread, p.cmdline
+        from process p
+        where pid in (618, 710)
+        order by pid asc;
+        """,
+        out=Csv("""
+        "pid","is_kthread","cmdline"
+        618,1,"kworker/R"
+        710,0,"/usr/sbin/apache2 -k start"
+        """))