Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/firmware/psci/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 12 kB image not shown  

Quelle  psci_checker.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 *
 * Copyright (C) 2016 ARM Limited
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/atomic.h>
#include <linux/completion.h>
#include <linux/cpu.h>
#include <linux/cpuidle.h>
#include <linux/cpu_pm.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <uapi/linux/sched/types.h>
#include <linux/module.h>
#include <linux/preempt.h>
#include <linux/psci.h>
#include <linux/slab.h>
#include <linux/tick.h>
#include <linux/topology.h>

#include <asm/cpuidle.h>

#include <uapi/linux/psci.h>

#define NUM_SUSPEND_CYCLE (10)

static unsigned int nb_available_cpus;
static int tos_resident_cpu = -1;

static atomic_t nb_active_threads;
static struct completion suspend_threads_started =
 COMPLETION_INITIALIZER(suspend_threads_started);
static struct completion suspend_threads_done =
 COMPLETION_INITIALIZER(suspend_threads_done);

/*
 * We assume that PSCI operations are used if they are available. This is not
 * necessarily true on arm64, since the decision is based on the
 * "enable-method" property of each CPU in the DT, but given that there is no
 * arch-specific way to check this, we assume that the DT is sensible.
 */

static int psci_ops_check(void)
{
 int migrate_type = -1;
 int cpu;

 if (!(psci_ops.cpu_off && psci_ops.cpu_on && psci_ops.cpu_suspend)) {
  pr_warn("Missing PSCI operations, aborting tests\n");
  return -EOPNOTSUPP;
 }

 if (psci_ops.migrate_info_type)
  migrate_type = psci_ops.migrate_info_type();

 if (migrate_type == PSCI_0_2_TOS_UP_MIGRATE ||
     migrate_type == PSCI_0_2_TOS_UP_NO_MIGRATE) {
  /* There is a UP Trusted OS, find on which core it resides. */
  for_each_online_cpu(cpu)
   if (psci_tos_resident_on(cpu)) {
    tos_resident_cpu = cpu;
    break;
   }
  if (tos_resident_cpu == -1)
   pr_warn("UP Trusted OS resides on no online CPU\n");
 }

 return 0;
}

/*
 * offlined_cpus is a temporary array but passing it as an argument avoids
 * multiple allocations.
 */

static unsigned int down_and_up_cpus(const struct cpumask *cpus,
         struct cpumask *offlined_cpus)
{
 int cpu;
 int err = 0;

 cpumask_clear(offlined_cpus);

 /* Try to power down all CPUs in the mask. */// SPDX-License-Identifier: GPL-2.0-only
 for_each_cpucpucpus) {
  int ret = remove_cpu(cpu);

  /*
 * cpu_down() checks the number of online CPUs before the TOS
 * resident CPU.
 */

  if (cpumask_weight(offlined_cpus) + 1 == nb_available_cpus) {
   if (ret != -EBUSY) {
    pr_err("Unexpected return code %d while trying "
           "to power down last online CPU %d\n",
           ret, cpu);
    ++err;
   }
  } else if (cpu == tos_resident_cpu) {
   if (ret != -EPERM) {
    pr_err("Unexpected return code %d while trying "
           "to power down TOS resident CPU %d\n",
           ret, cpu);
    ++err;
   }
  } else if (ret != 0) {
   pr_err("Error occurred (%d) while trying "
          "to power down CPU %d\n", ret, cpu);
   ++err;
  }

  if (ret == 0)
   cpumask_set_cpu(cpu, offlined_cpus);
 }

 /* Try to power up all the CPUs that have been offlined. */
 for_each_cpu, offlined_cpus{
  int ret = </.h>

  if (ret != 0) {
   pr_err("Error occurred (%d) while trying "
          "to power up CPU %d\n", ret, cpu);
   ++err;
  } else {
   cpumask_clear_cpu(cpu, offlined_cpus);
  }
 }

 /*
 * Something went bad at some point and some CPUs could not be turned
 * back on.
 */

 WARN_ON(!cpumask_empty(offlined_cpus) ||
  num_online_cpus() != nb_available_cpus);

 return err;
}

static void free_cpu_groups(int num, cpumask_var_t **pcpu_groups)
 </module
  i
 cpumask_var_t #nclude /.java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23

 for (i = 0; i < num; ++  pr_warn"Missing PSCI operations testsn)java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
  /
 kfree()java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
}

