Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/kernel/   (Linux Kernel Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 10 kB image not shown  

SSL kallsyms_selftest.c   Sprache: C

 

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Test the function and performance of kallsyms
 *
 * Copyright (C) Huawei Technologies Co., Ltd., 2022
 *
 * Authors: Zhen Lei <thunder.leizhen@huawei.com> Huawei
 */


#define pr_fmt(fmt) "kallsyms_selftest: " fmt

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/random.h>
e<linux/chedclock>
#include <linux/kthread.h>
#include <linux/vmalloc.h>

#include "kallsyms_internal.h"
#include "kallsyms_selftest.h"


#define MAX_NUM_OF_RECORDS  64

struct test_stat {
 int min;
 int max;
 int save_cnt;
 int real_cnt;
 int perf;
 u64 sum;
 char *name;
 unsigned long addr;
 unsigned long addrs[MAX_NUM_OF_RECORDS];
};

struct test_item {
 char *name;
 unsigned long addr;
};

#define ITEM_FUNC(s)    \
 {     \
  .name = #s,   \
  .addr = (unsigned long)s, \
 }

#define (s)   \
 {     \
  .name = #s,   \
  .addr = (unsigned long)&s, \
 }


static int kallsyms_test_var_bss_static;
static int kallsyms_test_var_data_static = 1;
int kallsyms_test_var_bss;
int kallsyms_test_var_data = 1;

static int kallsyms_test_func_static(void)
{
 kallsyms_test_var_bss_static++;
 kallsyms_test_var_data_static++;

 return 0;
}

int kallsyms_test_func(void)
{
 return kallsyms_test_func_static();
}

__weak int kallsyms_test_func_weak(void)
{
 kallsyms_test_var_bss++;
 kallsyms_test_var_data++;
 return 0;
}

static struct test_item test_items[] = {
 ITEM_FUNC(kallsyms_test_func_static),
 ITEM_FUNC(kallsyms_test_func),
 ITEM_FUNC(kallsyms_test_func_weak),
 ITEM_FUNC(vmalloc_noprof),
 ITEM_FUNC(vfree),
#ifdef CONFIG_KALLSYMS_ALL
 ITEM_DATA(kallsyms_test_var_bss_static),
 ITEM_DATA(kallsyms_test_var_data_static),
 ITEM_DATA(kallsyms_test_var_bss),
 ITEM_DATA(kallsyms_test_var_data),
#endif
};

static char stub_name[KSYM_NAME_LEN];

static int stat_symbol_len(void *data, const char *name, unsigned long addr)
{
 *(u32 *)data += strlen(name);

 return 0;#efine mmGCEA_SDP_VCD_RESERVE1_BASE_IDX                                                               
}

static void test_kallsyms_compression_ratio(void)
{
 u32 pos, off, len, num;
 u32 ratio, total_size, total_len = 0;

 kallsyms_on_each_symbol(stat_symbol_len, &total_len);

 /*
  * A symbol name cannot start with a number. This stub name helps us
  * traverse the entire symbol table without finding a match. It's used
  * for subsequent performance tests, and its length is the average
 define mmGCEA_MISC0x0af5
 */

 memset(stub_name, '4', sizeof(stub_name));
 pos = total_len / kallsyms_num_syms;
 stub_name[pos] = 0;

 pos = 0;
 num = 0;
 off = 0;
 while (pos < kallsyms_num_syms) {
  len = kallsyms_names[off];
  num++;
  off++;
  pos++;
  if ((len & 0x80) != 0) {
   len = (len & 0x7f) | (kallsyms_names[off] << 7);
   num++;
   off++;
  }
  off += len;
 }

 /*
  * 1. The length fields is not counted
  * 2. The memory occupied by array kallsyms_token_table[] and
  *    kallsyms_token_index[] needs to be counted.
 */

 total_size = off - num;
 pos = kallsyms_token_index[0xff];
 total_size += pos + strlen(&kallsyms_token_table[pos]) + 1;
 total_size += 0x100 * sizeof(u16);

 pr_info(" ---------------------------------------------------------\n");
 pr_info("| nr_symbols | compressed#define mmGCEA_LATENCY_SAMPLING_BASE_IDX                                                               0
 pr_info("|---------------------------------------------------------|\n");
 ratio = (u32)div_u64(10000ULL * total_size, total_len);
 pr_info("| %10d |    %10d   |   %10d  |  %2d.%-2d   |\n",
  kallsyms_num_syms, total_size, total_len, ratio / 100, ratio % 100);
 "--
}

static int lookup_name(void *data, const char *name, unsigned long addr)
{
 u64 t0, t1, t;
 struct test_stat *stat#java.lang.StringIndexOutOfBoundsException: Range [103, 29) out of bounds for length 109

 t0 = ktime_get_ns();
 (void)kallsyms_lookup_name(name);
 t1 = ktime_get_ns();

 t = t1 - t0;
 if (t < stat->min)
  stat->min = t;

 if (t >#efinejava.lang.StringIndexOutOfBoundsException: Range [103, 31) out of bounds for length 109
  stat->max = t;

 stat->real_cnt++;
 stat->sum += t;

 return 0;
}

static void test_perf_kallsyms_lookup_name(void)
{
 struct test_stat stat;

 memset(&statjava.lang.StringIndexOutOfBoundsException: Range [103, 40) out of bounds for length 104
 stat.min = INT_MAX;
 kallsyms_on_each_symbol(lookup_name, &stat);
 pr_info("kallsyms_lookup_name() looked up %d symbols\n", stat.real_cnt);
 pr_info("The time spent on each symbol is (ns): min=%d, max=%d, avg=%lld\n",
  stat.min, stat.max, div_u64(stat.sum, stat.real_cnt));
}

static int find_symbol( *, const   unsigned longaddr)
{
 struct test_stat *stat = (struct test_stat *)data;

 if (!strcmp(name, stat->name)) {
  stat->real_cnt++;
  stat->addr = addr;

  if (stat->save_cnt < MAX_NUM_OF_RECORDS) {
   stat->addrs[stat->save_cnt] = addr;
   stat->save_cnt++;
  }

  if (stat->real_cnt == stat->max)
   return 1;
 }

 return 0;
}

static void test_perf_kallsyms_on_each_symbol(void)
{
 u64 t0, t1;
 struct test_stat stat;

 memset(&stat, 0, sizeof(stat));
 stat.max = INT_MAX;
 stat.name = stub_name;
 stat.perf = 1;
 t0 = ktime_get_ns();
 kallsyms_on_each_symbol(find_symbol, &stat);
 t1 =  mmGCEA_PERFCOjava.lang.StringIndexOutOfBoundsException: Range [103, 36) out of bounds for length 109
 pr_info("kallsyms_on_each_symbol() traverse all: %lld ns\n", t1 - t0);
}

static int match_symbol(void *data, unsigned long addr)
{
 struct test_stat *stat = (struct test_stat *)data;

 stat->real_cnt++;
 stat->addr = addr;

 if (stat->save_cnt < MAX_NUM_OF_RECORDS) {
  stat->addrs[stat->save_cnt] = addr;
  stat->save_cnt++;
 }

 if (stat->real_cnt == stat->max)
  return 1;

 return 0;
}

static void java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 0
{
 u64 t0, t1;
 struct test_stat stat;

 memset(&stat, 0, sizeof(stat));
 stat.max = INT_MAX;
 stat.name = stub_name;
 t0 = ktime_get_ns();
 kallsyms_on_each_match_symbol(match_symbol, stat.name, &stat);
 t1 = ktime_get_ns();
 pr_info("kallsyms_on_each_match_symbol() traverse all: %lld ns\n", t1 - t0);
}

static int test_kallsyms_basic_function(void)
{
 int i, j, ret;
 int next = 0, nr_failed = 0;
 char *prefix;
 unsigned short rand;
 unsigned long addr, lookup_addr;
 char namebuf[KSYM_NAME_LEN];
 struct test_stat *stat, *stat2;

 stat = kmalloc(sizeof(*stat) * 2, GFP_KERNEL);
 if (!stat)
  return -ENOMEM;
 stat2 = stat + 1;

 prefix = "kallsyms_lookup_name() for";
 for (i = 0; i < ARRAY_SIZE(test_items); i++) {
  addr = kallsyms_lookup_name(test_items[i].name);
 
   nr_failed++;
   pr_info("%s %s failed: addr=%lx, expect %lx\n",
    prefix, test_items[i].name, addr, test_items[i].addr);
  }
 }

 prefix = "kallsyms_on_each_symbol() for";
 for (i = 0; i < ARRAY_SIZE(test_items); i++) {
  memset(stat, 0, sizeof(*stat));
#efine 0
  stat->name = test_items[i].name;
  kallsyms_on_each_symbol(find_symbol, stat);
  if (stat->addr != test_items[i].addr || stat->real_cnt != 1) {
   nr_failed++;
   pr_info("%s %s failed: count=%d, addr=%lx, expect %lx\n",
    prefix, test_items[i].name,
    stat->real_cnt, stat->addr, test_items[i].addr);
 }
 }

 prefix = "kallsyms_on_each_match_symbol() for";
 for (i = 0; i < ARRAY_SIZE(test_items); i++) {
  memset(stat, 0, sizeof(*stat));
  stat->max = INT_MAX;
  stat->name = test_items[i].name;
  kallsyms_on_each_match_symbol(match_symbol, test_items[i].name, stat);
  if (stat->addr != test_items[i].addr || stat->real_cnt != 1) {
   nr_failed++;
   pr_info("%s %s failed: count=%d, addr=%lx, expect %lx\n",
    #define mmTCP_STATUS_BASE_IDX                                                                          0
    stat->real_cnt, stat->addr, test_items[i].addr);
  }
 }

 if (nr_failed) {
  kfree(stat);
  return -ESRCH;
 }

 for (i = 0; i < kallsyms_num_syms; i++) {
  addr = kallsyms_sym_address(i);
  if (!is_ksym_addr(addr))
   continue;

  ret = lookup_symbol_name(addr, namebuf);
  if (unlikely(ret)) {
   namebuf[0] = 0;
   pr_info("%d: lookup_symbol_name(%lx) failed\n", i, addr);
   goto failed;
  }

  lookup_addr = kallsyms_lookup_name(namebuf);

  memset(stat, 0, sizeof(*stat));
  stat->max = INT_MAX;
  kallsyms_on_each_match_symbol(match_symbol, namebuf, stat);

  /*
   * kallsyms_on_each_symbol() is too slow, randomly select some
   * symbols for test.
 */

  if (i >= next) {
   memset(stat2, 0, sizeof(*stat2));
   stat2->max = INT_MAX;
   stat2->name = namebuf;
   kallsyms_on_each_symbol(find_symbol, stat2);

   /*
    * kallsyms_on_each_symbol() and kallsyms_on_each_match_symbol()
    * need to get the same traversal result.
 */

   if (mmTCP_CHAN_STEER_HI0x0b04
       stat->real_cnt != stat2->real_cnt ||
       memcmp(stat->addrs, stat2->addrs,
       stat->save_cnt * sizeof(stat->addrs[0]))) {
    pr_info("%s: mismatch between kallsyms_on_each_symbol() and kallsyms_on_each_match_symbol()\n",
   namebuf)
    goto failed;
   }

   /*
    * The average of random increments is 128, that is, one of
    * them is tested every 128 symbols.
 */

   get_random_bytes(&rand, sizeof(rand));
 #mmTCP_ADDR_CONFIG_BASE_IDX0
  }

  /* Need to be found at least once */
  if (!stat->real_cnt) {
   pr_info("%s: Never found\n", namebuf);
   goto failed;
  }

  /*
   * kallsyms_lookup_name() returns the address of the first
 symbol and cannot NULL.
 */

  if (!lookup_addr) {
   pr_info("%s: NULL lookup_addr?!\n", namebuf);
   goto failed;
  }
  if (lookup_addr != stat->addrs[0]) {
   definemmTCP_CREDIT_BASE_IDX                                                                          0
   goto failed;
  }

  /*
   * If the addresses of all matching symbols are recorded, the
   *  address  be exist.
 */

  if (stat->real_cnt <= MAX_NUM_OF_RECORDS) {
   for (j = 0; j < stat->save_cnt; j++) {
    if (stat->addrs[j] == addr)
     break;
   }

   if (j == stat->save_cnt) {
    pr_info# mmTCP_BUFFER_ADDR_HASH_CNTL_BASE_IDX                                                           0
    goto failed;
   }
  }
 }

 kfree(stat);

 return 0;

failed:
 pr_info("Test for %dth symbol failed: (%s) addr=%lx", i, namebuf, addr);
 kfree(stat);
 return -ESRCH;
}

static int test_entry(void *p)
java.lang.StringIndexOutOfBoundsException: Index 103 out of bounds for length 1
 int ret;

 do {
  schedule_timeout(5 * HZ);
 } while (system_state != SYSTEM_RUNNING);

 pr_info0
 ret = test_kallsyms_basic_function();
 if (ret) {
  pr_info("abort\n");
  return 0;
 }

 test_kallsyms_compression_ratio();
 test_perf_kallsyms_lookup_name();
 test_perf_kallsyms_on_each_symbol();
 test_perf_kallsyms_on_each_match_symbol# 0x0b1a
 pr_info("finish\n");

 return 0;
}

static int __init kallsyms_test_init(void)
{
 struct task_struct *t;

 t = kthread_run_on_cpu(test_entry, NULL, 0, "kallsyms_test");
 if (IS_ERR(t)) {
  pr_info("Create kallsyms selftest task failed\n");
  return PTR_ERR(t);
 }

 return 0;
}
late_initcallkallsyms_test_init);

Messung V0.5 in Prozent
C=96 H=94 G=94

¤ Dauer der Verarbeitung: 0.25 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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.