385 lines
7.4 KiB
C
385 lines
7.4 KiB
C
/*
|
|
* drivers/platform/tegra/nvdumper/nvdumper_config.c
|
|
*
|
|
* Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/sched.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/irq.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/irqdesc.h>
|
|
#include <linux/idr.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/hashtable.h>
|
|
#include <soc/tegra/chip-id.h>
|
|
#include <linux/version.h>
|
|
/*
|
|
* hack
|
|
*/
|
|
#include <../../../kernel/workqueue_internal.h>
|
|
|
|
/*
|
|
* copied from kernel/kernel/workqueue.c
|
|
*/
|
|
#define BUSY_WORKER_HASH_ORDER 6
|
|
|
|
struct worker_pool {
|
|
spinlock_t lock; /* the pool lock */
|
|
int cpu; /* I: the associated cpu */
|
|
int node; /* I: the associated node ID */
|
|
int id; /* I: pool ID */
|
|
unsigned int flags; /* X: flags */
|
|
|
|
struct list_head worklist; /* L: list of pending works */
|
|
int nr_workers; /* L: total number of workers */
|
|
|
|
/* nr_idle includes the ones off idle_list for rebinding */
|
|
int nr_idle; /* L: currently idle ones */
|
|
|
|
struct list_head idle_list; /* X: list of idle workers */
|
|
struct timer_list idle_timer; /* L: worker idle timeout */
|
|
struct timer_list mayday_timer; /* L: SOS timer for workers */
|
|
|
|
/* a workers is either on busy_hash or idle_list, or the manager */
|
|
DECLARE_HASHTABLE(busy_hash, BUSY_WORKER_HASH_ORDER);
|
|
/* L: hash of busy workers */
|
|
|
|
/* see manage_workers() for details on the two manager mutexes */
|
|
struct mutex manager_arb; /* manager arbitration */
|
|
struct mutex manager_mutex; /* manager exclusion */
|
|
struct idr worker_idr;
|
|
/* MG: worker IDs and iteration */
|
|
|
|
struct workqueue_attrs *attrs; /* I: worker attributes */
|
|
struct hlist_node hash_node; /* PL: unbound_pool_hash node */
|
|
int refcnt;
|
|
/* PL: refcnt for unbound pools */
|
|
|
|
/*
|
|
* The current concurrency level. As it's likely to be accessed
|
|
* from other CPUs during try_to_wake_up(), put it in a separate
|
|
* cacheline.
|
|
*/
|
|
atomic_t nr_running ____cacheline_aligned_in_smp;
|
|
|
|
/*
|
|
* Destruction of pool is sched-RCU protected to allow dereferences
|
|
* from get_work_pool().
|
|
*/
|
|
struct rcu_head rcu;
|
|
} ____cacheline_aligned_in_smp;
|
|
|
|
|
|
#define MAX_KEY_LENGTH 32
|
|
#define MAX_GROUP_LENGTH 32
|
|
|
|
struct config_option {
|
|
char key[MAX_KEY_LENGTH];
|
|
char group[MAX_GROUP_LENGTH];
|
|
uint64_t value;
|
|
};
|
|
|
|
const struct config_option nvdumper_config[] = {
|
|
{
|
|
"stack",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, stack)
|
|
},
|
|
{
|
|
"state",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, state)
|
|
},
|
|
#if defined(CONFIG_SMP)
|
|
{
|
|
"on_cpu",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, on_cpu)
|
|
},
|
|
#endif
|
|
{
|
|
"exit_state",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, exit_state)
|
|
},
|
|
{
|
|
"thread_group",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, thread_group)
|
|
},
|
|
{
|
|
"pid",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, pid)
|
|
},
|
|
{
|
|
"comm",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, comm)
|
|
},
|
|
{
|
|
"tasks",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, tasks)
|
|
},
|
|
{
|
|
"mm",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, mm)
|
|
},
|
|
{
|
|
"parent",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, parent)
|
|
},
|
|
#if defined(CONFIG_ARM64)
|
|
{
|
|
"thread",
|
|
"task_struct",
|
|
(uint64_t)offsetof(struct task_struct, thread)
|
|
},
|
|
{
|
|
"cpu_context",
|
|
"thread_struct",
|
|
(uint64_t)offsetof(struct thread_struct, cpu_context)
|
|
},
|
|
#if (KERNEL_VERSION(4, 9, 135) > LINUX_VERSION_CODE)
|
|
{
|
|
"on_cpu",
|
|
"thread_info",
|
|
(uint64_t)offsetof(struct thread_info, cpu)
|
|
},
|
|
#endif
|
|
{
|
|
"fp",
|
|
"cpu_context_save",
|
|
(uint64_t)offsetof(struct cpu_context, fp)
|
|
},
|
|
{
|
|
"sp",
|
|
"cpu_context_save",
|
|
(uint64_t)offsetof(struct cpu_context, sp)
|
|
},
|
|
{
|
|
"pc",
|
|
"cpu_context_save",
|
|
(uint64_t)offsetof(struct cpu_context, pc)
|
|
},
|
|
#endif
|
|
#if defined(CONFIG_ARM)
|
|
{
|
|
"cpu_context",
|
|
"thread_info",
|
|
(uint64_t)offsetof(struct thread_info, cpu_context)
|
|
},
|
|
{
|
|
"fp",
|
|
"cpu_context_save",
|
|
(uint64_t)offsetof(struct cpu_context_save, fp)
|
|
},
|
|
{
|
|
"sp",
|
|
"cpu_context_save",
|
|
(uint64_t)offsetof(struct cpu_context_save, sp)
|
|
},
|
|
{
|
|
"pc",
|
|
"cpu_context_save",
|
|
(uint64_t)offsetof(struct cpu_context_save, pc)
|
|
},
|
|
#endif
|
|
{
|
|
"mmap",
|
|
"mm_struct",
|
|
(uint64_t)offsetof(struct mm_struct, mmap)
|
|
},
|
|
{
|
|
"pgd",
|
|
"mm_struct",
|
|
(uint64_t)offsetof(struct mm_struct, pgd)
|
|
},
|
|
{
|
|
"vm_mm",
|
|
"vm_area_struct",
|
|
(uint64_t)offsetof(struct vm_area_struct, vm_mm)
|
|
},
|
|
{
|
|
"vm_start",
|
|
"vm_area_struct",
|
|
(uint64_t)offsetof(struct vm_area_struct, vm_start)
|
|
},
|
|
{
|
|
"vm_end",
|
|
"vm_area_struct",
|
|
(uint64_t)offsetof(struct vm_area_struct, vm_end)
|
|
},
|
|
{
|
|
"vm_pgoff",
|
|
"vm_area_struct",
|
|
(uint64_t)offsetof(struct vm_area_struct, vm_pgoff)
|
|
},
|
|
{
|
|
"vm_file",
|
|
"vm_area_struct",
|
|
(uint64_t)offsetof(struct vm_area_struct, vm_file)
|
|
},
|
|
{
|
|
"vm_next",
|
|
"vm_area_struct",
|
|
(uint64_t)offsetof(struct vm_area_struct, vm_next)
|
|
},
|
|
{
|
|
"vm_flags",
|
|
"vm_area_struct",
|
|
(uint64_t)offsetof(struct vm_area_struct, vm_flags)
|
|
},
|
|
{
|
|
"f_path",
|
|
"file",
|
|
(uint64_t)offsetof(struct file, f_path)
|
|
},
|
|
{
|
|
"dentry",
|
|
"path",
|
|
(uint64_t)offsetof(struct path, dentry)
|
|
},
|
|
{
|
|
"d_name",
|
|
"dentry",
|
|
(uint64_t)offsetof(struct dentry, d_name)
|
|
},
|
|
{
|
|
"name",
|
|
"qstr",
|
|
(uint64_t)offsetof(struct qstr, name)
|
|
},
|
|
{
|
|
"irq_data",
|
|
"irq_desc",
|
|
(uint64_t)offsetof(struct irq_desc, irq_data)
|
|
},
|
|
{
|
|
"kstat_irqs",
|
|
"irq_desc",
|
|
(uint64_t)offsetof(struct irq_desc, kstat_irqs)
|
|
},
|
|
{
|
|
"action",
|
|
"irq_desc",
|
|
(uint64_t)offsetof(struct irq_desc, action)
|
|
},
|
|
{
|
|
"name",
|
|
"irq_desc",
|
|
(uint64_t)offsetof(struct irq_desc, name)
|
|
},
|
|
{
|
|
"chip",
|
|
"irq_data",
|
|
(uint64_t)offsetof(struct irq_data, chip)
|
|
},
|
|
{
|
|
"name",
|
|
"irq_chip",
|
|
(uint64_t)offsetof(struct irq_chip, name)
|
|
},
|
|
{
|
|
"name",
|
|
"irq_action",
|
|
(uint64_t)offsetof(struct irqaction, name)
|
|
},
|
|
{
|
|
"idle_list",
|
|
"worker_pool",
|
|
(uint64_t)offsetof(struct worker_pool, idle_list)
|
|
},
|
|
{
|
|
"busy_hash",
|
|
"worker_pool",
|
|
(uint64_t)offsetof(struct worker_pool, busy_hash)
|
|
},
|
|
{
|
|
"entry",
|
|
"worker",
|
|
(uint64_t)offsetof(struct worker, entry)
|
|
},
|
|
{
|
|
"hentry",
|
|
"worker",
|
|
(uint64_t)offsetof(struct worker, hentry)
|
|
},
|
|
{
|
|
"current_work",
|
|
"worker",
|
|
(uint64_t)offsetof(struct worker, current_work)
|
|
},
|
|
{
|
|
"current_func",
|
|
"worker",
|
|
(uint64_t)offsetof(struct worker, current_func)
|
|
},
|
|
{
|
|
"task",
|
|
"worker",
|
|
(uint64_t)offsetof(struct worker, task)
|
|
},
|
|
{
|
|
"sku_id",
|
|
"tegra_sku_info",
|
|
(uint64_t)offsetof(struct tegra_sku_info, sku_id)
|
|
},
|
|
{
|
|
"cpu_speedo_value",
|
|
"tegra_sku_info",
|
|
(uint64_t)offsetof(struct tegra_sku_info, cpu_speedo_value)
|
|
},
|
|
{
|
|
"cpu_iddq_value",
|
|
"tegra_sku_info",
|
|
(uint64_t)offsetof(struct tegra_sku_info, cpu_iddq_value)
|
|
},
|
|
{
|
|
"soc_speedo_value",
|
|
"tegra_sku_info",
|
|
(uint64_t)offsetof(struct tegra_sku_info, soc_speedo_value)
|
|
},
|
|
{
|
|
"soc_iddq_value",
|
|
"tegra_sku_info",
|
|
(uint64_t)offsetof(struct tegra_sku_info, soc_iddq_value)
|
|
},
|
|
{
|
|
"gpu_speedo_value",
|
|
"tegra_sku_info",
|
|
(uint64_t)offsetof(struct tegra_sku_info, gpu_speedo_value)
|
|
},
|
|
{
|
|
"gpu_iddq_value",
|
|
"tegra_sku_info",
|
|
(uint64_t)offsetof(struct tegra_sku_info, gpu_iddq_value)
|
|
},
|
|
{
|
|
"id_and_rev",
|
|
"tegra_sku_info",
|
|
(uint64_t)offsetof(struct tegra_sku_info, id_and_rev)
|
|
}
|
|
};
|
|
|
|
EXPORT_SYMBOL(nvdumper_config);
|