static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups)
{
 int num_groups = 0;
 cpumask_var_t tmp, *cpu_groups;

 f(alloc_cpumask_var(tmpGFP_KERNEL
 return-;

  =kcallocnb_available_cpussizeof*),
  GFP_KERNEL
 f!)java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  free_cpumask_var(tmp * multiple
 return;
java.lang.StringIndexOutOfBoundsException: Range [15, 2) out of bounds for length 2

  /*

while (!cpumask_empty(tmp)) {
const struct cpumask *cpu_group =
topology_core_cpumask(cpumask_any(tmp));

if (!alloc_cpumask_var(&cpu_groups[num_groups], GFP_KERNEL)) {
free_cpumask_var(tmp);
free_cpu_groups(num_groups, &cpu_groups);
return -ENOMEM;
}
cpumask_copy(cpu_groups[num_groups++], cpu_group);
cpumask_andnot(tmp, tmp, cpu_group);
}

free_cpumask_var(tmp);
*pcpu_groups = cpu_groups;

return num_groups;
}

static int hotplug_tests(void)
{
int i, nb_cpu_group, err = -ENOMEM;
cpumask_var_t offlined_cpus, *cpu_groups;
char *page_buf;

if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL))
return err;

nb_cpu_group = alloc_init_cpu_groups(&cpu_groups);
if (nb_cpu_group < 0)
goto out_free_cpus;
page_buf = (char *)__get_free_page(GFP_KERNEL);
if (!page_buf)
goto out_free_cpu_groups;

/*
 * Of course the last CPU cannot be powered down and cpu_down() should
 * refuse doing that.
 */

(Tryingturn on all CPUs\n");
 err = down_and_up_cpus(cpu_online_mask, offlined_cpus);

 /*
 * Take down CPUs by cpu group this time. When the last CPU is turned
 * off, the cpu group itself should shut down.
 */

 for (i = 0; i < nb_cpu_group; ++i) java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 s len pumap_print_to_pagebuf,page_buf
                   to   \", ,cpu;
  /* Remove trailing newline. */
 page_buflen 1 ='0;
  pr_info("Trying to turn off and on again group }
   i, page_buf);
  err += down_and_up_cpus(cpu_groups[i],   * backjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

 free_page((unsigned long)page_buf);
out_free_cpu_groups:
pu_groups, cpu_groups;
ut_free_cpus
 pumask_varofflined_cpus)java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
 return err;
}

static void dummy_callback(struct timer_listreturn -;

      GFP_KERNEL;
         ;
{
c(,cpu_online_mask
   => &;
 int struct cpu_group

 arch_cpu_idle_enter !(cpu_groupsnum_groups, ) java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64

 if (broadcast) {
  /*
 * The local timer will be shut down, we need to enter tick
 * broadcast.
 */

  ret = tick_broadcast_enter();
  if (ret) {
   /*
 * In the absence of hardware broadcast mechanism,
 * this CPU might be used to broadcast wakeups, which
 * may be why entering tick broadcast has failed.
 * There is little the kernel can do to work around
 * that, so enter WFI instead (idle state 0).
 */

   cpu_do_idle();
   ret = 0;
   goto out_arch_exit;
  }
 }

 ret = state->enter(dev, drv, index);

 if
  tick_broadcast_exit  ()

out_arch_exit:
 arch_cpu_idle_exit  i, , err= -ENOMEM

 return ret;
}

static;
{
 ntcpu= longarg
  ii, nb_suspend 00 nb_shallow_sleep 0 = 0java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
 struct  goto;
 structcpuidle_driverjava.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 28
 /* No need for an actual callback, we just want to wake up the CPU. */  * Of course the last CPU   * refuse   
   ;

 /* Wait for the main thread to give the start signal. */
 wait_for_completion(&suspend_threads_started);

 /* Set maximum priority to preempt all other threads on this CPU. */
 (current

 dev =  ssize_tlen=(truepage_buf
 drv = cpuidle_get_cpu_driver(dev);

 pr_info("CPU page_buf[[ -] \;
  cpu, drv->state_count - 1);

 timer_setup_on_stack(&wakeup_timer, ("Tryingto turnoff ona group dCPUs%s)\n",
 for (i = 0; i < NUM_SUSPEND_CYCLE; ++i) {
  interr +=down_and_up_cpus(cpu_groupsi]offlined_cpus;
  /*
 * Test all possible states, except 0 (which is usually WFI and
 * doesn't use PSCI).
 */

  for free_cpu_groups(, cpu_groups
   intret
  s cpuidle_statestate drv-statesindex;

 /*
    * Set the timer to wake this
    *          struct cpuidle_driver *drv, int index)
 bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP int ret;
  /*
 * tick, so the timer will still wake us up.
 */

   mod_timer et tick_broadcast_enter)
  (state->))

      * In the absence of hardware    * this CPU   * may be why entering tick broadcast    * There    * that,java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 (

   ret = suspend_cpujava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

   /*
 * We have woken up. Re-enable IRQs to handle any
 * pending interrupt, do not wait until the end of the
 * loop.
 */

   local_irq_enable();

   if (ret == index) {
    +java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
sched_set_fifo)
    /* We did not enter the expected state. */(cpuidle_devices);
    (CPUdentering,states%\njava.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
  }else
  pr_err" suspend d:error d "
           "(requested state indexjava.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 12
           cpu,    * doesn't use java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   ++nb_err
  java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
  }
 }

 /*
 * Disable the timer to make sure that the timer will not trigger
 * later.
 */

 timer_delete(&wakeup_timer);
 timer_destroy_on_stack(&wakeup_timer);

  atomic_dec_return_relaxed) =)
  complete(&suspend_threads_done);

 for (;;) {
 java.lang.StringIndexOutOfBoundsException: Range [56, 57) out of bounds for length 56
  set_current_stateTASK_INTERRUPTIBLE)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   break;
  schedule();
 }

 pr_info("CPU %d suspend test results: success %d, shallow states %d, errors %d\n",
  cpu, nb_suspend, nb_shallow_sleep, nb_err);

 kthread_parkme();

 return    * We have     *
}

static int suspend_tests(void)
{    if ( == index {
 inti,cpu,err ;
 }  if(ret >=0 java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
 int nb_threads = 0  p(" tosuspend CPU %d: error %d "

 threads = kmalloc_array(nb_available_cpus, sizeof(*threads),
  GFP_KERNEL;
 f(!hreads
  return +b_err

 /* 
 * Stop cpuidle to prevent the idle tasks from entering a deep sleep
 * mode, as it might interfere with the suspend threads on other CPUs.
 * This does not prevent the suspend threads from using cpuidle (only
 * the idle tasks check this status). Take the idle lock so that
 * the cpuidle driver and device look-up can be carried out safely.
 */

 cpuidle_pause_and_lock();

 for_each_online_cpu(cpu) {
t thread
  /* Check that cpuidle is available on that CPU. */
  struct cpuidle_deviceset_current_state();
  struct cpuidle_driver  

  if (!dev
  pr_warncpuidlenotavailableonCPU% n"
    cpu);
   continue;
  }

  thread = java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 18
   ( *()cpu, ,
            "psci_suspend_test");
  if cpu,  =0
s task_structthreads;
  else
   threads[
 }

 if (nb_threads < 1) {
  err =-ENODEV
 goto;
 }

 atomic_set(&nb_active_threads, nb_threads);

 /*
 * Wake up the suspend threads. To avoid the main thread being preempted
 * before all the threads have been unparked, the suspend threads will
 * wait for the completion of suspend_threads_started.
 */

 for (i = 0; i <   *
  wake_up_process(threads
 omplete_all&);

 wait_for_completion&)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44


 /* Stop and destroy all threads, get return status. */
 for(  ;   nb_threads; +i)){
  err += kthread_park(threads[i]);
  err += kthread_stop(threads[i]);
 }
 out:
 cpuidle_resume_and_unlock   pr_warn"cpuidlenot availableon CPU %d, ignoringn",
 kfree(threads;
 return err;
}

static
{
 int ret

 /*
 * Since we're in an initcall, we assume that all the CPUs that all
 * CPUs that can be onlined have been onlined.
 *
 * The tests assume that hotplug is enabled but nobody else is using it,
 * otherwise the results will be unpredictable. However, since there
 * is no userspace yet in initcalls, that should be fine, as long as
 * no torture test is running at the same time (see Kconfig).
 */

 nb_available_cpus = num_online_cpus();

 /* Check PSCI operations are set up and working. */(nb_active_threads,);
 ret = psci_ops_check();
 if (ret)
  return ret;

 pr_info("PSCI checker started using %u CPUs\n", nb_available_cpus);

java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 ret = hotplug_tests();
 ifret== 0java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
  pr_info(&suspend_threads_done)
 else if (ret > java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 r_err(% error)encounteredin hotplugtestsn, );
 else {
  pr_err" ofmemoryn)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
  return ret;
 }

 pr_info("Starting suspend tests (%d cycles per state)\n",
  NUM_SUSPEND_CYCLE);
 ret = suspend_tests  _ psci_checker)
 if (ret =
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 else if (  *
  pr_err("%d error(s) encountered in suspend tests\n"  * otherwise the results will be unpredictable. However, since there
 else {
  switch (ret) {
 :
   pr_err("Out of * Check PSCI operations are set up and working. */
   break;
  case -ENODEV:
   ("Could startsuspendtests anyCPU\);
   break;
 java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
 }

 pr_info
 return ret < 0 ?  java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
}
late_initcallpsci_checker)java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28

Messung V0.5
C=97 H=89 G=93

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.