kernel_thread_start

Sample usage of kernel_thread_start from XNU kernel: (bsd/kern/kern_memorystatus_freeze.c)

__private_extern__ void
memorystatus_freeze_init(void)
{
	kern_return_t result;
	thread_t thread;

	freezer_lck_grp_attr = lck_grp_attr_alloc_init();
	freezer_lck_grp = lck_grp_alloc_init("freezer", freezer_lck_grp_attr);

	lck_mtx_init(&freezer_mutex, freezer_lck_grp, NULL);

	/*
	 * This is just the default value if the underlying
	 * storage device doesn't have any specific budget.
	 * We check with the storage layer in memorystatus_freeze_update_throttle()
	 * before we start our freezing the first time.
	 */
	memorystatus_freeze_budget_pages_remaining = (memorystatus_freeze_daily_mb_max * 1024 * 1024) / PAGE_SIZE;

	result = kernel_thread_start(memorystatus_freeze_thread, NULL, &thread);
	if (result == KERN_SUCCESS) {
		proc_set_thread_policy(thread, TASK_POLICY_INTERNAL, TASK_POLICY_IO, THROTTLE_LEVEL_COMPRESSOR_TIER2);
		proc_set_thread_policy(thread, TASK_POLICY_INTERNAL, TASK_POLICY_PASSIVE_IO, TASK_POLICY_ENABLE);
		thread_set_thread_name(thread, "VM_freezer");

		thread_deallocate(thread);
	} else {
		panic("Could not create memorystatus_freeze_thread");
	}
}

Assuming the strings are available, search for "Could not create memorystatus_freeze_thread". I found 1 xref in IDA inside sub_FFFFFFF00802E71C function.

__int64 sub_FFFFFFF00802E71C()
{
  _DWORD *v0; // x0
  _DWORD *v1; // x20
  __int64 v2; // x0
  __int64 v3; // x19
  unsigned int v4; // w8
  __int64 v5; // x19
  __int64 result; // x0
  unsigned int v7; // w9
  unsigned int v8; // off
  __int64 v9; // [xsp+0h] [xbp-30h] BYREF
  unsigned __int64 v10; // [xsp+8h] [xbp-28h] BYREF

  v9 = 0LL;
  v10 = 4LL;
  v0 = kalloc_canblock(&v10, 1LL, &unk_FFFFFFF0090C85D8);
  v1 = v0;
  if ( v0 )
    *v0 = (dword_FFFFFFF0092557C0 >> 1) & 1;
  qword_FFFFFFF009270068 = v0;
  v10 = 168LL;
  v2 = kalloc_canblock(&v10, 1LL, &unk_FFFFFFF0090C85F0);
  v3 = v2;
  if ( v2 )
    sub_FFFFFFF007C224E0(v2, "freezer", v1);
  qword_FFFFFFF009270070 = v3;
  qword_FFFFFFF0092DAC28 = 570425344LL;
  qword_FFFFFFF0092DAC20 = 0LL;
  v4 = atomic_fetch_add_explicit((v3 + 16), 1u, memory_order_relaxed);
  if ( !v4 )
    sub_FFFFFFF00821F2FC(v3 + 16);
  if ( v4 >= 0xFFFFFFF )
    sub_FFFFFFF00821F318(v3 + 16);
  atomic_fetch_add_explicit((v3 + 24), 1u, memory_order_relaxed);
  qword_FFFFFFF009270030 = (dword_FFFFFFF0090E7AE4 << 6) & 0x3FFC0;
  if ( sub_FFFFFFF007C4F540(sub_FFFFFFF00802E8C0, 0LL, &v9) )                       <----- As it can be observed, this is the call to kernel_thread_start. thread_t thread = v9.
    sub_FFFFFFF0090BAA08("\"Could not create memorystatus_freeze_thread\"");        <----- this should be panic
  v5 = v9;                                                                          <----- v5 = v9 = thread
  sub_FFFFFFF007C59340(v9, 0LL, 35LL, 2LL);                                         <----- sub_FFFFFFF007C59340 = proc_set_thread_policy
  result = sub_FFFFFFF007C59340(v5, 0LL, 36LL, 1LL);
  if ( v5 )
  {
    result = *(v5 + 960);
    if ( result )
      result = sub_FFFFFFF00809100C(result, "VM_freezer");                          <---- sub_FFFFFFF00809100C = thread_set_thread_name
    v7 = atomic_fetch_add_explicit((v5 + 204), 0xFFFFFFFF, memory_order_release);   
    if ( v7 == 1 )
    {
      v8 = __ldar((v5 + 204));
      result = sub_FFFFFFF007C4DCAC(v5);                                            <------ thread_deallocate_complete
    }
    else if ( !v7 )
    {
      sub_FFFFFFF00821F2E0((v5 + 204));
    }
  }
  return result;
}
kernel_thread_start = 0xFFFFFFF007C4F540
panic               = 0xFFFFFFF0090BAA08