keywords: fec housekeeping_update
timer_cancel
tcp_timewait_state_process TCP_TIMEWAIT_LEN inet_twsk_reschedule __inet_twsk_schedule mod_timer inet_twsk_alloc timer_setup -> TIMER_PINNED tw_timer_handler inet_twsk_kill
tcp_keepalive_timer
trace_softirq_raise softirq_raise DEFINE_EVENT ->
debug_deactivate
isolcpus non_isolcpus sched_load_balance /sys/kernel/debug/sched/domains update_sched_domain_debugfs SMT is the hyperthreading domain, so it's going to be just that CPU and its thread siblings MC is multi-core, should be all CPUs that share the same last-level cache
newidle_balance
normal_prio __normal_prio sched_core_enqueue rb_sched_core_less __sched_core_less prio_less __task_prio MAX_RT_PRIO dl_time_before cfs_prio_less rq_attach_root raw_spin_rq_lock_irqsave _raw_spin_rq_lock_irqsave raw_spin_rq_lock raw_spin_rq_lock_nested raw_spin_lock_nested _raw_spin_lock_nested do_raw_spin_trylock arch_spin_trylock queued_spin_trylock spin_acquire -> raw_spin_rq_unlock
sysctl_timer_migration timers_migration_enabled
timer_migration_handler timers_migration_enabled
raw_smp_processor_id this_cpu_read(pcpu_hot.cpu_number) #define this_cpu_read(pcp) __pcpu_size_call_return(this_cpu_read_, pcp) smp_processor_id __smp_processor_id __this_cpu_read(pcpu_hot.cpu_number)
delayacct task_delay_info delayacct_init delayacct_end
CONFIG_TICK_ONESHOT tick_irq_enter hotplug_cpu__broadcast_tick_pull tick_setup_hrtimer_broadcast tick-oneshot.o tick_program_event ... tick-sched.o tick_get_tick_sched CONFIG_NO_HZ_COMMON TICK_ONESHOT CONFIG_NO_HZ_IDLE Idle dynticks system (tickless idle) (former NO_HZ "Old Idle dynticks config") CONFIG_NO_HZ_FULL Full dynticks system (tickless) CPU_ISOLATION CONFIG_IRQ_WORK irq_work_run irq_work_needs_cpu irq_work_tick_soft
CONFIG_HZ_PERIODIC
CONFIG_RT_MUTEXES RT_MUTEXES include/linux/rtmutex.h rt_mutex_init rt_mutex_lock rt_mutex rt_mutex_base raw_spinlock_t kernel/locking/rtmutex_api.c kernel/locking/rtmutex.c kernel/locking/rtmutex_common.h
CONFIG_PREEMPT_RT PREEMPT_RT
include/linux/rwbase_rt.h rwbase_rt include/linux/rwlock_rt.h include/linux/spinlock_rt.h spin_lock spin_lock_bh rt_spin_lock -> spin_lock_irq rt_spin_lock kernel/locking/ww_rt_mutex.c kernel/locking/spinlock_rt.c kernel/locking/rwase_rt.c
include/linux/rwlock_types.h rwlock_t include/linux/spinlock_types.h spinlock_t rt_mutex_base
include/linux/sched/mm.h mmdrop_sched &realtime_attr.attr ./include/linux/local_lock_internal.h local_lock_t include/linux/mutex.h struct mutex { struct rt_mutex_base rtmutex; } ./kernel/softirq.c softirq_ctrl ... ./include/linux/sched/task.h put_task_struct ./include/linux/sched.h schedule_rtlock ./include/linux/preempt.h preempt_disable_nested preempt_disable preempt_enable_nested preempt_enable preempt_model_rt irq_exit_rcu a_irq_exit_rcu wake_timersd if (!IS_ENABLED(CONFIG_PREEMPT_RT)) { cpu_relax();
static bool use_softirq = !IS_ENABLED(CONFIG_PREEMPT_RT);
sched_init_debug debugfs_create_dir debugfs_create_file debugfs_create_u64
PATCH: softirq: Wake ktimers thread also in softirq. If the hrtimer is raised while a softirq is processed then it does not wake the corresponding ktimers thread.
This is due to the optimisation in the irq-exit path which is also used to wake the ktimers thread. __irq_exit_rcu [irq_exit] if (!in_interrupt() && local_softirq_pending()) invoke_softirq(); if (IS_ENABLED(CONFIG_PREEMPT_RT) && local_pending_timers() && !(in_nmi() | in_hardirq())) wake_timersd();
For the other softirqs, this is okay because the additional softirq bits will be handled by the currently running softirq handler.
The timer related softirq bits are added to a different variable and rely on the ktimers thread.
As a consuequence the wake up of ktimersd is delayed until the next timer tick.
Always wake the ktimers thread if a timer related softirq is pending.
PELT - Per-Entity Load Tracking
echo timerlat > current_tracer
late_initcall init_osnoise_tracer register_tracer osnoise_tracer osnoise_tracer_stop osnoise_workload_stop osnoise_unhook_events ^ timerlat_tracer timerlat_tracer_start osnoise_workload_start ^ __osnoise_tracer_start start_per_cpu_kthreads start_kthread osnoise_main timerlat_main hrtimer_init(&tlat->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD); hrtimer_cb_get_time get_time s.timer_latency = diff trace_timerlat_sample osnoise_instances __trace_timerlat_sample trace_buffer_lock_reserve __trace_buffer_lock_reserve ring_buffer_lock_reserve rb_reserve_next_event timerlat_irq < __run_hrtimer time_get trace_clock_local sched_clock tlat->count++ s.timer_latency = diff trace_timerlat_sample wait_next_period hrtimer_start schedule
grep -E '[0-9]{5} ns' trace
brew mock-config --tag rhel-8.6.0-z-build --arch x86_64 -o ~/main/rhel-8.6.0.cfg -> config_opts['basedir'] = '/home/juril/mock'
make BUILDID=".myid" rh-srpm
mock -r /tmp/rhel-8.6.0.cfg /home/juril/rhel-8/redhat/rpm/SRPMS/kernel-rt-4.18.0-372.57.1.rt7.215.el8_6.myid.src.rpm
ls ~/main/mock/rhel-8.6.0-z-build-repo_*/root/builddir/build/RPMS/
rcu_nocb_setup "rcu_nocbs"
kernel/sched/build_utility.c:104:#
update_isolation_cpumasks lockdep_assert_cpus_held(); housekeeping_exlude_isolcpus housekeeping_update - irq_migrate_all_off_cpu irq_affinity_adjust irq_restore_affinity_of_irq migrate_one_irq_from_isolated +__irq_can_set_affinity irq_set_affinity -irq_set_affinity_locked ->
find_lowest_rq cpumask_any_distribute distribute_cpu_mask_prev cpumask_any_and_distribute distribute_cpu_mask_prev
sed 's/ /\n/g;s/=/=\n\t/g' /proc/cmdline
memcg_stat_show __mem_cgroup_flush_stats+75 mem_cgroup_flush_stats do_flush_stats cgroup_rstat_flush cgroup_rstat_flush_irqsafe blkcg_print_blkgs
long _raw_write_unlock_irq kernel_clone exit_notify run_timer_softirq
do_notify_resume do_signal get_signal do_group_exit do_exit exit_notify _raw_write_unlock_irq __raw_write_unlock_irq do_raw_write_unlock local_irq_enable raw_local_irq_enable arch_local_irq_enable preempt_enable
__bpf_kfunc
irq_domain irq_matrix_debug_show head -n-1 /sys/kernel/debug/irq/domains/*
kernel/stop_machine.c - kernel/cpu.c cpu_stop_init - cpuhp_threads_init
cpu_stop_threads - cpuhp_threads smpboot_thread_fn cpu_stopper_thread multi_cpu_stop kernel/cpu.c: - cpuhp_thread_fun take_cpu_down arch/x86/kernel/smpboot.c: native_cpu_disable cpu_disable_common - cpuhp_invoke_callback arch/x86/kernel/irq.c fixup_irqs kernel/irq/cpuhotplug.c: irq_migrate_all_off_this_cpu - irq_affinity_online_cpu migrate_one_irq - irq_restore_affinity_of_irq irqd_set_managed_shutdown - irq_startup
cpuhp_up_callbacks cpuhp_invoke_callback smpboot_create_threads perf_event_init_cpu x86_pmu_prepare_cpu page_alloc_cpu_online random_prepare_cpu workqueue_prepare_cpu hrtimers_prepare_cpu smpcfd_prepare_cpu relay_prepare_cpu rcutree_prepare_cpu topology_add_dev trace_rb_cpu_prepare timers_prepare_cpu kvmclock_setup_percpu crash_cpuhp_online cpuhp_kick_ap_alive arch_cpuhp_kick_ap_alive kick_ap_alive -> native_kick_ap do_boot_cpu initial_code = start_secondary cpuhp_bringup_ap cpuhp_kick_ap cache_ap_online sched_cpu_starting sched_core_cpu_starting cpu_smt_mask sched_rq_cpu_starting sched_tick_start -> x86_pmu_starting_cpu intel_pmu_cpu_starting kvm_online_cpu __hardware_enable_nolock smpboot_unpark_threads smpboot_unpark_thread kthread_unpark irq_affinity_online_cpu ...
cpuhp_down_callbacks... cpuhp_invoke_callback -> rcutree_offline_cpu workqueue_offline_cpu tmigr_cpu_offline rapl_cpu_offline perf_event_exit_cpu blk_mq_hctx_notify_offline -> smpboot_park_threads sched_cpu_wait_empty balance_hotplug_wait kvm_offline_cpu takedown_cpu -> tick_cpu_dying -- stops tick_nohz_handler tick_do_timer_cpu - time keeper cpu tick_sched_timer_dying tick_sched_timer_cancel hrtimer_cancel -> tick_offline_cpu tick_broadcast_offline(cpu); tick_broadcast_oneshot_offline(cpu); tick_shutdown_broadcast clockevents_shutdown clockevents_switch_state(dev, CLOCK_EVT_STATE_SHUTDOWN); hrtimers_cpu_dying bpftrace -e 'kprobe:hrtimers_cpu_dying { @[kstack()] = count(); }' smpcfd_dying_cpu x86_pmu_dying_cpu rcutree_dying_cpu sched_cpu_dying sched_tick_stop cache_ap_offline
cpu_down_maps_locked __cpu_down_maps_locked _cpu_down cpus_write_lock(); percpu_down_write cpu_hotplug_lock cpuhp_down_callbacks cpuhp_invoke_callback_range __cpuhp_invoke_callback_range cpuhp_invoke_callback timers_dead_cpu ->
cpu_subsys_online
mm/percpu.c
per_cpu_ptr per_cpu_offset __per_cpu_offset
include/linux/cpumask.h cpumask DECLARE_BITMAP cpumask_weight cpumask_bits cpumask_weight_and cpumask_bits cpumask.bits cpumask_any_and cpumask_first_and find_first_and_bit _find_first_and_bit IND_FIRST_BIT for __ffs bsf - Bit Scan Forward break cpumask_intersects bitmap_intersects __bitmap_intersects for & return
kernel/smp.c __smp_call_single_queue call_single_data_t (CSD) trace_csd_queue_cpu_enabled trace_csd_queue_cpu send_call_function_single_ipi smp_call_function_many_cond _RET_IP_ trace_csd_queue_cpu csd_do_func trace_csd_function_entry trace_csd_function_exit include/trace/events/csd.h
cpu control isolation & housekeeping drain_all_stock !cpu_is_isolated schedule_work_on(cpu, &stock->work); vmstat_shepherd !cpu_is_isolated queue_delayed_work_on __queue_delayed_work
schedule_work_on queue_work_on -> cpu_is_isolated !housekeeping_test_cpu(cpu, HK_TYPE_DOMAIN) || !housekeeping_test_cpu(cpu, HK_TYPE_TICK) || cpuset_cpu_is_isolated include/linux/cpuset.h cpumask_test_cpu(cpu, isolated_cpus);
kernel/acct.c sys_acct acct_on bsd_acct_struct acct_file_reopen
kernel/capability.c sys_capget kernel_cap_t cap_get_target_pid sys_capset lkm2 cred security_capset lkm2 prepare_creds commit_creds
kernel/exec_domain.c sys_personality
kernel/exit.c sys_exit_group do_group_exit sys_exit do_exit exit_mm mm_release exit_sem exit_files exit_fs check_stack_usage exit_thread cgroup_exit exit_notify tasklist_lock write_lock_irq forget_original_parent release_task write_lock_irq sys_wait4 do_wait do_wait_thread
sys_waitid do_wait
kernel/fork.c sys_set_tid_address current->clear_child_tid = tidptr; sys_unshare sys_fork ▻
kernel/futex.c futex_init futex_queues sys_futex lkm2 do_futex futex_wait futex_wake sys_get_robust_list current->robust_list sys_set_robust_list current->robust_list
sys_getgroups kernel/groups.c current_cred cred->group_info sys_setgroups kernel/groups.c
kernel/itimer.c sys_getitimer do_getitimer itimer_get_remtime ktime_to_timeval ktime_t ▻ timeval get_cpu_itimer thread_group_cputimer sys_setitimer do_setitimer hrtimer_start set_cpu_itimer
kernel/kexec.c sys_kexec_load kimage_normal_alloc kimage_alloc_control_pages kimage_alloc_normal_control_pages kimage_alloc_pages kimage_crash_alloc kimage_alloc_control_pages kimage_alloc_crash_control_pages
kernel/module.c sys_delete_module ▻ sys_init_module ▻
kernel/perf_event.c sys_perf_event_open perf_event_open perf_event_attr perf_event perf_event_alloc anon_inode_getfd ▻ current->perf_event_list perf_event_init <- sched_init init_hw_perf_events x86/kernel/cpu/perf_event.c intel_pmu_init
kernel/posix-timers.c sys_clock_getres CLOCK_DISPATCH posix_clocks common_clock_getres sys_clock_gettime CLOCK_DISPATCH sys_clock_nanosleep hrtimer_nanosleep -> sys_clock_settime sys_timer_create k_itimer alloc_posix_timer sys_timer_delete sys_timer_getoverrun sys_timer_gettime sys_timer_settime
kernel/printk.c sys_syslog ▻
kernel/ptrace.c sys_ptrace ▻ lkm2 lock_kernel arch_ptrace ptrace_request ptrace_resume
kernel/sys.c sys_getpgid find_task_by_vpid ▻ task_pgrp task->group_leader->pids[PIDTYPE_PGID].pid sys_getpgrp sys_getpgid sys_getpriority task_nice PRIO_TO_NICE((p)->static_prio); sys_getresgid cred = current_cred sys_getresuid cred = current_cred sys_getrlimit current->signal->rlim sys_getrusage k_getrusage sys_getsid sys_prctl perf_event_task_enable perf_event_enable sys_reboot ▻ sys_setdomainname utsname domainname sys_setfsgid sys_setfsuid sys_setgid sys_sethostname utsname nodename sys_setpgid task_pid_vnr task_pgrp change_pid sys_setpriority set_one_prio sys_setregid sys_setresgid sys_setresuid sys_setreuid sys_setrlimit sys_setsid sys_setuid sys_times ▻ sys_umask current->fs->umask
kernel/sysctl_binary.c sys_sysctl do_sysctl ▻
kernel/time.c sys_adjtimex do_adjtimex sys_gettimeofday ▻ sys_settimeofday do_sys_settimeofday do_settimeofday sys_time ▻
kernel/timer.c sys_alarm alarm_setitimer do_setitimer ▻ sys_getegid sys_geteuid sys_getgid sys_getpid sys_getppid sys_gettid sys_getuid sys_sysinfo lkm2 do_sysinfo si_meminfo totalram_pages lkm2 totalhigh_pages global_page_state(NR_FREE_PAGES) si_swapinfo swap_info lkm2 total_swap_pages tracer_alloc_buffers tracer_init_debugfs
kubelet ksys_read vfs_read kernfs_fop_read_iter seq_read_iter kernfs_seq_show cgroup_seqfile_show memory_stat_show < memory_files taskset --cpu-list 0 cat /sys/fs/cgroup/memory.stat > /dev/nul memory_stat_format.constprop.0 mem_cgroup_flush_stats should_flush_stats do_flush_stats cgroup_rstat_flush __bpf_kfunc 200+ us cgroup_rstat_lock spin_lock_irq raw_spin_lock_irq -> cgroup_rstat_flush_locked 200+us -> cgroup_rstat_updated_list 0-20 us -> need_resched spin_unlock_irq raw_spin_unlock_irq _raw_spin_unlock_irq
cgroup_account_cputime __cgroup_account_cputime cgroup_base_stat_cputime_account_end cgroup_rstat_updated
cgroup_base_stat_cputime_show cgroup_rstat_flush_hold cgroup_rstat_flush_release
_raw_spin_unlock_irq el1h_64_irq ... try_to_wake_up
kworker/u256:6 mem_cgroup_flush_stats+132
ret_from_fork kthread worker_thread process_one_work wb_workfn wb_do_writeback wb_writeback spin_lock(&wb->list_lock); wb_over_bg_thresh mem_cgroup_wb_stats mem_cgroup_flush_stats_atomic do_flush_stats cgroup_rstat_flush_atomic 200+ us spin_lock_irqsave cgroup_rstat_flush_locked -> _raw_spin_unlock_irqrestore
copy-content
ksys_write vfs_write xfs_file_write_iter xfs_file_buffered_write iomap_file_buffered_write iomap_write_iter balance_dirty_pages_ratelimited_flags balance_dirty_pages mem_cgroup_wb_stats mem_cgroup_flush_stats_atomic 6 mem_cgroup_flush_stats_ratelimited mem_cgroup_flush_stats cgroup_rstat_flush_atomic
cgroup_rstat_updated_list: The _irqsave() is needed because cgroup_rstat_lock is spinlock_t which is a sleeping lock on PREEMPT_RT. Acquiring this lock with the _irq() suffix only disables interrupts on a non-PREEMPT_RT kernel. The raw_spinlock_t below disables interrupts on both configurations. The _irqsave() ensures that interrupts are always disabled and later restored.
kernel/cgroup/rstat.c cgroup_rstat_flush_locked cgroup_rstat_updated_list longman cgroup_rstat_cpu_lock raw_spin_lock_irqsave(cpu_lock, flags);
cgroup_rstat_push_children cgroup_rstat_cpu /* if @may_sleep, play nice and yield if necessary */ if (may_sleep && (need_resched() || spin_needbreak(&cgroup_rstat_lock))) { spin_unlock_irq(&cgroup_rstat_lock); if (!cond_resched()) cpu_relax(); spin_lock_irq(&cgroup_rstat_lock); }
"cpu_dma_latency" cpu_latency_qos_write cpu_latency_qos_update_request cpu_latency_qos_apply(req, PM_QOS_UPDATE_REQ, new_value); pm_qos_update_target plist_node_init plist_add pm_qos_set_value target_value wake_up_all_idle_cpus
apply_constraint pm_qos_read_value set_latency_tolerance
Max Latencies: 08124
echo 2 > /proc/irq/24/smp_affinity_list; cat /proc/interrupts; dmesg -c
mlx5e_open_channel ... netif_set_xps_queue mlx5_alloc_irq_vectors
power dnf install -yq kernel-tools turbostat cpupower grep '' -r /sys/devices/system/cpu/cpu0/cpuidle/
cpuidle_state cpuidle_state_usage
online irq_affinity_online_cpu
attribute_group attribute name mode API sample usage module_notes_attrs bin_attribute module_notes_read add_notes_attrs sysfs_bin_attr_init sysfs_create_bin_file kobject_init_and_add mod_sysfs_setup module_add_modinfo_attrs sysfs_attr_init sysfs_create_file ▻ example_init kobject_create_and_add kobject_create kzalloc dynamic_kobj_ktype kobject_init kobject_init_internal kobject_add ▻ kobject_init_and_add kobject_init ▻ kobject_add_varg ▻ bin_attribute attribute sysfs_bin_attr_init sysfs_attr_init sysfs_create_dir - not used sysfs_create_file sysfs_add_file sysfs_add_file_mode x sysfs_make_dirent sysfs_new_dirent kobj_attribute (kobject.h) sysfs_init sysfs_fs_type sysfs_get_sb sysfs_fill_super sysfs_ops get_sb_single register_filesystem sysfs_create sysfs_ops
fs/proc
/proc/stat kstat_read_proc kstat
proc_cpuinfo_operations
CONFIG_PROC_FS proc_root_init do_rw_proc
sysctl_init register_proc_table proc_sys_file_operations proc_fs ▻ init_irq_proc
include/linux/module.h kernel/module.c
struct module (module_state) kernel_param lkm2
x sys_create_module sys_init_module load_module find_sec find_module module_alloc_update_bounds module_alloc mod_sysfs_init mod_sysfs_setup do_one_initcall sys_delete_module sys_query_module sys_get_kernel_syms
2.4 create_module() init_module() delete_module()
insmod - module.c module_init() <include/linux/init.h> - module_exit() <include/linux/init.h>
busybox insmod_main query_module new_get_kernel_symbols add_kernel_symbols create_module
kernel_module module_list
init_modules
MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT <include/linux/module.h> init_module() cleanup_module() EXPORT_SYMBOL() EXPORT_SYMTAB
Chapter 11 kmod and Advanced Modularization Contents: Loading Modules on Demand Intermodule Communication Version Control in Modules
Chapter 2 Building and Running Modules Contents: Kernel Modules Versus Applications Compiling and Loading The Kernel Symbol Table Initialization and Shutdown Using Resources Automatic and Manual Configuration Doing It in User Space
/etc/modules, /etc/conf.modules
sysctl.h: General linux system control interface /linux/include/linux/sysctl.h _LINUX_SYSCTL_H /linux/kernel/sysctl.c do_sysctl proc_sys_file_operations proc_fs ▻
system_calls #337
sys_syscall sys_call_table syscall_table_32.S arch/x86/kernel/syscall_64.c ./source/arch/x86/include/asm/unistd_64.h ia32_sys_call_table ia32entry.S
__vectors_start
arm vector_table vector_swi arm_syscall ptrace_break __show_regs show_regs_common dmi_get_system_info(DMI_SYS_VENDOR); dmi_get_system_info(DMI_PRODUCT_NAME) dmi_get_system_info(DMI_BOARD_NAME); c_backtrace __irq_entry IPSR Interrupt Program Status Register irq = ipsr -16 asm_do_IRQ handle_IRQ generic_handle_irq generic_handle_irq_desc irq_to_desc desc->handle_irq
??? system_call (arch/i386/kernel/entry.S) sys_call_table (arch/i386/kernel/entry.S) sys_open ▻
vfs_read __vfs_read file->f_op->read new_sync_read filp->f_op->read_iter do_readv_writev ▻ ... tty_read ▻ x do_sync_read generic_file_aio_read .aio_read sock_aio_read .aio_read sock->ops->recvmsg sock_common_recvmsg ssh ? tcp_recvmsg skb_copy_datagram_iovec memcpy_toiovec sys_write sys_socketcall __NR_socketcall
include/asm/uaccess.h copy_from_user copy_to_user
-
System Calls POSIX APIs and System Calls System Call Handler and Service Routines Kernel Wrapper Routines
sys_mmap2 sys_mmap lkm2 ksys_mmap_pgoff vm_mmap_pgoff do_mmap do_mmap_pgoff /mm/mmap.c get_unmapped_area get_area arch_get_unmapped_area_topdown find_vma ERR find_vma_prepare may_expand_vm mm_struct kmem_cache_alloc ▻ security_file_mmap security_ops->file_mmap generic_file_mmap generic_file_vm_ops vma_merge vma_link ▻ file file->f_op->mmap make_pages_present find_vma get_user_pages - zero copy __gup_longterm_locked sys_remap_file_pages find_vma
maps_open proc_pid_maps_op m_start get_task_mm get_gate_vma find_vma ▻
uevent_sock_list uevent_sock kobject_uevent_init lkm2 return register_pernet_subsys(&uevent_net_ops); uevent_net_ops uevent_net_init NETLINK_KOBJECT_UEVENT uevent_sock_list netlink_kernel_create(net, NETLINK_KOBJECT_UEVENT,
kobject_uevent lkm2 120 calls uevent_ops kobject_uevent_env uevent_ops->filter uevent_sock_list netlink_broadcast_filtered do_one_broadcast netlink_broadcast_deliver call_usermodehelper call_usermodehelper_keys
__netlink_create netlink_ops netlink_sendmsg netlink_broadcast netlink_broadcast_filtered
ftrace=function trace_buf_size=50M
? ftrace_filter=usb* ? ftrace_notrace=wait_for_xmit,pfn_valid,setup_per_zone_wmarks
echo 1 > /proc/sys/kernel/ftrace_dump_on_oops
mcount
API CONFIGFS_ATTR_STRUCT configfs_attribute CONFIGFS_ATTR show store config_item_init_type_name config_item_init config_group_init config_item_init kref_init atomic_set INIT_LIST_HEAD configfs_subsystem configfs_register_subsystem configfs_attach_group configfs_unregister_subsystem configfs_detach_group config_group config_item configfs_detach_group configfs_detach_group ci_namebuf ▻ dirname ci_name config_item_type ci_type ct_item_ops: configfs_item_operations .show_attribute .store_attribute .ct_attrs configfs_attribute * .ca_name ▻ filename .ca_mode
configfs_example_init mkdir -p config; mount -t configfs none config; modprobe configfs_sample cat config/01-childless/storeme config_group_init childless <- to_childless <- config_item configfs_subsystem x childless_attribute example_subsys : configfs_subsystem childless_subsys : childless config_item_type childless_type childless_attrs childless_attr_showme childless_attr_storeme childless_storeme_show to_childless config_item to_configfs_subsystem to_config_group childless_storeme_store L3 x childless_item_ops x childless_attr_show x childless_attr_store simple_children_subsys, simple_children_type simple_children_item_ops simple_children_release to_simple_children simple_children config_group container_of simple_children_group_ops :configfs_group_operations, simple_children_make_item .make_item simple_children_make_item kzalloc simple_child config_item_init_type_name config_item_init simple_child_type simple_child_item_ops simple_child_release simple_child_attrs CONFIGFS_ATTR simple_child config_item simple_child_attr_storeme simple_child_storeme_store simple_child_storeme_show to_simple_child container_of config_item config_item_init_type_name ▻ group_children_subsys group_children_type group_children_group_ops group_children_make_group config_group_init_type_name config_item_set_name config_group_init ▻ group_children_attrs group_children_attr_description group_children_description_show mutex_init configfs_register_subsystem ▻ x CHILDLESS_ATTR x CHILDLESS_ATTR_RO
dynamic_netconsole_init
configfs_file_operations configfs_read_file fill_read_buffer show_attribute misc_init misc_fops misc_open misc_mtx
debugfs debugfs_create_file
dma dma_ops request_dma enable_dma disable_dma
struct scatterlist sg_init_one sg_init_table sg_set_buf sg_set_page sg_assign_page
platform_driver ldt device_driver driver probe platform_set_drvdata dev_set_drvdata device_private_init driver_data platform_get_drvdata dev_get_drvdata dev->driver_data
<- module_platform_driver platform_driver_register ▻
dev_get_platdata dev->platform_data
platform_device name id .. platform_device_register
-> of_device_alloc platform_device_alloc
platform_device_register_simple platform_device_register_resndata platform_device_info platform_device_register_full platform_device_alloc ERR_PTR
data structures kfifo ldt __kfifo DECLARE_KFIFO kfifo_in_spinlocked spin_lock_irqsave ▻ kfifo_in spin_unlock_irqrestore ▻ idr DEFINE_IDR idr_init list_head ▻ rb_root RB_ROOT rb_insert_color
platform_driver platform_driver_probe register driver for non-hotpluggable platform_driver_register driver_register ▻ bus_add_driver driver_attach
arch_initcall __define_initcall __initcall device_initcall __define_initcall
module_init !MODULE __initcall ▻
module_param lkm2 module_param_named module_param_call __module_param_call kernel_param ▻ module_exit
pm_init kernel/sys.c sys_reboot stop_this_cpu set_cpu_online
kernel_restart kernel_restart_prepare device_shutdown machine_restart arch_reset cpu_reset kernel_halt kernel_kexec hibernate
#define flags_test(flags, mask) (((flags) & (mask)) == (mask))
context: GENMASK
TEST_OPCODE
Neighbor functions: set_mask_bits test_bit regmap_update_bits_check
similar func: regmap_set_bits regmap_test_bits https://lwn.net/Articles/821711/ TEST_FLAGS drivers/staging/rtl8723bs/include/basic_types.h CHK_FLAGS drivers/media/pci/solo6x10/solo6x10.h HAS_CAP drivers/soc/mediatek/mtk-pmic-wrap.c MTK_HAS_CAPS drivers/net/ethernet/mediatek/mtk_eth_soc.h MTK_HAS_FLAGS any_allowed TEST_OPCODE BITS_SET drivers/net/ethernet/qualcomm/emac/emac-mac.h drivers/gpu/drm/i915/display/intel_display_power.c all_bits_set TESTHI TEST_FLAG
# 3K cases in 1.5K files: grep -r --include '*.[ch]' -Pzo ".* & (.*)\) [!=]=[ \n].*\1.*\n"
# Complex cases, 275 results: grep -r --include '*.[ch]' -Pzo ".* & (\(.*\))\) [!=]=[ \n].*\1.*\n"
example in clone3_args_valid
vim -c '/& \((.*)\)) [!=]=[ \n].*\1'
vim -c ':%s/(\(\w\+\) & (\(.*\))) ==[ \n]\s*(\2)/flags_test(\1, \2)/g | %s/(\(\w\+\) & (\(.*\))) !=[ \n]\s*(\2))/!flags_test(\1, \2)/g' \ `grep -l -r --include '*.[ch]' -Pzo ".* & (\(.*\))\) [!=]=[ \n].*\1.*\n" kernel`
grep -l -r --include '*.[ch]' -Pzo ".* & (\(.*\))\) [!=]=[ \n].*\1.*\n" \ | xargs -n 1 \ vim -e -c '%s/(\([^(]\+\((\w\+)\)\?\) & (\([^)]*\))) ==[ \n]\s*(\3)/flags_test(\1, \3)/ge' \ -c '%s/(\([^(]\+\) & (\([^)]*\))) !=[ \n]\s*(\2)/!flags_test(\1, \2)/ge' \ -c 'wq'
grep -r --include '*.[ch]' -Hn ' & \(.*\)) == \1\>'
ioctl _IOC_DIR _IOC_DIR _IOC_TYPE _IOC_NR _IOC_SIZE _IO _IOC
Linux Driver Model
include/linux/device.h struct device ▻ struct class dev_name dev->init_name struct device_link
device_driver dev_pm_ops *pm -> bus_type -> module driver_register bus_type bus_register drivers/base/bus.c lkm2 subsystem bus_attribute attribute device_attribute driver_attribute kobject
probe
buses_init kset_create_and_add ▻ classes_init kset_create_and_add ▻ class_kset
/sys/class/ lkm2 ...
class_register __class_register kset_register ▻ class_create __class_create __class_register ▻ devices_init kset_create_and_add ▻ kobject_create_and_add ▻ subsystem_register ▻
cdev_add dev_set_name device_register ------------------------- xxx ! device_create device_create_vargs
device_register device_initialize kobject_init device_add device_add_attrs drivers/base/core.c 3.2.54 device_add_attributes(dev, class->dev_attrs); device_create_file device_add_groups(dev, class->dev_groups); sysfs_create_groups sysfs_create_group internal_create_group kernfs_create_dir create_files sysfs_add_file_mode_ns sysfs_file_kfops_rw sysfs_kf_seq_show ops->show bus_probe_device dev device_attach device dev bus_for_each_drv __device_attach struct device *dev = data driver_match_device ▻ driver_probe_device really_probe driver_sysfs_add probe device_create_file sysfs_create_file ▻ device_driver ▻ struct class_device class_device_create class_device_register class_device_initialize class_device_add class_device_create_file sysfs_create_file ▻ class_device_add_groups sysfs_create_group nouveau_hwmon_show_name struct class subsystem include/linux/kobject.h class_create ▻ kobject
linux/kobject.h kobject kref ?? hot_plug kobject_add -- sysfs kobject_add_varg kobject_set_name_vargs kobject_add_internal create_dir sysfs_create_dir create_dir ▻ populate_dir sysfs_create_file ▻ kset kset_create_and_add kset_uevent_ops *uevent_ops, kset_create kobject_set_name kobject_set_name_vargs kset_register kset_init kobject_add_internal ▻ kobject_uevent ▻ kobj_type xxx subsystem - sysfs subsystem_register x subsystem_init kset_register ▻ devices_subsys
Documentation/kobject.txt
/dev sys_mknod sys_mknodat new_decode_dev vfs_mknod security_inode_mknod
ext3_mknod init_special_inode def_blk_fops blkdev_open def_chr_fops chrdev_open kobj = kobj_lookup(cdev_map, inode->i_rdev, &idx); inode->i_cdev cdev filp->f_op->open def_fifo_fops fifo_open
inode near i_hash
union { struct pipe_inode_info *i_pipe; struct block_device *i_bdev; struct cdev *i_cdev; }; inode_operations setattr block_device
linux/cdev.h fs/char_dev.c cdev chrdev_init cdev_map lkm2 kobj_map_init(base_probe, &chrdevs_lock); request_module call_usermodehelper ▻ def_chr_fops cdev_alloc cdev_init kobject_init cdev_add ▻ register_chrdev - old one file_operations __register_chrdev __register_chrdev_region ▻ cdev_add lkm2 kobj_map cdev_map chrdev_open register_chrdev_region __register_chrdev_region chrdevs
vfsmount lkm3 dentry_open
system files sysfs ▻
head.S startup arch/sh/boot/compressed/head.S
decompress_kernel_addr: decompress_kernel gunzip lib/inflate.c output_ptr = (unsigned long)&_text+0x20001000; _start inflate gzip_mark flush_output flush_window misc.c
kernel_start_addr = _text + 0x1000
build/arch/sh/kernel/head.S:75 ./arch/arm/mach-lpc22xx/head.S _stext build/vmlinux 88002000 start_kernel ▻ build/arch/sh/kernel/head.S :75
secondary_startup_64_no_verify - x86_64_start_kernel -- x86_64_start_reservations start_kernel init/main.c boot_cpu_init set_cpu_active cpumask_set_cpu cpumask_check __cpu_active_mask cpu_active_mask set_cpu_present cpumask_set_cpu cpumask_clear_cpu __cpu_present_mask cpu_present_mask setup_arch lkm2 arch/x86/kernel/setup.c sh_mv_setup enable_early_printk scif_sercon_init SCIF_REG 0xfffe9800 register_console console_drivers platform_setup vmi_init early_trap_init ▻ early_cpu_init early_ioremap_init paging_init ▻ num_physpages lkm2 get_num_physpages initmem_init e820_register_active_regions e820_find_active_region add_active_range num_physpages = max_low_pfn
x86_init.oem.arch_setup setup_memory_map x86_init.resources.memory_setup default_machine_specific_memory_setup ▻ arm_memblock_init initrd_start = __phys_to_virt(phys_initrd_start);
page_alloc_init parse_early_param boot_command_line parse_early_options trap_init near early_trap_init arch/x86/kernel/traps.c cpu_init syscall_init entry_SYSCALL_64 arch/x86/entry/entry_64.S do_syscall_64 sys_call_table swapgs_restore_regs_and_return_to_usermode native_iret native_irq_return_iret iretq USERGS_SYSRET64 swapgs sysretq see also early_trap_init set_system_trap_gate x set_system_gate lcall7/lcall27 call gates; @unix (./arch/i386/kernel/entry.S)
set_system_trap_gate(SYSCALL_VECTOR, &system_call); SYSCALL_VECTOR 0x80
mm_init near thread_info_cache_init init/main.c lkm2 page_cgroup_init_flatmem mem_init lkm2 memblock_free_all totalram_pages_add _totalram_pages pci_iommu_alloc pfn_to_page pfn = Page Frame Number ... num_physpages nr_free_pages ▻ totalhigh_pages kmem_cache_init lkm2 slob slab slub SLOB EMBEDDED Simple Allocator SLAB regular slab allocator SLUB Unqueued Allocator pgtable_cache_init vmalloc_init lkm2 vmlist lkm2 vfs_caches_init mnt_init init_rootfs
sched_init ▻ parse_options console_init rest_init ->
x kernel_thread_helper > kernel_init > prepare_namespace > mount_root > mount_block_root
kernel_init kernel_init_freeable
init in kernel_thread, near run_init_process populate_rootfs via rootfs_initcall initrd_start __initramfs_start unpack_to_rootfs write_buffer do_start header_buf read_into
gunzip do_basic_setup driver_init devices_subsys devices_init ▻ sysctl_init (proc) ▻ pci_init x pcibios_init x pcibios_resource_survey x pcibios_allocate_bus_resources sock_init sk_init start_context_thread context_thread schedule do_initcalls populate_rootfs ▻ via rootfs_initcall
prepare_namespace # mounts saved_root_name < __setup("root=", root_dev_setup); initrd_load init/do_mounts_initrd.c if CONFIG_BLK_DEV_INITRD rd_load_image if CONFIG_BLK_DEV_RAM identify_ramdisk_image SQUASHFS_MAGIC 0x73717368 "filesystem found at block" "RAMDISK: image too big"
mount_root create_dev sys_mknod mount_block_root root_mount_data get_fs_names get_filesystem_list do_mount_root sys_mount ▻ rd_load_disk rd_load_image ▻ run_init_process kernel_execve old execve sys_execve ▻
/sbin/init init_main (busybox) init_action_list parse_inittab console_init /etc/inittab
init_cramfs_fs cramfs_uncompress_init register_filesystem cramfs_fs_type cramfs_get_sb cramfs_fill_super cramfs_uncompress_block
{ virtualization kvm Address: virtual/physical/frame guest/host gva_t guest virtual address gpa_t guest physical address gfn_t guest frame number hva_t host virtual address hpa_t host physical address hfn_t host frame number other tdp_page_fault PMU Performance Monitoring Unit kvm_guest_init arch/x86/kernel/kvm.c kvm_para_has_feature kvm_para_has_hint pci_sriov_get_totalvfs pci_num_vf svm_init kvm_init vmx_init kvm_init kvm_init kvm_arch_init kvm_chardev_ops kvm_dev_ioctl ./virt/kvm/kvm_main.c kvm_dev_ioctl_create_vm kvm kvm_vm_fops kvm_vm_ioctl, kvm_vm_ioctl_create_vcpu kvm_arch_vcpu_create kvm_x86_ops- vmx_create_vcpu svm_create_vcpu kvm_create_vm
vmx_x86_ops hardware_setup vmx_set_ms MSR (Model Specific Register) kvm_arch_dev_ioctl KVM_GET_MSRS kvm_setup_async_pf Tsirkin kvm_vm_ioctl_check_extension vhost_new_msg virtcons_remove remove_vqs virtio_device_for_each_vq drivers/virtio SRIOV Single Root I/O Virtualization (SRIOV SR-IOV) numvfs sriov_numvfs_show num_VFs virtio_pci_driver virtio_pci_probe virtio_pci_modern_probe virtio_pci_sriov_configure pci_enable_sriov -> virtio_pci_modern_probe PCI_EXT_CAP_ID_SRIOV PCI_EXT_CAP_ID_MRIOV pci_init_capabilities pci_msi_setup_pci_dev pci_find_capability __pci_bus_find_cap_start PCI_STATUS pci_bus_read_config_word pci_find_next_capability PCI_CAP_ID_MSI PCI_CAP_ID_MSIX msix_cap pci_msix_clear_and_set_ctrl trl_(); trvs_(dev_name(dev)); trvd(irq); pci_iov_init pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV); pci_find_next_ext_capability pci_read_config_dword PCI_EXT_CAP_ID PCI_EXT_CAP_NEXT sriov_init pci_sriov PCI_SRIOV_CTRL PCI_SRIOV_TOTAL_VF is_physfn
pci_enable_sriov is_physfn CONFIG_PCI_IOV pci_sriov_configure_simple sriov_enable (pci_disable_sriov) callers be_sriov_enable lpfc_sli_probe_sriov_nr_virtfn ixgbe_enable_sriov sriov_enable PCI_SRIOV_INITIAL_VF PCI_SRIOV_CAP PCI_SRIOV_CAP_VFM
}
include/linux/nmi.h test on 5.14.0-284.69.1.rt14.354.el9_2.x86_64 https://access.redhat.com/downloads/content/kernel-rt-devel/5.14.0-284.69.1.rt14.354.el9_2/x86_64/fd431d51/package kernel/watchdog.c lockup_detector_init lockup_detector_setup __lockup_detector_reconfigure lockup_detector_update_enable NMI_WATCHDOG_ENABLED softlockup_start_all watchdog_cpumask watchdog_enable hrtimer_init hrtimer_start watchdog_timer_fn watchdog_interrupt_count hrtimer_interrupts 6 watchdog_hardlockup_kick 6 watchdog_hardlockup_enable 6 watchdog_hardlockup_touch_cpu watchdog_next_cpu watchdog_cpus watchdog_nmi_enable hardlockup_detector_perf_enable hardlockup_detector_event_create perf_event_create_kernel_counter watchdog_overflow_callback is_hardlockup CONFIG_SOFTLOCKUP_DETECTOR CONFIG_HARDLOCKUP_DETECTOR touch_nmi_watchdog arch_touch_nmi_watchdog touch_softlockup_watchdog watchdog_sysctl_init CONFIG_LOCKUP_DETECTOR nmi_watchdog echo 1 > /proc/sys/kernel/nmi_watchdog
{ kthread_run_on_cpu < test_ringbuffer kthread_create_on_cpu kthread_create_on_node → kthread_bind kthread_create_worker_on_cpu < erofs_init_percpu_worker kthread_bind kthread_bind → kthread_bind_mask →
kthread kthread_run ldt kthread_create ▻ kthread_should_stop test_bit KTHREAD_SHOULD_STOP kthread_stop to_kthread kthread_work kthread_worker
current_thread_info
x exit_kthread
Scheduler
lightweight_kernel_threads
-
Process Scheduling Scheduling Policy The Scheduling Algorithm System Calls Related to Scheduling
linux/sched.h schedule kernel/sched.c 200 LOC __schedule ?? pre_schedule signal_pending_state trace_sched_switch "sched_switch" TP_printk context_switch switch_mm mm_struct switch_to __switch_to finish_task_switch post_schedule
sys_nice set_user_nice NICE_TO_PRIO
rq runqueue s runqueue_t
sched_init hrtick_rq_init hrtick_csd __hrtick_start __hrtick_restart hrtick_timer.function = hrtick task_tick -> hrtick update_rq_clock sched_class->task_tick task_tick_rt requeue_task_rt init_idle ->
setup_IO_APIC Advanced Programmable Interrupt Controller setup_IO_APIC_irqs ioapic_register_intr alloc_intr_gate set_intr_gate(vector, interrupt[irq]); _set_gate pack_gate write_idt_entry idt_table
init_IRQ /arch/x86/kernel/irqinit.c x86_init.irqs.intr_init native_init_IRQ l/arch/i386/kernel/i8259.c lkm2 set_intr_gate lkm2 set_intr_gate(vector, interrupt[irq]); interrupt source/arch/i386/kernel/entry.S irq_entries_start (arch/i386/kernel/entry.S) common_interrupt: do_IRQ ▻ ret_from_intr resume_kernel preempt_schedule_irq schedule ▻
load_balance
start_kernel rest_init kernel_init (via kernel_thread:) kernel_init_freeable smp_init idle_threads_init -> cpuhp_threads_init do_basic_setup ▻ x ? init_post run_init_process ▻ kernel_thread(kthreadd cpu_startup_entry do_idle -> tick_nohz_idle_enter tick_sched ts->inidle = 1; [TS_FLAG_INIDLE] = 1 tick_nohz_start_idle ts->idle_entrytime = ktime_get(); ts->idle_active = 1; sched_clock_idle_sleep_event sched_clock_cpu(smp_processor_id()); tick_sched_flag_set(ts, TS_FLAG_INIDLE); !need_resched cpu_is_offline cpu_online_mask tick_nohz_idle_stop_tick -> cpuhp_report_idle_dead play_dead arch_cpu_idle_dead arch_cpu_idle_enter tick_nohz_idle_restart_tick cpu_idle_poll cpuidle_idle_call -> tick_nohz_tick_stopped arch_cpu_idle_exit tick_nohz_idle_exit ts->inidle = 0; tick_nohz_idle_update_tick tick_nohz_account_idle_time ts->idle_exittime = now; cpuidle_enter_state err: default_idle_call trace_cpu_idle arch_cpu_idle x86_idle default_idle raw_safe_halt arch_safe_halt native_safe_halt hlt enter = &intel_idle __intel_idle mwait_idle_with_hints
trace_cpu_idle cpu_idle_poll x cpu_idle default_idle arch_idle cpu_do_idle processor._do_idle cpu_arm920_do_idle
idle_threads_init idle_init idle_threads fork_idle init_idle_pids init_idle INIT_TASK_COMM "swapper" set_cpus_allowed_common
bringup_cpu idle_thread_get(cpu); idle_threads __cpu_up cpu_up = native_cpu_up common_cpu_up
do_cpu_up _cpu_up
tick_nohz_idle_stop_tick can_stop_idle_tick
__tick_nohz_idle_stop_tick ts->timer_expires tracepoint:timer:*timer_expire_entry /cpu==$1/{printf("%s %u\n",probe, cpu)} tick_nohz_next_event __get_next_timer_interrupt➝tmigr_quick_check➝asm_exc_invalid_op➝exc_invalid_op➝handle_bug➝report_bug➝tmigr_quick_check➝__warn tick_nohz_stop_tick
ENTRY(cpu_arm926_do_idle) ... mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt pm_idle
linux/kernel/sched.c task_struct
renice
include/linux/wait.h include/linux/sched.h DECLARE_WAIT_QUEUE_HEAD()
UMP: __set_cpus_allowed_ptr set_cpus_allowed_ptr Syncronizations preempt_disable -> RT -> migrate_disable
migrate_disable_switch SCA_MIGRATE_DISABLE __do_set_cpus_allowed
migrate_disable p->migration_disabled++; migrate_enable -> p->migration_disabled--; SCA_MIGRATE_ENABLE __set_cpus_allowed_ptr -> __set_cpus_allowed_ptr_locked -> __do_set_cpus_allowed ->
atomic_t spinlock_t semaphore wait_queue_t
local_bh_disable local_bh_enable
local_lock __local_lock !CONFIG_PREEMPT_RT preempt_disable -> local_lock_acquire(this_cpu_ptr(lock)); CONFIG_PREEMPT_RT migrate_disable -> spin_lock(this_cpu_ptr((__lock))) rt_spin_lock __rt_spin_lock rtlock_lock rtlock_slowlock rtlock_slowlock_locked try_to_take_rt_mutex rt_mutex_set_owner schedule_rtlock schedule_loop(SM_RTLOCK_WAIT); raw_spin_lock_irq _raw_spin_lock_irq local_lock_irqsave __local_lock_irqsave !rt: local_irq_save raw_local_irq_save arch_local_irq_save arch_local_save_flags native_save_fl pushf ; pop arch_local_irq_disable native_irq_disable cli local_lock_acquire rt: __local_lock -> migrate_disable spin_lock local_unlock_irqrestore !rt: __local_unlock_irqrestore local_lock_release local_irq_restore raw_local_irq_restore raw_check_bogus_irq_restore warn_bogus_irq_restore arch_local_irq_restore arch_local_irq_enable native_irq_enable sti rt: __local_unlock rt: spin_unlock -> migrate_enable ->
local_unlock __local_unlock !rt local_lock_release
irqflags.h irqs_disabled raw_irqs_disabled arch_irqs_disabled arch_local_save_flags -> arch_irqs_disabled_flags local_lock_irq __local_lock_irq !rt: local_irq_disable local_lock_acquire rt: __local_lock -> local_unlock_irq __local_unlock_irq
-
Kernel Synchronization Kernel Control Paths When Synchronization Is Not Necessary Synchronization Primitives Synchronizing Accesses to Kernel Data Structures Examples of Race Condition Prevention
BKL lock_kernel lkm2 https://elixir.bootlin.com/linux/v2.6.32/ident/lock_kernel _lock_kernel __lock_kernel do_raw_spin_lock(&kernel_flag); include/linux/cache.h arch/x86/include/asm/cache.h static __cacheline_aligned_in_smp DEFINE_RAW_SPINLOCK(kernel_flag); kernel_flag lkm2 near __reacquire_kernel_lock atomic_t atomic_dec_and_test atomic_dec_return (generic) atomic_sub_return atomic_add_return ▻ xadd __xadd
completion wait_queue_head_t ▻ DECLARE_COMPLETION COMPLETION_INITIALIZER __WAIT_QUEUE_HEAD_INITIALIZER init_completion init_waitqueue_head INIT_LIST_HEAD prev, next wait_for_completion_interruptible ldt wait_for_completion wait_for_common __add_wait_queue_tail list_add_tail schedule if done > 0, done-- complete done++ mutex __LINUX_MUTEX_H include/linux/mutex.h atomic_t count; spinlock_t wait_lock; struct list_head wait_list;
No timeout for mutex! mutex_lock might_sleep(); __mutex_fastpath_lock(&lock->count, __mutex_lock_slowpath); __mutex_lock_slowpath __mutex_lock_common wait_lock mutex_set_owner(lock); mutex_lock_interruptible __mutex_fastpath_lock_retval __mutex_lock_interruptible_slowpath __mutex_lock_common(lock, TASK_INTERRUPTIBLE, 0, _RET_IP_); mutex_acquire mutex_lock_killable __mutex_lock_killable_slowpath return __mutex_lock(lock, TASK_KILLABLE, 0, NULL, _RET_IP_); mutex_unlock mutex_clear_owner(lock); __mutex_fastpath_unlock(&lock->count, __mutex_unlock_slowpath); __mutex_unlock_slowpath __mutex_unlock_common_slowpath wake_up_process ▻
lockdep lockdep_map lock_is_held lock_is_held_type semaphore source/include/linux/semaphore.h spinlock_t lock; unsigned int count; struct list_head wait_list;
wait_queue_head_t ▻ x init_MUTEX sema_init struct semaphore *sem, int val init_waitqueue_head
down_interruptible __down_interruptible __down_common(sem, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT) down_killable down_timeout down x __down_failed __down __down_common signal_pending_state signal_pending return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING)); __fatal_signal_pending task_struct pending.signal schedule_timeout
add_wait_queue_exclusive_locked atomic_add_negative __add_wait_queue_tail schedule down_trylock up lkm2 Unlike mutexes, up() may be called from any context and even by tasks which have never called down(). x __up_wakeup
__up wake_up_process try_to_wake_up ▻
rw_semaphore up down * writer reader
include/linux/vtime.h account_softirq_enter SOFTIRQ_OFFSET irqtime_account_irq irqtime_account_delta cpustat[idx] += delta;
include/linux/hrtimer.h hrtimer struct timerqueue_node _softexpires -> hrtimer_clock_base hrtimer_cpu_base
hrtimer_set_expires timer->node.expires = time; timer->_softexpires = time;
kernel/hrtimer.c sys_nanosleep ▻
hrtimer_wakeup
hrtimer_run_softirq __hrtimer_run_queues ->
__hrtimer_run_queues __run_hrtimer trace_hrtimer_expire_entry "hrtimer_expire_entry" ->tick_setup_sched_timer ->hrtimer_wakeup wake_up_process -> try_to_wake_up ▻ select_task_rq -> psi_ttwu_dequeue psi_task_change psi_flags_change psi_group_change set_task_cpu ttwu_queue ttwu_do_activate ttwu_do_wakeup ->
==> ./oo/conversion/cpu_mng/task/process/ipc/signals/src <== send_sig() signal()
sys_kill siginfo kill_something_info kill_pid_info group_send_sig_info __group_send_sig_info send_signal ** __send_signal __sigqueue_alloc sigpending sigaddset complete_signal signalfd_notify sigaddset complete_signal sys_signal do_sigaction lkm2 k = &t->sighand->action[sig-1];
linux/kernel/signal.c sigaction task_struct blocked #!sh ls -l -> scheduling
linux/ipc ipc() system call
message_queue
sys calls sys_msgget() sys_msgctl() sys_msgrcv()
structs msg_queue msg_msg msg_msgseg msg_sender msg_receiver msqid64_ds msqid_ds msg_setbuf
uses wait_queue
==> ./oo/conversion/cpu_mng/task/process/ipc/system_v_ipc/notes.txt <== 5. IPC mechanisms 5.1 Semaphores 5.2 Message queues 5.3 Shared Memory 5.4 Linux IPC Primitives
linux/ipc/sem.c syscalls: sys_semget() ▻ ipc_lock ▻ spin_lock sys_semctl() sys_semop()
structs sem_array sem seminfo semid64_ds semid_ds sem_queue sembuf sem_undo
shared_memory ./ipc/shm.c shmid_ds xx shm_segs shm_info
system calls sys_shmget() ipcget ipc_namespace ipcget_new newseg ipc_addid ipcget_public ipc_check_perms shm_security shm_vm_ops
raise_softirq BH HI_SOFTIRQ .. NR_SOFTIRQS raise_softirq_irqoff
BH DECLARE_TASKLET, tasklet_struct, tasklet_schedule (softirq context) DECLARE_WORK, work_struct (process context) softirq
static void ldt_work_func(struct work_struct *work) { }
static DECLARE_WORK(ldt_work, ldt_work_func);
schedule_work(&ldt_work);
tasklet_struct HI_SOFTIRQ, TASKLET_SOFTIRQ tasklet_init tasklet_schedule ldt __tasklet_schedule tasklet_vec raise_softirq_irqoff(TASKLET_SOFTIRQ); __raise_softirq_irqoff or_softirq_pending(1UL << nr); wakeup_softirqd tasklet_kill task_queue #include <linux/tqueue.h>
tq_struct
softirq softirq_init open_softirq TASKLET_SOFTIRQ tasklet_action softirq_vec tasklet_action func open_softirq HI_SOFTIRQ tasklet_hi_action func
ksoftirqd do_softirq ▻
DECLARE_TASK_QUEUE tq_timer tq_scheduler tq_immediate tq_disk tq_immediate IMMEDIATE_BH tq_disk
void queue_task(struct tq_struct *task, task_queue *list); void run_task_queue(task_queue *list);
Tasklets DECLARE_TASK_QUEUE(variablename);
#include <linux/interrupt.h>
tasklet_struct Tasklets
workqueue init_workqueues
workqueue_struct lkm2 create_workqueue ▻ queue_work worker cpu_workqueue_struct wait_queue_head_t work_struct ▻ task_struct ▻
work_struct lkm2 DECLARE_WORK INIT_WORK lkm2 schedule_work ▻
create_worker worker->task = kthread_create(worker_thread, worker, "kworker/u:%d", id);
kthread_create kthread_create_on_node __kthread_create_on_node kthread_create_info kthread_create_list wake_up_process(kthreadd_task); kthreadd set_cpus_allowed_ptr(tsk, housekeeping_cpumask(HK_TYPE_KTHREAD)); kthread_create_list create_kthread kthread set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_TYPE_KTHREAD)); kernel_thread INIT_WORK x keventd_create_kthread kernel_thread
create_workqueue kernel/workqueue.c __create_workqueue x create_workqueue_thread kthread_create -> worker_thread run_workqueue work->func
alloc_workqueue schedule_work ltd lkm2 system_wq work_struct ▻ queue_work queue_work_on x wq_per_cpu(wq, cpu) __queue_work cpu = wq_select_unbound_cpu(raw_smp_processor_id()); insert_work set_wq_data &cwq->more_work run_scheduled_work __run_work
tasklets are a special function that may be scheduled to run, in interrupt context, at a system-determined safe time.
DECLARE_TASKLET(name, function, data) DECLARE_TASKLET_DISABLED(name, function, data)
while (jiffies < j) schedule(); # not durable
sys_nanosleep hrtimer_nanosleep hrtimer_init_sleeper_on_stack hrtimer_set_expires_range_ns do_nanosleep hrtimer_sleeper_start_expires hrtimer_start_expires -> hrtimer_start_range_ns -> freezable_schedule schedule set_restart_fn(restart, hrtimer_nanosleep_restart);
schedule_timeout_interruptible __set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(timeout);
sleep_on_timeout schedule_timeout->
interruptible_sleep_on_timeout schedule_timeout ▻
Long: { // together set_current_state(TASK_INTERRUPTIBLE); schedule_timeout (jit_delay*HZ); } ssleep msleep msecs_to_jiffies schedule_timeout_uninterruptible schedule_timeout timer_list setup_timer init_timer process_timeout wake_up_process ▻ __mod_timer ▻ internal_add_timer list_add_tail schedule
do_IRQ irq_exit
apic_timer_interrupt smp_apic_timer_interrupt irq_exit invoke_softirq do_softirq local_softirq_pending __do_softirq softirq_vec action run_timer_softirq this_cpu_ptr timer_bases __run_timers ->
process_timeout ▻
call_function_single_interrupt smp_call_function_single_interrupt irq_exit ->
common_startup_64 arch/x86/kernel/head_64.S
initial_code -> start_secondary
do_boot_cpu
-> secondary_startup_64_no_verify start_secondary cpu_startup_entry do_idle -> cpuidle_idle_call cpuidle_enter cpuidle_enter_state poll_idle asm_sysvec_apic_timer_interrupt -> set_cpu_online
idt_setup_apic_and_irq_gates apic_idts reschedule_interrupt call_function_interrupt call_function_single_interrupt INTG(LOCAL_TIMER_VECTOR, asm_sysvec_apic_timer_interrupt),
./arch/x86/include/asm/idtentry.h DECLARE_IDTENTRY_SYSVEC(LOCAL_TIMER_VECTOR, sysvec_apic_timer_interrupt);
DECLARE_IDTENTRY_SYSVEC asm_##func
include/linux/tracepoint.h DEFINE_EVENT DECLARE_TRACE __DECLARE_TRACE __traceiter_##name trace_##name TP_ARGS register_trace_##name arch/x86/include/asm/trace/irq_vectors.h DECLARE_EVENT_CLASS(x86_irq_vector, "vector=" DEFINE_IRQ_VECTOR_EVENT(irq_work); DEFINE_IRQ_VECTOR_EVENT(local_timer); ##_entry ##_exit DEFINE_EVENT_FN DECLARE_TRACE -> trace_local_timer_entry trace_local_timer_exit
arch/x86/kernel/apic/apic.c sysvec_apic_timer_interrupt trace_local_timer_entry(LOCAL_TIMER_VECTOR); trace_intel_irq_entry osnoise_trace_irq_entry -> set_int_safe_time(osn_var, &osn_var->irq.delta_start); local_apic_timer_interrupt(); trace_local_timer_exit(LOCAL_TIMER_VECTOR); trace_intel_irq_exit osnoise_trace_irq_exit trace_irq_noise "duration" -> timer_irq_duration get_int_safe_duration
cpuidle_enter_state ? asm_sysvec_apic_timer_interrupt (sysvec_apic_timer_interrupt) ? sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c ? __sysvec_apic_timer_interrupt hrtimer_interrupt ->
fec issue irqentry_enter lockdep_hardirqs_off rcu_irq_enter trace_hardirqs_off_finish
rcu_eqs_enter trace_rcu_dyntick
do_IRQ irq_work_interrupt x reschedule_interrupt x smp_apic_timer_interrupt native_smp_send_reschedule apicinterrupt RESCHEDULE_VECTOR reschedule_interrupt smp_reschedule_interrupt irq_enter rcu_irq_enter lockdep_assert_irqs_disabled rcu_nmi_enter irq_enter_rcu tick_irq_enter __irq_enter irq_exit irq_exit_rcu __irq_exit_rcu in_interrupt irq_count preempt_count invoke_softirq in_hardirq hardirq_count preempt_count HARDIRQ_MASK wake_timersd RT timersd RT wake_up_process tick_irq_exit -> rcu_irq_exit rcu_nmi_exit rcu_dynticks_eqs_enter lockdep_hardirq_exit
Short: #include <linux/delay.h> ndelay __ndelay __const_udelay ▻ udelay __udelay __const_udelay __delay cur_timer mdelay udelay
#include <linux/param.h> HZ
#include <linux/sched.h> jiffies
TIMER_IRQ
-
start_secondary setup_secondary_APIC_clock
-
setup_APIC_timer clockevents_register_device tick_check_new_device tick_setup_device tick_setup_periodic tick_set_periodic_handler dev→event_handler = tick_handle_periodic; dev→event_handler tick_handle_periodic →
time_init_hook setup_irq irq0 IRQF_SHARED hpet_time_init setup_default_timer_irq setup_irq(0, &irq0); timer_interrupt ./arch/../kernel/time.c x do_timer_interrupt_hook global_clock_event->event_handler(global_clock_event
tick_handle_periodic tick_periodic do_timer update_process_times xx do_timer_interrupt mark_offset_tsc do_timer jiffies_64 ++ jiffies++; update_times update_wall_time xtime calc_global_load calc_load_fold_idle calc_load_tasks avenrun calc_load #include <linux/time.h> void do_gettimeofday(struct timeval *tv); void get_fast_time(struct timeval *tv);
get_cycles rdtscll rdtsc sched_clock native_sched_clock rdtscll cycles_2_ns
uptime_read_proc
do_posix_clock_monotonic_gettime do_posix_clock_monotonic_gettime_parts
setitimer() and getitimer() - not found linux/kernel/timer.c TIMER_DEFERRABLE -> BASE_DEF, !BASE_STD init_timers open_softirq TIMER_SOFTIRQ run_timer_softirq lkm2 timer_list DEFINE_TIMER timer_setup __init_timer init_timer_key dinit_idle_pidso_init_timer timer->function get_timer_this_cpu_base (was get_target_base) kernel/time/timer.c timers_migration_enabled TIMER_PINNED -> BASE_LOCAL get_timer_cpu_base per_cpu_ptr timer_bases DEFINE_PER_CPU timer_base timer_list expires !CONFIG_SMP get_timer_this_cpu_base this_cpu_ptr -> init_timer add_timer() __mod_timer ▻ mod_timer __mod_timer internal_add_timer -> del_timer ? setup_timer
__run_timers timer_base_lock_expiry raw_spin_lock_irq
collect_expired_timers pending_map __next_timer_interrupt next_pending_bucket pending_map time_before expire_timers detach_timer fn = timer->function; call_timer_fn __mod_timer running_timer internal_add_timer enqueue_timer trace_timer_start
current int in_interrupt();
-
Timing Measurements Hardware Clocks The Linux Timekeeping Architecture CPU’s Time Sharing Updating the Time and Date Updating System Statistics Software Timers System Calls Related to Timing Measurements timer_interrupt ▻ xx do_timer_interrupt do_timer ▻ update_process_times → update_one_process do_process_times
kernel/sched.c sys_sched_getparam find_process_by_pid find_task_by_vpid find_task_by_pid_ns find_pid_ns pid_task task_struct p->rt_priority sys_sched_get_priority_max sys_sched_get_priority_min sys_sched_getscheduler security_task_getscheduler sys_sched_rr_get_interval sys_sched_setaffinity sched_setaffinity -> __sched_setaffinity task_struct ... __set_cpus_allowed_ptr set_cpus_allowed -> sys_sched_getaffinity sched_getaffinity cpumask_and cpus_mask cpu_active_mask sys_sched_setparam do_sched_setscheduler sys_sched_setscheduler do_sched_setscheduler sys_sched_yield do_sched_yield yield_task yield_task_fair clear_buddies schedule
kernel/signal.c sys_kill ▻ sys_pause schedule sys_restart_syscall ¤t_thread_info()->restart_block sys_rt_sigaction do_sigaction ▻ sys_rt_sigpending do_sigpending sys_rt_sigprocmask sigdelsetmask sys_rt_sigqueueinfo kill_proc_info sys_rt_sigsuspend schedule sys_rt_sigtimedwait schedule_timeout_interruptible sys_rt_tgsigqueueinfo do_rt_tgsigqueueinfo do_send_specific do_send_sig_info sys_tgkill do_tkill do_send_specific sys_tkill do_tkill
delayed_work work_struct ▻ timer_list -> cancel_delayed_work }
-
-
no wait list only one locker busy loop ▻ it can be used in interrupt context (where sleeping is not an option)
include/linux/spinlock.h
spinlock_t raw_spinlock spin_lock lkm2 raw_spin_lock _raw_spin_lock __raw_spin_lock preempt_disable(); spin_acquire -> LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock); ---- preempt_disable -> spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); lock_acquire __lock_acquire atomic_inc arch_atomic_inc atomic_add_return ▻ arch_atomic_add_return xadd lockdep_print_held_locks _raw_spin_lock(lock); __raw_spin_trylock xchgb spin_lock_irq() spin_unlock_irq()
spin_lock_irqsave lkm2 raw_spin_lock_irqsave _raw_spin_lock_irqsave SMP __raw_spin_lock_irqsave local_irq_save preempt_disable spin_acquire(&lock->dep_map, 0, 0, _RET_IP_); lock_acquire LOCK_CONTENDED do_raw_spin_lock_flags arch_spin_lock_flags arch_spin_lock __ticket_spin_lock ...
UP __LOCK_IRQSAVE local_irq_save(flags); __LOCK x _spin_lock_irqsave local_irq_save preempt_disable ▻ spin_acquire ▻ _raw_spin_lock_flags __raw_spin_lock_flags local_irq_save spin_unlock_irqrestore lkm2 raw_spin_unlock_irqrestore _raw_spin_unlock_irqrestore spin_unlock raw_spin_unlock _raw_spin_unlock __raw_spin_unlock spin_release(&lock->dep_map, 1, _RET_IP_); ~ lock_release do_raw_spin_unlock(lock); arch_spin_unlock __ticket_spin_unlock incb ~ __release __context__ preempt_enable();
include/linux/wait.h DECLARE_WAITQUEUE wait_queue_entry __WAITQUEUE_INITIALIZER default_wake_function add_wait_queue wait_queue_head_t __wait_queue_head lock struct list_head task_list; DECLARE_WAIT_QUEUE_HEAD interruptible_sleep_on decates, uses wait_event_interruptible sleep_on_common(q, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); init_waitqueue_entry(&wait, current); __add_wait_queue timeout = schedule_timeout(timeout); wake_up_interruptible ▻ __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL) ->
add_wait_queue __add_wait_queue list_add(&new->task_list, &head->task_list); remove_wait_queue __remove_wait_queue
wake_up_interruptible ldt wait_event lkm2 __wait_event prepare_to_wait ▻ schedule ▻ wait_event_interruptible ldt __wait_event_interruptible ___wait_event prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); prepare_to_wait spin_lock_irqsave ▻ __add_wait_queue ▻ set_current_state spin_unlock_irqrestore signal_pending test_tsk_thread_flag TIF_SIGPENDING test_ti_thread_flag task_thread_info thread_info test_bit flags schedule -> wait_event_interruptible_timeout __wait_event_interruptible_timeout prepare_to_wait ▻ signal_pending ▻ schedule_timeout
DEFINE_WAIT init_wait autoremove_wake_function init_waitqueue_head __init_waitqueue_head lockdep_set_class_and_name INIT_LIST_HEAD wake_up __wake_up spin_lock_irqsave ▻ __wake_up_common_lock __wake_up_common default_wake_function try_to_wake_up task_rq_lock task_rq activate_task -> lkm2 __activate_task resched_task spin_unlock_irqrestore ▻
fork() _exit() linux/kernel/fork.c
==> ./oo/conversion/cpu_mng/task/connected_to.txt <== Scheduler Interrupts
-
Program Execution Executable Files Executable Formats Execution Domains The exec Functions
==> ./oo/conversion/cpu_mng/task/kinds.txt <== the idle thread(s), kernel threads, user process.
==> ./oo/conversion/cpu_mng/task/notes.txt <== 2. Process and Interrupt Management 2.1 Task Structure and Process Table 2.2 Creation and termination of tasks and kernel threads 2.3 Linux Scheduler 2.4 Linux linked list implementation 2.5 Wait Queues 2.6 Kernel Timers 2.7 Bottom Halves 2.8 Task Queues 2.9 Tasklets 2.10 Softirqs 2.11 How System Calls Are Implemented on i386 Architecture? 2.12 Atomic Operations 2.13 Spinlocks, Read-write Spinlocks and Big-Reader Spinlocks 2.14 Semaphores and read/write Semaphores 2.15 Kernel Support for Loading Modules
-
Processes Processes, Lightweight Processes, and Threads Process Descriptor Process Switch Creating Processes Destroying Processes
pid_t
== current
== task_struct mm_struct vm_area_struct vm_start
union thread_union init_thread_union __init_task_data = { INIT_THREAD_INFO(init_task) };
thread_union
trvx(current_stack_pointer & (THREAD_SIZE - 1));
thread_info asm/thread_info.h task_struct exec_domain current_thread_info return (struct thread_info *) (current_stack_pointer & ~(THREAD_SIZE - 1)); current_stack_pointer asm("esp") stack
scheduler current <include/asm/current.h>
task_struct* current
Thread in Linux are just processes that share VM
kernel_thread CLONE_VM CLONE_UNTRACED do_fork
add_wait_queue() kernel function remove_wait_queue() kernel function sleep_on() linux/kernel/fork.c IPC fsnotify_init dnotify_init Directory notifications for Linux. - obsoleted by inotify fanotify_user_setup inotify_user_setup
sys_inotify_init ▻
sys_fanotify_init fs/notify/fanotify/fanotify_user.c lkm2 FAN_ALL_EVENTS fanotify_fops fsnotify_init ipc/mqueue.c sys_mq_open do_create vfs_create ▻ do_open sys_mq_getsetattr sys_mq_notify alloc_skb netlink_attachskb sys_mq_timedreceive msg_get pipelined_receive msg_insert store_msg sys_mq_timedsend load_msg pipelined_send list_del sys_mq_unlink vfs_unlink ipc/msg.c sys_msgctl sys_msgget sys_msgrcv do_msgrcv store_msg sys_msgsnd do_msgsnd pipelined_send ipc/sem.c sys_semctl sys_semget sys_semop sys_semtimedop ipc/shm.c sys_shmat lkm2 do_shmat do_mmap ▻ lkm2 sys_shmctl sys_shmdt do_munmap ▻ sys_shmget ▻
-
Process Communication Pipes FIFOs System V IPC
pipe() open() named pipe uses wait queue, signals pipe_read pipe_readv fs_table pipe_max_size
mkfifo
-
Signals The Role of Signals Generating a Signal Delivering a Signal System Calls Related to Signal Handling
get_cpu_ptr get_cpu_ptr() disables preemption and therefore migration preempt_disable include/linux/preempt.h inc_preempt_count add_preempt_count preempt_count current_thread_info()->preempt_count this_cpu_ptr raw_cpu_ptr __verify_pcpu_ptr arch_raw_cpu_ptr this_cpu_off raw_smp_processor_id -> put_cpu_ptr preempt_enable
proc_pid_sched_operations sched_open sched_show proc_sched_show_task /proc/self/sched policy prio wait_sum do_task_stat task_prio return p->prio - MAX_RT_PRIO; task_nice -> ... task->rt_priority task->policy
ps openproc simple_readproc stat2proc PIDS_PRIORITY stat: priority finalize_stacks pr_priority
is_migration_disabled
map_queues_v2_hw blk_mq_queue_map irq_get_affinity_mask irq_data_get_affinity_mask desc->irq_common_data.affinity;
irq_data_update_affinity cpumask_copy(d->common->affinity, m);
apic_update_irq_cfg irq_data_update_effective_affinity effective_affinity
mlx4_en_activate_cq irq_get_effective_affinity_mask irq_data_get_effective_affinity_mask
irq_thread_check_affinity irq_data_get_effective_affinity_mask
"rq_affinity" queue_rq_affinity_store
pci_alloc_irq_vectors_affinity->
dfl_files cpuset_write_resmask -> sched_partition_write update_prstate partition_xcpus_newstate update_isolation_cpumasks housekeeping_exlude_isolcpus partition_xcpus_add partition_xcpus_newstate cpu_up(cpu, CPUHP_ONLINE); cpu_down(cpu, CPUHP_OFFLINE);
for_each_cpu(cpu, enable_mask) timers_prepare_cpu(cpu);
for_each_cpu(cpu, disable_mask) timers_resettle_from_cpu(cpu);
timers_prepare_cpu who sets is_idle?
mce_timer_fn
grep mce_timer_fn /proc/timer_list
gqip
watchdog_cpumask is initialized in lockup_detector_init() from housekeeping_cpumask(HK_TYPE_TIMER).
lockup_detector_reconfigure() utilizes watchdog_cpumask via __lockup_detector_reconfigure().
kernel_init kernel_init_freeable do_one_initcall acpi_init acpi_scan_init acpi_bus_scan acpi_bus_attach acpi_dev_for_each_child device_for_each_child ? acpi_dev_for_one_check acpi_bus_attach device_for_each_child ? acpi_dev_for_one_check acpi_bus_attach acpi_create_platform_device acpi_dev_get_resources acpi_walk_resources ? acpi_dev_process_resource acpi_walk_resource_buffer ? acpi_dev_process_resource acpi_dev_process_resource acpi_dev_resource_interrupt ? acpi_dev_resource_address_space acpi_dev_get_irqresource ? lock_acquire acpi_register_gsi_ioapic mp_map_pin_to_irq alloc_isa_irq_from_domain __irq_domain_alloc_irqs irq_domain_alloc_irqs_locked dump_stack_lvl
really_probe platform_probe ged_probe acpi_walk_resources acpi_walk_resource_buffer acpi_ged_request_interrupt request_threaded_irq __setup_irq irq_startup irq_setup_affinity irq_do_set_affinity ioapic_set_affinity parent->chip->irq_set_affinity apic_set_affinity
mp_register_ioapic
mp_ioapic_irqdomain_ops mp_irqdomain_alloc ioapic_chip ->ioapic_set_affinity
cpus_timer_store isolate resettle_all_timers tick_cpu_dying tick_nohz_handler hrtimers_cpu_evict
syscore_suspend
timekeeping_syscore_ops timekeeping_suspend tick_suspend tick_suspend_local tick_suspend_broadcast clockevents_shutdown
tick_nohz_full_stop_tick tick_nohz_next_event tick_nohz_stop_tick tick_nohz_retain_tick
tick_nohz_handler ->
cpu_startup_entry do_idle -> tick_nohz_idle_enter -> [TS_FLAG_INIDLE] = 1 tick_nohz_idle_exit -> WARN_ON_ONCE(!tick_sched_flag_test(ts, TS_FLAG_INIDLE)); [TS_FLAG_INIDLE] = 0
housekeeping_update timers_prepare_cpu hrtimers_prepare_cpu hrtimers_cpu_evict smp_call_function_single -> retrigger_next_event timers_dead_cpu ->
ipi_send_cpu: cpu=11 callsite=irq_work_queue_on+0x109/0x120 callback=nohz_full_kick_func+0x0/0x10 <...>-111 [009] d...3.. 94815.741420: ipi_send_cpu: cpu=11 callsite=check_preempt_curr+0x33/0x70 callback=0x0
irq_action irqaction
{ save_flags(flags); // better spin_lock_irqsave cli();
/* This code runs with interrupts disabled */
restore_flags(flags); // instead sti; }
linux/interrupt.h
free_irq
request_irq kernel/irq/manage.c request_threaded_irq ▻ setup_irq __setup_irq desc->action = irqaction irq_desc register_irq_proc /proc/irq/ register_handler_proc /proc/irq/1234/handler/
/proc/interrupts proc_interrupts_init int_seq_ops show_interrupts desc = irq_to_desc(i); sparse_irqs arch_show_interrupts "Non-maskable interrupts" ... irq_stats for_each_online_cpu for_each_cpu for_each_set_bit
/proc/stat
-
Interrupts and Exceptions The Role of Interrupt Signals Interrupts and Exceptions Nested Execution of Exception and Interrupt Handlers Initializing the Interrupt Descriptor Table Exception Handling Interrupt Handling Softirqs, Tasklets, and Bottom Halves Returning from Interrupts and Exceptions
IRQ_PER_CPU IRQD_PER_CPU irq_settings_set_per_cpu irq_settings_is_per_cpu irq_is_percpu irqd_is_per_cpu
irqd_can_balance->
include/linux/irqdesc.h irq_is_*: irq_check_status_bit irq_to_desc irq_balancing_disabled IRQ_NO_BALANCING_MASK IRQ_PER_CPU | IRQ_NO_BALANCING irq_is_percpu IRQ_PER_CPU irq_is_percpu_devid IRQ_PER_CPU_DEVID kernel/irq/settings.h irq_desc: _IRQ_NO_BALANCING irq_settings_set_no_balancing < __setup_irq IRQF_NOBALANCING -> irq_settings_has_no_balance_set -> IRQD_NO_BALANCING < irq_modify_status _IRQ_PER_CPU IRQ_PER_CPU: irq_settings_set_per_cpu < __setup_irq
irq_settings_is_per_cpu -> IRQD_PER_CPU < irq_modify_status IRQD_PER_CPU ?__irq_get_desc_lock kstat_irqs_desc < kstat_irqs try_one_irq
irq_settings_is_per_cpu_devid _IRQ_PER_CPU_DEVID IRQ_PER_CPU_DEVID
irq_modify_status->
irqd_is_per_cpu < migrate_one_irq irq_move_masked_irq show_interrupts
IRQD_PER_CPU
IRQF_PERCPU IRQD_PER_CPU __irq_can_set_affinity
IDT Interrupt Descriptor Table show_interrupts
setup_vector_irq __setup_vector_irq vector_irq
x do_IRQ unsigned vector = ~regs->orig_ax; irq = __this_cpu_read(vector_irq[vector]); irq_desc x __do_IRQ x handle_IRQ_event timer_interrupt ▻ handle_irq desc->handle_irq x irq_handler
linux/include/asm/irq.h :
disable_irq disable_irq_nosyn enable_irq
Restrictions: A handler can't transfer data to or from user space, because it doesn't execute in the context of a process. other than GFP_ATOMIC, or locking a semaphore. Finally, handlers cannot call schedule.
void short_interrupt(int irq, void *dev_id, struct pt_regs *regs) { struct timeval tv; int written;
do_gettimeofday(&tv);
/* Write a 16-byte record. Assume PAGE_SIZE is a multiple of 16 */ written = sprintf((char *)short_head,"%08u.%06u\n", (int)(tv.tv_sec % 100000000), (int)(tv.tv_usec)); short_incr_bp(&short_head, written); wake_up_interruptible(&short_queue); /* wake any reading process */ }
not for SNP
unsigned long flags;
save_flags(flags); cli(); /* critical code */ restore_flags(flags);
global_bh_lock init_bh remove_bh mark_bh
BH
devm_irq_alloc_desc ... __devm_irq_alloc_descs devm_irq_desc_release
irq_free_desc -> <linux/interrupt.h>
irq_free_desc irq_free_descs free_desc delete_irq_desc
-
Process and Interrupt Management 2.1 Task Structure and Process Table 2.2 Creation and termination of tasks and kernel threads 2.3 Linux Scheduler 2.4 Linux linked list implementation 2.5 Wait Queues 2.6 Kernel Timers 2.7 Bottom Halves 2.8 Task Queues 2.9 Tasklets 2.10 Softirqs 2.11 How System Calls Are Implemented on i386 Architecture? 2.12 Atomic Operations 2.13 Spinlocks, Read-write Spinlocks and Big-Reader Spinlocks 2.14 Semaphores and read/write Semaphores 2.15 Kernel Support for Loading Modules PCI examples snd_intel8x0, snd_intel8x0_probe hl_device_init pci_error_handlers pci_ers_result_t ← pci_channel_state_t pci_ers_result AER - Advanced Error Reporting BAR - Base Address Registers PCI_CAP_ID_PCIX pcie_port_service_driver PCIE_PORT_SERVICE_PME Power Management Event PCIE_PORT_SERVICE_AER Advanced Error Reporting PCIE_PORT_SERVICE_HP Native Hotplug PCIE_PORT_SERVICE_DPC Downstream Port Containment PCIE_PORT_SERVICE_BWNOTIF Bandwidth notification PMC - Power Management Controller ACPI - Advanced Configuration and Power Interface pci_dev_id PCI_DEVID PCI_BUS_NUM 15:8 PCI_DEVFN(slot, func) PCI_SLOT 7:3 PCI_FUNC 2:0 __pci_read_base pci_read_config_word(dev, PCI_COMMAND, &orig_cmd); pci_setup_device pci_hdr_type PCI_HEADER_TYPE PCI_HEADER_TYPE_NORMAL PCI_HEADER_TYPE_BRIDGE PCI_HEADER_TYPE_CARDBUS
pci_request_regions pci_request_region request_region ▻ request_mem_region
pci_request_selected_regions -> pci_release_regions pci_release_selected_regions pci_release_region release_region ioport_resource __release_region > release_mem_region pcim_iomap_regions_request_all 16 uses ~ pci_request_selected_regions __pci_request_selected_regions __pci_request_region -> request_region ioport_resource __request_region kernel/resource.c alloc_resource __request_resource &root->child new->parent = root request_mem_region iomem_resource __request_region __request_resource __request_mem_region &iomem_resource __request_region-> -EBUSY pcim_iomap_regions pci_request_region __pci_request_region pcim_iomap pcim_iomap_table devres_find pcim_iomap_release pci_iomap pci_iomap_range ioremap 1 pci_enable_device 904 uses pci_set_dma_mask pci_request_regions pcim_iomap / pci_iomap / pci_ioremap_bar pci_iounmap iounmap pci_release_regions 616 uses pci_disable_device 2 pcim_iomap_regions 115 uses pcim_iomap_table pci_set_master 639 uese pcim_iounmap_regions 16 3 pci_select_bars pci_request_selected_regions 59 uses pci_ioremap_bar/ devm_ioremap pci_iounmap pci_release_selected_regions 54 uses 4 pci_request_mem_regions ioremap pci_iomap pci_release_mem_regions
pcim_iounmap_regions (pcim_iomap_regions) pcim_iounmap pci_release_region pci_enable_device_mem 73 uses pci_register_driver -> pci_set_pcie_reset_state pcie_capability_read_word 179 pci_is_pcie 123 pcie_capability_write_word 87 pci_pcie_type 83 pci_disable_pcie_error_reporting 55 pci_enable_pcie_error_reporting 48 pcie_capability_read_dword 48 pcie_capability_clear_and_set_word 38 pcie_set_readrq 34 pcie_get_mps 23 pcie2_write32 22 pci_pcie_cap 21 pcie_flr 21 pcie_print_link_status 20 pcie_get_readrq 20 pcie_capability_clear_word 18 pcie_bus_configure_settings 18 bcma_drv_pcie2 17 pcie_aspm_enabled pcie_aspm_get_link aspm_enabled pci_dev_msi_enabled Endpoint Core EPC Endpoint Controller include/linux/pci-epc.h pci_epc_create devm_pci_epc_create EPF PCI Endpoint Function include/linux/pci-epf.h pci_epf_create pci_epf_test_init pci_epc_set_bar include/linux/pci-epc.h
a nvme_init nvme_driver nvme_probe nvme_pci_alloc_dev nvme_max_io_queues nvme_pci_enable ... nvme_init_queue #define PCI_IRQ_ALL_TYPES (PCI_IRQ_INTX | PCI_IRQ_MSI | PCI_IRQ_MSIX) pci_alloc_irq_vectors-> nvme_pci_configure_admin_queue nvme_alloc_queue nvme_init_queue queue_request_irq nvme_setup_io_queues nvme_setup_irqs (managed) irq_affinity PCI_IRQ_AFFINITY nvme_calc_irq_sets io_queues[HCTX_TYPE_DEFAULT] = nrirqs - nr_read_queues; irq_affinity affd->set_size pci_alloc_irq_vectors_affinity -> adminq: queue_request_irq nvme_irq_check nvme_irq nvme_poll_cq nvme_pci_complete_batch nvme_complete_batch nvme_complete_batch_req trace_nvme_complete_rq blk_mq_end_request_batch blk_complete_request pci_request_irq -> pci_irq_vector(dev, nr) request_threaded_irq -> nvme_create_io_queues nvme_alloc_queue max = min(dev->max_qid, dev->ctrl.queue_count - 0); nvme_create_queue nvme_init_queue dev->online_queues++; cq_vector queue_request_irq ->
mlx5_irq_table_create PCI_IRQ_MSIX pci_alloc_irq_vectors
PCI_CAP_ID_MSIX PCI_CAP_ID_EXP pci_alloc_irq_vectors affd = 0 pci_alloc_irq_vectors_affinity PCI_IRQ_MSI __pci_enable_msi_range irq_calc_affinity_vectors msi_capability_init irq_affinity *affd irq_affinity_desc irq_create_affinity_masks -> arch_setup_msi_irqs msi_setup_msi_desc irq_affinity_desc *masks desc.affinity = masks; msi_insert_msi_desc -> PCI_IRQ_MSIX __pci_enable_msix_range x __pci_enable_msix msix_capability_init msix_setup_interrupts irq_affinity_desc <- irq_create_affinity_masks -> msix_setup_msi_descs msi_desc.affinity <- irq_affinity_desc msi_desc desc.affinity = masks ? curmsk : NULL; msix_prepare_msi_desc msi_insert_msi_desc msi_domain_insert_msi_desc msi_alloc_desc msi_insert_desc msi: dev_msi_info msi.data: msi_device_data __domains: msi_dev_domain store: xarray dev->msi.data->__domains[domid].store msi_device_data PCI_IRQ_INTX irq_create_affinity_masks irq_affinity_desc <- irq_affinity group_cpus_evenly -> cpumask_copy(&masks[curvec].mask, ...); masks[i].is_managed = 1; pci_intx PCI_COMMAND_INTX_DISABLE pci_free_irq_vectors pci_disable_msix -> pci_disable_msi pci_msi_shutdown free_msi_irqs // when pci_free_irq was called // free_msi_irqs: BUG_ON(irq_has_action(entry->irq + i));
pci_request_irq pci_irq_vector x for_each_pci_msi_entry first_pci_msi_entry first_msi_entry list_first_entry request_threaded_irq -> pci_free_irq free_irq __free_irq irq_shutdown irq_state_set_disabled IRQD_IRQ_DISABLED irqd_set __irqd_to_state __irq_disable irq_disable irq_state_clr_started irqd_clear __irqd_to_state irq_release_resources pcie_pme_init pcie_pme_driver pcie_pme_probe pcie_port_service_register pcie_bandwidth_notification_init pcie_port_service_register depricated pci_enable_msi, use pci_alloc_irq_vectors pci_enable_msi_block msi_capability_init arch_setup_msi_irqs ▻ pci_disable_msi -> , use pci_free_irq_vectors pci_enable_msix_exact pci_enable_msix_range use pci_alloc_irq_vectors __pci_enable_msix_range msix_enabled pci_disable_msix pci_msix_shutdown free_msi_irqs pci_read_config_dword pci_bus_read_config_dword pci_bus pci_ops pci_root_ops core pci_pcbios_init raw_pci_ops = pci_find_bios pci_bios_access pci_bios_read pci_bios_write pci pci_legacy_init pcibios_scan_root acpi_pci_root_add pci_acpi_scan_root pcibios_scan_root pci_scan_bus_parented pci_create_bus pci_root_ops pci_read raw_pci_ops->read ?? raw_pci_read pci_write raw_pci_ops->write pcibios_init pci_init pci_dev pci_get_device pci_get_subsys pci_get_dev_by_id match_pci_dev_by_id pci_match_one_device pci_device_id bus_find_device to_pci_dev pci_fixup_device pci_bus_read_dev_vendor_id pci_bus_generic_read_dev_vendor_id pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l) pci_status_get_and_clear_errors ret = pci_read_config_word(pdev, PCI_STATUS, &status); PCI Hotplug pci_do_scan_bus pci_scan_child_bus pci_bus_add_devices pci_bus_add_device pci_devices
acpi_pci_root_init acpi_bus_register_driver acpi_bus_drivers acpi_driver_attach acpi_bus_driver_init add ▻ acpi_pci_root_driver acpi_pci_root_add ▻ acpi_pci_root_start acpi_pci_roots pci_bus_add_devices
? pci_scan_bus pci_fixup_device pci_do_fixups pci_driver_init bus_register ▻ pci_bus_type pci_hotplug
pci_set_consistent_dma_mask
DMA_28BIT_MASK ?
linux/Documentation/pci.txt
pci_driver device_driver pci_register_driver (pci_module_init) __pci_register_driver driver_register ▻ pci_create_newid_file sysfs_create_file ▻ pci_unregister_driver
?? pci_bus_type pci_device_probe __pci_device_probe pci_match_device pci_match_id pci_match_one_device pci_call_probe local_pci_probe probe() skeleton_probe pci_dev_get get_device pci_dev_put put_device kobject_put kref_put \kobject_release kobject_cleanup __kobject_del < kobject_del t->release
pci_scan_slot pci_scan_single_device pci_scan_device pci_setup_device pci_read_irq pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq); pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); dev->irq = irq pci_subsystem_ids PCI_SUBSYSTEM_VENDOR_ID PCI_SUBSYSTEM_ID pci_read_bases -reading resources patch PCI_BASE_ADDRESS_0 pci_size pci_device_add pci_init_capabilities -> pci_pm_init pci_iov_init ▻ list_add_tail(&dev->bus_list, &bus->devices);
CONFIG_PCI_IOV pci_assign_resource pci_assign_bus_resource allocate_resource find_resource pcibios_update_resource struct pci_dev (before pci_physfn) bus_list msi_enabled msix_enabled aer_cap, pcie_mpss <- key -> pci_driver pcie_capability_read_dword(pcid, PCI_EXP_LNKCAP, &lnk_cap); trlvx(lnk_cap); trlvx(lnk_cap & PCI_EXP_LNKCAP_LBNC); trlvx(pcid->class); trlvx(pcid->cfg_size); for (i = 0; i < DEVICE_COUNT_RESOURCE; ++i) { if (!pci_resource_flags(pcid, i)) continue; trlvd(i); trvs(pcid->resource[i].name); trlvx(pci_resource_start(pcid, i)); trlvx(pci_resource_len(pcid, i)); trlvx(pci_resource_flags(pcid, i)); //trlvx(pci_resource_flags(pcid, i) & IORESOURCE_TYPE_BITS); trvdnz((pci_resource_flags(pcid, i) & IORESOURCE_IO) > 0); trvdnz((pci_resource_flags(pcid, i) & IORESOURCE_MEM) > 0); }
CONFIG_HOTPLUG pci_insert_device pbus_assign_resources pbus_assign_resources_sorted pci_assign_resource ▻
pcibios_assign_resources 2.4-sh pci_assign_resource ▻
proc show_dev_config (/proc/pci) show_device pci_proc_attach_device
do_pci_enable_device device_ktype device_release devres_release_all < really_probe < __device_release_driver release_nodes release pcim_release pci_disable_device pcim_enable_device pci_devres get_pci_dr pcim_release devres_find devres_alloc __devres_alloc_node alloc_dr -> devres_get pci_enable_device __pci_enable_device pci_enable_device_bars pci_set_power_state pcibios_enable_device pcibios_enable_resources pci_read_config_word(dev, PCI_COMMAND, &cmd); pci_bus_read_config_word PCI_OP_READ bus->ops->read pcibios_enable_irq pirq_enable_irq "can't find IRQ for PCI INT" pci_fixup_device pci_disable_device do_pci_disable_device
Linux basic linux/config.h _LINUX_CONFIG_H include/linux/autoconf.h AUTOCONF_INCLUDED linux/version.h LINUX_VERSION_CODE KERNEL_VERSION linux/module.h _LINUX_MODULE_H linux/kernel.h _LINUX_KERNEL_H irq linux/sched.h _LINUX_SCHED_H task_struct
readl readw readb
lspci
pcitweak
cat /proc/bus/pci/devices
od -Ax -t x1 /proc/bus/pci/*/*
PCI Addressing
Configuration Space
#include <linux/pci.h>
pci_bus struct pci_dev -> struct pci_device_id;
pci_dev x pci_find_device x pci_find_class
pci_read_config_word pci_write_config_word
kobject_hotplug hotplug_path
pci_present obsolete readl readw readb
device drivers
-
Managing I/O Devices I/O Architecture Device Files Device Drivers Block Device Drivers Character Device Drivers
firmware request_firmware }
irq_affinity_setup "irqaffinity" irq_default_affinity
irq_default_affinity < irq_create_affinity_masks irq_affinity_setup init_irq_default_affinity desc_smp_init irq_setup_affinity default_affinity_show
irq_startup > irq_setup_affinity irq_default_affinity irq_desc __irq_can_set_affinity irq_do_set_affinity optimistic tmp_mask = mask & housekeeping_cpumask(HK_TYPE_MANAGED_IRQ) & cpu_online_mask
irqd_affinity_is_managed __irqd_to_state(d) IRQD_AFFINITY_MANAGED; hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ); chip->irq_set_affinity msi_set_affinity apic_set_affinity apic_set_affinity assign_managed_vector vector_matrix irq_data_get_affinity_mask vector_searchmask irq_matrix_alloc_managed -> vector matrix_find_best_cpu_managed apic_update_vector move_in_progress irq_matrix_free alloc_map vector_irq apic_update_irq_cfg -> msi_domain_set_affinity irq_chip_write_msi_msg irq_validate_effective_affinity irq_data_get_effective_affinity_mask-> irq_set_thread_affinity irqaction IRQTF_AFFINITY, cpumask_copy(desc->irq_common_data.affinity, mask);
kernel_init kernel_init_freeable do_basic_setup init_irq_proc register_default_affinity_proc /proc/irq/default_smp_affinity default_affinity_show irq_default_affinity default_affinity_write cpu_online_mask smp_prepare_cpus set_cpu_present
/proc/irq/*/effective_affinity /proc/irq/*/effective_affinity_list
"effective_affinity_list"
"smp_affinity" irq_affinity_proc_ops irq_affinity_proc_open irq_affinity_proc_show show_irq_affinity irq_desc::irq_data mask = desc->irq_common_data.affinity; mask = irq_data_get_effective_affinity_mask
irq_affinity_proc_write write_irq_affinity ->
irq_affinity_list_proc_ops irq_affinity_list_proc_open irq_affinity_list_proc_show show_irq_affinity -> irq_affinity_list_proc_write write_irq_affinity cpu_online_mask irq_can_set_affinity_usr !irqd_affinity_is_managed irq_select_affinity_usr irq_set_affinity ->
irq_common_data::msi_desc::irq_affinity_desc::mask irq_common_data::msi_desc::irq_affinity_desc::is_managed
start_kernel early_irq_init irq_desc desc_set_defaults irq_data irq ->irq_common_data ->irq_chip ->irq_domain irq_common_data affinity msi_desc msi_msg irq_affinity_desc cpumask mask; arch_early_irq_init x86_vector_domain_ops x86_vector_alloc_irqs assign_irq_vector_policy reserve_managed_vector irq_matrix_reserve_managed lapic_controller ->apic_set_affinity -> irqd_set_single_target IRQD_SINGLE_TARGET
irq_get_affinity_mask 14 irq_can_set_affinity 14 < dpaa_set_portal_irq_affinity tick_check_percpu __irq_can_set_affinity TODO irqd_can_balance !IRQD_PER_CPU & !IRQD_NO_BALANCING pci_alloc_irq_vectors_affinity 15 irq_data_get_effective_affinity_mask 17 irq_desc::irq_data::irq_common_data::effective_affinity; irq_affinity_desc 33 irq_set_affinity_notifier 30 irq_affinity_notify 41 irq_chip_set_affinity_parent 46 data->chip->irq_set_affinity irq_data_get_affinity_mask 47 irq_set_vcpu_affinity 47 irq_set_affinity_hint 167 irq_set_affinity_and_hint __irq_apply_affinity_hint affinity_hint __irq_set_affinity -> struct irq_affinity 265
15 irq_settings_is_per_cpu_devid _IRQ_PER_CPU_DEVID 16 irq_cpu_rmap_add irq_set_affinity_notifier -> 16 irq_set_percpu_devid irq_set_percpu_devid_partition irq_set_percpu_devid_flags 17 irqd_is_forwarded_to_vcpu __irqd_to_state(d) & IRQD_FORWARDED_TO_VCPU; 19 handle_percpu_devid_irq -> 26 free_irq_cpu_rmap irq_set_affinity_notifier -> 40 request_percpu_irq __request_percpu_irq -> 33 free_percpu_irq __free_percpu_irq 44 disable_percpu_irq irq_percpu_disable 48 enable_percpu_irq irq_percpu_enable
echo 4 > /proc/irq/24/effective_affinity_list
irq_set_affinity args irq cpumask not forced __irq_set_affinity args irq cpumask raw_spin_lock_irqsave irq_set_affinity_locked args irq_data cpumask irq_set_affinity_deactivated cpumask_copy(desc->irq_common_data.affinity, mask); irq_data_update_effective_affinity -> irq_can_move_pcntxt irqd_can_move_in_process_context IRQD_MOVE_PCNTXT < irq_settings_can_move_pcntxt irq_try_set_affinity irq_do_set_affinity -> irq_set_affinity_pending irq_data_to_desc irqd_set_move_pending IRQD_SETAFFINITY_PENDING irq_copy_pending pending_mask
irq_setup_generic_chip irq_modify_status irqd_clear IRQD_NO_BALANCING | IRQD_PER_CPU | IRQD_TRIGGER_MASK | IRQD_LEVEL | IRQD_MOVE_PCNTXT); irq_settings_can_move_pcntxt _IRQ_MOVE_PCNTXT irq_settings_clr_and_set IRQD_MOVE_PCNTXT irqd_set
CONFIG_GENERIC_IRQ_DEBUGFS x86_vector_domain_ops x86_vector_debug_show GENERIC_IRQ_DEBUGFS irq_debugfs_init irq_add_debugfs_entry dfs_irq_ops irq_debug_open irq_debug_show irqd_get __irqd_to_state irq_sysfs_init irq_lock_sparse sparse_irq_lock
irq_lock_sparse -> NMI: Non-maskable interrupts LOC: Local timer interrupts SPU: Spurious interrupts PMI: Performance monitoring interrupts IWI: IRQ work interrupts RTR: APIC ICR read retries RES: Rescheduling interrupts CAL: Function call interrupts TLB: TLB shootdowns TRM: Thermal event interrupts THR: Threshold APIC interrupts DFR: Deferred Error APIC interrupts MCE: Machine check exceptions MCP: Machine check polls ERR: MIS: PIN: Posted-interrupt notification event NPI: Nested posted-interrupt event PIW: Posted-interrupt wakeup event
__setup __setup_param tsc_setup tsc_clocksource_reliable
send_call_function_ipi_mask
"isolcpus=" housekeeping_isolcpus_setup tick domain managed_irq
DECLARE_DELAYED_WORK DECLARE_DEFERRABLE_WORK __queue_delayed_work delayed_work_timer_fn __queue_work ->
arch_timer_of_init arch_timer_register request_percpu_irq "arch_timer" arch_timer_evt arch_timer_handler_phys timer_handler evt->event_handler
handle_percpu_devid_irq bpftrace -e 'kprobe:handle_percpu_devid_irq { @[sym(((struct irq_desc *)arg0)->action->handler)] = count();}' ipi_handler -> arch_timer_handler_phys trace_irq_handler_entry irq_handler_entry irq_handler_entry: irq=12 name=arch_timer res = action->handler(irq, action->dev_id); trace_irq_handler_exit "irq_handler_exit"
trace_softirq_entry "softirq_entry" trace_softirq_exit "softirq_exit"
trace_softirq_raise "softirq_raise"
can_stop_full_tick check_tick_dependency
tick_irq_exit tick_nohz_irq_exit tick_nohz_full_update_tick
__tick_nohz_full_update_tick can_stop_full_tick check_tick_dependency trace_tick_stop "tick_stop"
msi_create_device_irq_domain msi_domain_for_each_desc msi_domain_first_desc msi_find_desc xa_for_each_start msi_next_desc msi_find_desc msi_setup_device_data msi_device_data msi_sysfs_create_group msi_irqs_group "msi_irqs" msi_device_data_release
msi_domain_populate_irqs irq_set_msi_desc irq_set_msi_desc_off desc->irq_common_data.msi_desc = entry; msi_domain_depopulate_descs
ice_alloc_irq pci_msix_can_alloc_dyn pci_msi_domain_supports MSI_FLAG_PCI_MSIX_ALLOC_DYN pci_msix_alloc_irq_at msi_domain_alloc_irq_at __msi_domain_alloc_irq_at __msi_domain_alloc_irqs __irq_domain_alloc_irqs msi_sysfs_populate_desc nvec_used sysfs_add_file_to_group irq_set_msi_desc_off ->
mlx5_msix_alloc mlx5_irq_alloc mlx5_vdpa_dev_add allocate_irqs pci_msix_alloc_irq_at
irq_get_msi_desc irq_get_irq_data irq_to_desc irq_data irq_data irq_common_data msi_desc
irq_data_get_msi_desc irq_get_irq_data d->common->msi_desc;
update_curr -> trace_sched_stat_runtime irq/338-ice-ens-4479 [009] d...2.. 94815.741415: sched_stat_runtime: comm=irq/338-ice-ens pid=4479 runtime=16111 [ns] vruntime=0 [ns]
ipi_send_cpu smp_send_reschedule trace_ipi_send_cpu wakeup_preempt old: check_preempt_curr arch_smp_send_reschedule native_smp_send_reschedule __apic_send_IPI(cpu, RESCHEDULE_VECTOR); send_IPI default_send_IPI_single __apic_send_IPI_mask send_IPI_mask ? flat_send_IPI_mask _flat_send_IPI_mask __default_send_IPI_dest_field native_apic_mem_write } alternative_io irq_work_raise
{ cpus_isolated_store cpus_timer_store }
{ irq_alloc_descs __irq_alloc_descs devm_irq_alloc_descs __devm_irq_alloc_descs __irq_alloc_descs irq_find_free_area irq_expand_nr_irqs mutex_lock(&sparse_irq_lock); alloc_descs alloc_desc kzalloc_node init_desc alloc_masks zalloc_cpumask_var_node desc->irq_common_data.affinity desc_set_defaults desc_smp_init(desc, node, affinity); irq_default_affinity cpumask_copy(desc->irq_common_data.affinity, affinity); irq_insert_desc sparse_irqs mas_store_gfp }
hisi_sas_v2_interrupt_preinit devm_platform_get_irqs_affinity platform_irq_count irq_calc_affinity_vectors irq_create_affinity_masks -> irq_update_affinity_desc irq_affinity_desc !irqd_affinity_is_managed affinity->is_managed IRQD_AFFINITY_MANAGED IRQD_MANAGED_SHUTDOWN cpumask_copy(desc->irq_common_data.affinity, &affinity->mask);
handle_edge_irq handle_percpu_irq irq_ack apic_ack_edge apic_ack_irq irq_move_irq irqd_is_setaffinity_pending IRQD_SETAFFINITY_PENDING __irq_move_irq irqd_irq_masked IRQD_IRQ_MASKED irq_move_masked_irq !irqd_is_per_cpu irq_do_set_affinity -> err: irqd_set_move_pending
__cpu_disable < take_cpu_down smp_ops.cpu_disable native_cpu_disable cpu_disable_common fixup_irqs irq_migrate_all_off_this_cpu for_each_active_irq irq_get_next_irq irq_find_at_or_after sparse_irqs irq_domain_deactivate_irq raw_spin_lock(&desc->lock); migrate_one_irq irq_datairq_data irq_chip irqd_irq_masked irq_mask: mask_ioapic_irq pci_irq_mask_msix < pci_msix_template irq_desc_get_irq_data irq_data irq_force_complete_move -> irq_fixup_move_pending irq_desc_get_pending_mask pending_mask irq_data_get_affinity_mask -> irq_do_set_affinity ->
housekeeping_cpumask(HK_TYPE_MANAGED_IRQ); irq_common_data.affinity irq_needs_fixup chip->irq_mask irqd_affinity_is_managed irqd_set_managed_shutdown IRQD_MANAGED_SHUTDOWN irq_shutdown_and_deactivate ->
cpuset cpuset_cpus_allowed cpuset_flagbits_t
irq_fixup_move_pending !irqd_is_setaffinity_pending pending_mask irqd_clr_move_pending ~IRQD_SETAFFINITY_PENDING
irq_force_complete_move irq_domain_get_irq_data apic_chip_data x86_vector_domain free_moved_vector irq_matrix_free vector_irq
irq_shutdown_and_deactivate irq_shutdown -> irq_domain_deactivate_irq __irq_domain_deactivate_irq (x86_vector_domain_ops) x86_vector_deactivate vector_assign_managed_shutdown apic_update_irq_cfg -> irq_data_update_effective_affinity -> irqd_clr_activated
start_kernel setup_arch .init.init_platform kvm_init_platform kvmclock_init cpuhp_setup_state __cpuhp_setup_state __cpuhp_setup_state_cpuslocked ->
nt cpu = cpumask_any_and(cpu_active_mask, cs->effective_cpus);
HK_TYPE_MANAGED_IRQ
kernel/locking/lockdep.c __lock_acquire mark_usage mark_lock mark_lock_irq valid_state print_usage_bug "WARNING: inconsistent lock state" "inconsistent {%s} -> {%s} usage"
LOCKDEP_STATE IN-HARDIRQ-W - holding a lock within an interrupt context with interrupts disabled HARDIRQ-ON-W - attempting to acquire a lock with interrupts enabled
lockdep print_deadlock_bug print_deadlock_scenario held_lock acquire_ip lock_acquire -> tick_nohz_highres_handler
timerfd_tmrproc
get_cpu_device
calls: entry_SYSCALL_64_after_hwframe do_syscall_64 ksys_write vfs_write kernfs_fop_write_iter online_store lock_device_hotplug_sysfs device_online device_lock cpu_subsys_online cpu_device_up ->
hotplug device_online ? cpu_subsys_online -> device_offline /sys/devices/system/cpu/hotplug/states
ret_from_fork_asm ret_from_fork kthread smpboot_thread_fn cpu_stopper_thread < cpu_stop_threads preempt_count_inc .. cpu_stopper multi_cpu_stop unsigned long flags; local_save_flags(flags); local_irq_restore(flags); take_cpu_down __cpu_disable -> cpuhp_invoke_callback_range_nofail __cpuhp_invoke_callback_range cpuhp_next_state cpuhp_invoke_callback -> hrtimers_cpu_dying native_cpu_disable set_cpu_online __cpu_online_mask -> cpu_online_mask __num_online_cpus -> num_online_cpus
HK_TYPE_TIMER ->
include/linux/sched/topology.h sched_domain_topology_level set_sched_topology sd_data sched_domain sched_group sched_load_balance isolcpus=domain HK_FLAG_DOMAIN HK_TYPE_DOMAIN ->
Requirements to control kernel isolation/nohz_full at runtime schedule_user not used exception_enter schedule exception_exit preempt_schedule_notrace Start using bpftrace/eBPF for latency and load tests. frederic housekeeping_cpumask_set housekeeping_cpumask_clear housekeeping_cpumask_update rcu_nocb_cpumask_update cpumask_or cpumask_andnot waiman longman pool_workqueue +plugged unplug_oldest_pwq init_rescuer +wq_unbound_cpumask ordered_workqueue_ref_check workqueue_apply_unbound_cpumask ordered_workqueue_ref_check apply_wqattrs_commit +unbound_effective_cpumask unbound_pwq unbound_pwq_slot __pod_cpumask apply_wqattrs_prepare __WQ_ORDERED plugged
apply_wqattrs_cleanup pwq_tryinc_nr_active pool_workqueue frozen pwq_release_workfn +thaw_pwq rcu_nocb_cpumask_update frederic rcu_nocb_cpu_offload -> rcu_nocb_cpu_deoffload -> rcu_nocb_enabled update_isolation_cpumasks w2 <- update_unbound_workqueue_cpumask lockdep_assert_cpus_held workqueue_unbound_exclude_cpumask -> HOUSEKEEPING_FLAGS housekeeping_exlude_isolcpus w1 lockdep_assert_cpus_held housekeeping_copy2_boot w1 housekeeping_boot w1 + my housekeeping_update -> WRITE_ONCE __WRITE_ONCE volatile housekeeping.flags rcu_nocb_mask_preset cpuset.cpus.isolation_full, isolation_full
wq_requested_unbound_cpumask hk=wq_isolated_cpumask workqueue_unbound_exclude_cpumask -> dfl_files +cpuset_write_isolfull update_isolation_cpumasks remote_partition_enable +update_isolation_cpumasks remote_partition_disable +update_isolation_cpumasks remote_cpus_update +update_isolation_cpumasks update_parent_effective_cpumask +update_isolation_cpumasks update_prstate +update_isolation_cpumasks
CONFIG_RCU_NOCB_CPU rcu_init_nohz rcu_torture_init rcu_nocb_toggle rcu_nocb_cpu_offload rcu_rdp_is_offloaded rcu_segcblist_is_offloaded rcu_segcblist_test_flags SEGCBLIST_LOCKING rcu_nocb_mask work_on_cpu(cpu, rcu_nocb_rdp_offload, rdp); rcu_nocb_cpu_deoffload rcu_nocb_rdp_deoffload rdp_offload_toggle rcu_segcblist_offload rcu_nocb_rdp_offload rdp_offload_toggle rcu_nocb_cb_kthread
CONFIG_HOTPLUG_CPU unregister_cpu arch_cpu_probe arch_cpu_release remove_cpu ... cpu_subsys cpu_subsys_online cpu_device_up(dev); cpu_up(dev->id, CPUHP_ONLINE); try_online_node(cpu_to_node(cpu)); mem_hotplug_begin cpus_read_lock
_cpu_up(cpu, 0, target); cpus_write_lock percpu_down_write(&cpu_hotplug_lock); __percpu_down_write_trylock cpuhp_up_callbacks cpuhp_invoke_callback_range __cpuhp_invoke_callback_range -> cpuhp_invoke_callback -> cpu_subsys_offline cpu_device_down cpu_down(dev->id, CPUHP_OFFLINE); cpu_maps_update_begin mutex_lock(&cpu_add_remove_lock); cpu_down_maps_locked -> cpu_maps_update_done hotpluggable sched_cpu_wait_empty sched_cpu_dying idle_task_exit cpuhp_hp_states CPUHP_HRTIMERS_PREPARE hrtimers_prepare_cpu timerqueue_init_head hrtimers_cpu_dying | hrtimers_dead_cpu -> CPUHP_TIMERS_PREPARE timers_prepare_cpu -> timers_dead_cpu -> rcutree_dead_cpu rcutree_dying_cpu rcutree_offline_cpu rcu_lockdep_current_cpu_online torture_num_online_cpus tick_broadcast_offline
cpuhp_hp_states cpuhp_bringup_ap bringup_wait_for_ap_online wait_for_ap_thread kthread_unpark KTHREAD_IS_PER_CPU __kthread_bind cpumask_of get_cpu_mask cpu_bit_bitmap to_cpumask __kthread_bind_mask ->
cpuhp_kick_ap __cpuhp_kick_ap should_run
sched_cpu_activate cpuset_cpu_active - cpuset_update_active_cpus - - cpuset_handle_hotplug cpuset_hotplug_update_tasks remote_partition_disable
sched_cpu_deactivate set_cpu_active
"irq/affinity:online" irq_affinity_online_cpu CPUHP_AP_HRTIMERS_DYING hrtimers_cpu_dying | hrtimers_dead_cpu hrtimer_bases hrtimer_cpu_base -> cpu_active_mask x tick_cancel_sched_timer sched_timer hrtimer_cancel hrtimer_try_to_cancel hrtimer_clock_base hrtimer_active hrtimer_callback_running remove_hrtimer hrtimer_cancel_wait_running migrate_hrtimer_list timerqueue_node timerqueue_getnext timerqueue_head rb_first_cached __remove_hrtimer enqueue_hrtimer -> timerqueue_add __hrtimer_get_next_event __hrtimer_next_event_base smp_call_function_single generic_exec_single __smp_call_single_queue -> tick_handover_do_timer tick_shutdown
takeover_tasklets
cpuhp_setup_state_nocalls __cpuhp_setup_state cpus_read_lock cpu_hotplug_lock percpu_down_read __cpuhp_setup_state_cpuslocked cpuhp_store_callbacks cpuhp_issue_call cpuhp_invoke_callback cpuhp_get_step hrtimers_cpu_dying ->
object_cpu_offline cpuhp_issue_call cpuhp_invoke_ap_callback cpuhp_invoke_callback
smpboot_thread_fn cpuhp_threads.thread_fn cpuhp_thread_fun cpuhp_state local_irq_disable cpuhp_invoke_callback sched_cpu_activate set_cpu_active
irq_affinity_online_cpu irq_restore_affinity_of_irq -> irqd_affinity_is_managed irqd_is_managed_and_shutdown IRQD_MANAGED_SHUTDOWN irq_startup -> irqd_is_single_target IRQD_SINGLE_TARGET hk_should_isolate -> HK_TYPE_MANAGED_IRQ irq_set_affinity_locked -> ... irq_do_set_affinity-> ... apic_update_irq_cfg ->
housekeeping housekeeping_setup -> housekeeping_setup_type -> housekeeping_init < start_kernel static_branch_enable(&housekeeping_overridden); housekeeping_enabled !!(housekeeping.flags & BIT(type)); housekeeping_cpumask (const) housekeeping.flags & BIT(type) housekeeping.cpumasks[type]; cpu_possible_mask; housekeeping_cpu housekeeping_test_cpu(cpu, type); if (housekeeping.flags & BIT(type)) return cpumask_test_cpu(cpu, housekeeping.cpumasks[type]); housekeeping_any_cpu sched_numa_find_closest(housekeeping.cpumasks[type], smp_processor_id()); sched_domains_numa_masks HK_TYPE_TIMER used by: __queue_delayed_work add_timer_on(timer, cpu); try_to_generate_entropy < wait_for_random_bytes urandom_read_iter cpumask_and(&timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask); add_timer_on get_timer_cpu_base -> forward_timer_base internal_add_timer -> add_timer_on(&stack->timer, cpu); lockup_detector_init < kernel_init_freeable -> cpumask_copy(&watchdog_cpumask, housekeeping_cpumask(HK_TYPE_TIMER));
... lockup_detector_reconfigure __lockup_detector_reconfigure -> freeze_secondary_cpus, /CONFIG_PM_SLEEP_SMP/ < hibernate_resume_nonboot_cpu_disable hibernate_resume_nonboot_cpu_disable hibernate_resume_nonboot_cpu_disable suspend_disable_secondary_cpus _cpu_down cpuhp_down_callbacks cpuhp_invoke_callback takedown_cpu CPUHP_TEARDOWN_CPU take_cpu_down arch_cpuhp_cleanup_dead_cpu tick_cleanup_dead_cpu get_nohz_timer_target < switch_hrtimer_base > get_target_base __mod_timer > get_target_base idle_cpu sudo bpftrace -e 'kprobe:idle_cpu {@cpu[tid] = arg0;} kretprobe:idle_cpu {printf("%u %u\n", @cpu[tid], retval);delete(@cpu[tid]);} END{clear(@cpu);}' housekeeping_cpu(cpu, HK_TYPE_TIMER)) migrate_hrtimer_list -> CPUHP_TIMERS_PREPARE timers_prepare_cpu per_cpu_ptr(&timer_bases[b], cpu); timers_dead_cpu get_cpu_ptr -> raw_spin_lock_irq do_raw_spin_lock -> raw_spin_lock_nested timer_bases migrate_timer_list hlist_entry detach_timer internal_add_timer put_cpu_ptr -> housekeeping_any_cpu(HK_TYPE_TIMER); kvm_x86_vendor_init pi_inject_timer = housekeeping_enabled(HK_TYPE_TIMER); kvm_can_post_timer_interrupt pi_inject_timer HK_TYPE_MANAGED_IRQ is used by: ... irq_do_set_affinity -> < irq_setup_affinity -> chip->irq_set_affinity housekeeping_isolcpus_setup "domain" HK_FLAG_DOMAIN "managed_irq" HK_FLAG_MANAGED_IRQ housekeeping_setup -> cpuhp_hp_states - irq_affinity_online_cpu irq_restore_affinity_of_irq irq_data_get_affinity_mask -> hk_should_isolate < irq_restore_affinity_of_irq -> irq_data_get_effective_affinity_mask hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ); cpumask_test_cpu irq_set_affinity_locked -> ... irq_do_set_affinity-> housekeeping_cpumask(HK_TYPE_MANAGED_IRQ); irq_common_data.affinity
HK_TYPE_KTHREAD is used by: unbound - NUMA_NO_NODE create_kthread kthread ass pointer set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_TYPE_KTHREAD)); kthreadd -> set_cpus_allowed_ptr(tsk, housekeeping_cpumask(HK_TYPE_KTHREAD)); sysctl_est_cpulist housekeeping_cpumask(HK_TYPE_KTHREAD); ipvs_proc_est_cpumask_get mask = (struct cpumask *)housekeeping_cpumask(HK_TYPE_KTHREAD); HK_TYPE_RCU rcu_boost_kthread_setaffinity rcu_bind_gp_kthread rcu_tasks_kthread HK_TYPE_MISC, create_core_data find_new_ilb HK_TYPE_SCHED nohz_balance_enter_idle nohz_newidle_balance HK_TYPE_TICK cpu_is_isolated -> scheduler_tick sched_tick_start .. sched_tick_remote curr->sched_class->task_tick task_tick_fair -> task_tick_rt -> sched_tick_stop TICK_SCHED_REMOTE_OFFLINING HK_TYPE_DOMAIN, print_cpus_offline grep '' /sys/devices/system/cpu/{offline,online,possible,present} cpumask_andnot(offline, cpu_possible_mask, cpu_online_mask); print_cpus_isolated cpu_possible_mask & !housekeeping_cpumask(HK_TYPE_DOMAIN) pci_call_probe cpu_is_isolated -> generate_sched_domains HK_TYPE_DOMAIN alloc_sched_domains prstate_housekeeping_conflict cpu_down_maps_locked sched_init_smp cpu_active_mask < set_cpu_active sched_init_domains asym_cpu_capacity_scan alloc_sched_domains set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_TYPE_DOMAIN)) partition_sched_domains_locked rps_cpumask_housekeeping HK_TYPE_WQ Q: /sys/devices/virtual/workqueue/cpumask workqueue_sysfs_register pci_call_probe rps_cpumask_housekeeping
workqueue_init_early restrict_unbound_cpumask update_cpumask remote_cpus_update partition_xcpus_add partition_xcpus_newstate isolated_cpus partition_xcpus_del cpumask_and(xcpus, xcpus, cpu_active_mask); partition_xcpus_newstate -> cpuset_css_offline > update_prstate "cpus.partition" - sched_partition_show - - partition_root_state - sched_partition_write is_cpuset_online - - "isolated" - - cpus_read_lock - - mutex_lock(&cpuset_mutex); - - update_prstate update_partition_exclusive partition_root_state remote_partition_enable remote_partition_disable partition_xcpus_add update_unbound_workqueue_cpumask -> update_parent_effective_cpumask update_unbound_workqueue_cpumask isolated_cpus workqueue_unbound_exclude_cpumask wq_isolated_cpumask = exclude_cpumask wq_requested_unbound_cpumask &= !exclude_cpumask workqueue_apply_unbound_cpumask workqueues apply_wqattrs_prepare wqattrs_actualize_cpumask attrs->cpumask wq_unbound_cpumask partition_xcpus_newstate -> update_isolation_cpumasks wq_unbound_cpumask_store workqueue_set_unbound_cpumask wq_requested_unbound_cpumask workqueue_apply_unbound_cpumask ->
cpuhp_hp_states workqueue_online_cpu wq_update_pod workqueue_offline_cpu unbind_workers unbind_worker kthread_set_per_cpu -1 wq_update_pod wq_calc_pod_cpumask
arm PMU Performance Monitoring Unit runc rmqueue
__arm64_sys_prctl __do_sys_prctl sys_prctl PR_SET_SECCOMP prctl_set_seccomp do_seccomp seccomp_set_mode_strict not called spin_lock_irq current->sighand->siglock seccomp_assign_mode arch_seccomp_spec_mitigate seccomp_set_mode_filter 4683 us ... seccomp_may_assign_mode has_duplicate_listener spin_lock_irq seccomp_attach_filter 275 us seccomp_can_sync_threads for_each_thread seccomp_cache_prepare ? seccomp_cache_prepare_bitmap for (nr = 0; nr < bitmap_size; nr++) { seccomp_is_const_allow seccomp_sync_threads for_each_thread list_for_each_entry_rcu -> seccomp_assign_mode ..4 us seccomp_get_action_avail seccomp_get_notif_sizes _raw_spin_unlock_irq el1h_64_irq ... hrtimer_wakeup
dynticks wake_up_nohz_cpu wake_up_full_nohz_cpu tick_nohz_full_cpu tick_nohz_full_enabled context_tracking_enabled context_tracking_key tick_nohz_full_running tick_nohz_full_mask tick_nohz_full_kick_cpu irq_work_queue_on(&per_cpu(nohz_full_kick_work, cpu), cpu);
CONFIG_NO_HZ_FULL NO_HZ_FULL start_kernel tick_init tick_broadcast_init tick_nohz_init tick_nohz_full_mask context_tracking_cpu_set cpuhp_setup_state_nocalls CPUHP_AP_ONLINE_DYN, &tick_nohz_cpu_down tick_nohz_cpu_hotpluggable rcu_user_enter rcu_user_exit rcu_nohz_full_cpu sched_can_stop_tick sched_tick_offload_init
__setup "nohz_full" sets housekeeping to negative argument housekeeping_nohz_full_setup HK_FLAG_TICK HK_FLAG_WQ HK_FLAG_TIMER HK_FLAG_RCU HK_FLAG_MISC HK_FLAG_KTHREAD sets housekeeping.cpumasks for tick, wq, timer, rcu, misc, and kthread housekeeping_setup sets housekeeping to negative argument alloc_bootmem_cpumask_var cpu_present_mask housekeeping_setup_type(type, housekeeping_staging); cpumask_copy(housekeeping.cpumasks[type], housekeeping_staging); tick_nohz_full_setup cpumask_copy tick_nohz_full_mask tick_nohz_full_running = true; print_cpus_nohz_full tick_nohz_full_mask __tick_nohz_full_update_tick tick_nohz_stop_sched_tick show_state_filter sched_show_task sysrq_sched_debug_show kernel/sched/debug.c "Sched Debug Version" print_cpu
4 apic_timer_interrupt➝ smp_apic_timer_interrupt➝ hrtimer_interrupt CONFIG_HIGH_RES_TIMERS now = hrtimer_update_base(cpu_base); ktime_before __hrtimer_run_queues➝ raise_hrtimer_softirq HRTIMER_SOFTIRQ raise_ktimers_thread __this_cpu_or(pending_timer_softirq, 1 << nr);
static inline void hrtimer_set_expires_range timer->_softexpires = time; timer->node.expires = ktime_add_safe(time, delta);
hrtimer_get_expires timer->node.expires
hrtimer_get_softexpires timer->_softexpires
__ro_after_init apic_timer_interrupt
asm_sysvec_apic_timer_interrupt➝sysvec_apic_timer_interrupt➝__sysvec_apic_timer_interrupt➝
sysvec_apic_timer_interrupt local_apic_timer_interrupt event_handler -> tick_handle_periodic tick_periodic update_process_times run_local_timers hrtimer_run_queues ->
hrtimer_run_queues tick_switch_to_oneshot
raw_spin_lock_irqsave(&cpu_base->lock, flags); -> tick_check_oneshot_change tick_nohz_lowres_handler tick_nohz_handler tick_sched_do_timer tick_sched_handle -> hrtimer_forward tick_program_event tick_nohz_switch_to_nohz tick_setup_sched_timer tick_nohz_handler !hrtimer_is_hres_enabled hrtimer_switch_to_hres tick_init_highres tick_setup_sched_timer hrtimer_init(&ts->sched_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD); tick_nohz_handler sched_skew_tick &tick_nohz_highres_handler tick_sched_do_timer tick_do_update_jiffies64 tick_sched_handle -> hrtimer_forward tick_sched_timer -> tick_nohz_activate tick_sched_flag_set(ts, TS_FLAG_NOHZ); timers_update_nohz schedule_work(&timer_update_work);
hrtimer_run_softirq hrtimer_interrupt hrtimer_run_queues > __hrtimer_run_queues __run_hrtimer timer->function
hrtimer_get_softexpires (hrtimer_get_softexpires_tv64)
local_pending_timers __this_cpu_read(pending_timer_softirq) tick_sched_timer➝ tick_sched_handle➝ update_process_times➝ tick_sched_do_timer➝ scheduler_tick➝ task_tick -> task_tick_fair entity_tick update_curr -> update_load_avg -> update_cfs_group -> resched_curr_lazy resched_curr set_preempt_need_resched PREEMPT_NEED_RESCHED smp_send_reschedule set_tsk_need_resched_lazy set_tsk_thread_flag(tsk,TIF_NEED_RESCHED_LAZY); check_preempt_tick update_misfit_status update_overutilized_status
spawn_ksoftirqd timer_threads timersd run_timersd -> smpboot_register_percpu_thread smpboot_register_percpu_thread_cpumask __smpboot_create_thread kthread_create_on_cpu .. smpboot_thread_fn ->
test_preempt_need_resched
spawn_ksoftirqd softirq_threads run_ksoftirqd NRT __do_softirq ->
ret_from_fork kthread smpboot_thread_fn kthread_should_stop kthread_should_park __kthread_should_park
run_timersd RT __do_softirq hrtimer_run_softirq -> __hrtimer_run_queues ? tick_sched_timer➝ timerqueue_getnext __run_hrtimer -> sched_cfs_period_timer < __run_hrtimer ? set_kthread_struct
5 sched_debug 5 /sys/kernel/debug/sched/debug
4 init_sched_debug_procfs "sched_debug" /proc/sched_debug sched_debug_sops sched_debug_show print_cpu kernel/sched/debug.c "cpu#" print_cfs_stats for_each_leaf_cfs_rq_safe cfs_rq print_cfs_rq cpu_rq per_cpu per_cpu_ptr "cfs_rq" task_group_path autogroup_path cgroup_path kernfs_path kernfs_path_from_node throttled throttle_count cfs_rq->throttle_count print_cfs_group_stats /proc/sched_debug schedstat_enabled sleep_max in ms block_max wait_max sum_exec_runtime vruntime
print_rq "runnable tasks" print_task se.statistics.wait_sum print_rt_stats print_rt_rq "rt_rq"
sched_schedstats
echo 0 > events/workqueue/workqueue_execute_start/enable echo 0 > events/workqueue/workqueue_execute_end/enable echo 0 > events/workqueue/workqueue_activate_work/enable echo 0 > events/workqueue/workqueue_queue_work/enable
echo 1 > events/sched/sched_stat_wait/enable echo 1 > events/sched/sched_stat_iowait/enable echo 1 > events/sched/sched_stat_blocked/enable
echo 1 > events/sched/sched_stat_sleep/enable
echo 1 > /proc/sys/kernel/sched_schedstats sysctl kernel.sched_schedstats=1 set_schedstats
echo 1 > /proc/sys/kernel/sched_schedstats cat /proc/self/sched
grep se.statistics.wait_sum /proc/*/sched
latency_warn_ms sysctl_resched_latency_warn_ms cpu_resched_latency scheduler_tick resched_latency_warn
fair_sched_class set_next_task_fair set_next_entity update_stats_wait_end -> __dequeue_entity rb_erase_cached(&se->run_node, &cfs_rq->tasks_timeline) ? se->exec_start = rq_clock_task(rq_of(cfs_rq))u update_load_avg cfs_rq_clock_pelt rq_clock_pelt(rq_of(cfs_rq)) - cfs_rq->throttled_clock_task_time rq_clock_pelt rq->clock_pelt - rq->lost_idle_time cfs_rq->throttled_clock_task - cfs_rq->throttled_clock_task_time update_stats_curr_start se->exec_start = rq_clock_task(rq_of(cfs_rq));
Async unthrottling for cfs bandwidth distribute_cfs_runtime unthrottle_cfs_rq_async __unthrottle_cfs_rq_async unthrottle_cfs_rq -> throttled_csd_list
cfsb_csd __cfsb_csd_unthrottle cfsb_csd_list
CONFIG_FAIR_GROUP_SCHED .task_change_group = task_change_group_fair RT_GROUP_SCHED CGROUP_SCHED FAIR_GROUP_SCHED CONFIG_CFS_BANDWIDTH cfs_bandwidth_used sysctl_sched_cfs_bandwidth_slice tg_get_cfs_quota tg_set_cfs_quota -> tg_set_cfs_bandwidth -> cfs_rq_clock_pelt Per-Entity Load Tracking cfs_bandwidth_used ... cfs_bandwidth_usage_inc __cfs_bandwidth_used cfs_bandwidth_usage_dec cfs_rq += runtime_enabled throttled_clock
throttled_clock_task_time throttle_count ... pick_next_task __pick_next_task_fair pick_next_task_fair kernel/sched/fair.c check_cfs_rq_runtime ^ put_prev_entity ^ set_next_entity hrtick_enabled_fair hrtick_enabled -> hrtick_start_fair -> + hrtick_enabled_bw : sched_feat(HRTICK_BW)) && hrtick_enabled hrtick_enabled cpu_active(cpu_of(rq))) hrtimer_is_hres_active(&rq->hrtick_timer)
+ start_hrtick_cfs_bw : tick_nohz_full_cpu && cfs_bandwidth_used && cfs_rq->runtime_enabled rq->nr_running == 1 && cfs_rq->runtime_remaining hrtick_start -> __pick_next_task_fair pick_next_task_fair ^
sched_fork rt_sched_class
enqueue_entity < ... 4 update_stats_enqueue update_stats_wait_start wait_start = rq_clock(rq_of(cfs_rq)); rq->clock trace_sched_stat_wait trace sched_stat_wait 4 update_stats_enqueue_sleeper update_stats_enqueue_fair update_stats_wait_start_fair __update_stats_wait_start update_stats_enqueue_sleeper_fair schedstat_enabled __update_stats_enqueue_sleeper statistics.sleep_max trace_sched_stat_sleep trace_sched_stat_iowait trace_sched_stat_blocked
__enqueue_entity __entity_less rb_add_cached(&se->run_node, &cfs_rq->tasks_timeline, __entity_less); se->on_rq = 1 check_enqueue_throttle account_cfs_rq_runtime -> throttle_cfs_rq -> update_cfs_group reweight_entity update_curr ->
< throttle_cfs_rq dequeue_task_fair < fair_sched_class dequeue_entity return_cfs_rq_runtime __return_cfs_rq_runtime slack_runtime = cfs_rq->runtime_remaining - min_cfs_rq_runtime cfs_rq->runtime_remaining -= slack_runtime
reweight_task update_cfs_group
rt_sched_class fair_sched_class : sched_class .enqueue_task enqueue_task_fair cfs_rq_throttled enqueue_entity -> put_prev_task_fair put_prev_entity check_cfs_rq_runtime throttle_cfs_rq -> update_stats_wait_start __enqueue_entity -> update_load_avg list_add_leaf_cfs_rq leaf_cfs_rq_list hrtick_update hrtick_start_fair sched_slice __sched_period update_load_add __calc_delta hrtick_start kernel/sched/core.c hrtimer hrtick_timer hrtick_time __hrtick_restart hrtick_timer hrtimer_start -> .. hrtick smp_call_function_single_async generic_exec_single -> hrtick_csd
.rq_offline < set_rq_offline rq_offline_fair unthrottle_offline_cfs_rqs list_for_each_entry_rcu(tg, &task_groups throttle_count cfs_rq->runtime_remaining = 1 cfs_rq->runtime_enabled = 0 unthrottle_cfs_rq ->
throttle_cfs_rq __assign_cfs_rq_runtime list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); cfs_rq->runtime_remaining <= 0 : walk_tg_tree_from tg_throttle_down list_add_tail_rcu(&cfs_rq->throttled_list, &cfs_b->throttled_cfs_rq); throttled_clock_task = rq_clock_task throttle_count++ dequeue_entity DEQUEUE_SLEEP update_curr -> update_load_avg 4 update_stats_dequeue 5 update_stats_wait_end_fair schedstat_enabled sched_schedstats __update_stats_wait_end delta wait_max grep -E 'wait_max *: [0-9]{3}' /sys/kernel/debug/sched/debug wait_coun wait_sum wait_start = 0 sleep_start = block_start = __dequeue_entity -> se->on_rq = 0; account_entity_dequeue return_cfs_rq_runtime update_cfs_group cfs_rq->throttled = 1 throttled_clock
__cfsb_csd_unthrottle <.. unthrottle_cfs_rq cfs_b->throttled_time += rq_clock(rq) - cfs_rq->throttled_clock; cfs_rq->throttled = 0 list_del_rcu(&cfs_rq->throttled_list); tg_unthrottle_up throttle_count-- throttled_clock_task_time += rq_clock_task - throttled_clock_task list_add_leaf_cfs_rq enqueue_entity ENQUEUE_WAKEUP -> rq_clock(rq) - cfs_rq->throttled_clock cfs_rq_throttled cfs_bandwidth_used __cfs_bandwidth_used cfs_rq->throttled list_add_leaf_cfs_rq -> resched_curr
brew download-task child_cfs_rq_on_list
cgcreate cgclassify
do_syscall_64 syscall_trace_enter trace_sys_enter syscall_exit_work trace_sys_exit
SYSCALL_METADATA SYSCALL_TRACE_ENTER_EVENT print_syscall_enter "%s: " SYSCALL_TRACE_EXIT_EVENT print_syscall_exit " -> "
entry_SYSCALL_64_after_hwframe➝do_syscall_64➝
do_mkdirat➝vfs_mkdir➝kernfs_iop_mkdir➝ cgroup_mkdir➝ cgroup_apply_control_enable➝ cpu_cgroup_css_alloc➝ sched_create_group➝
context_tracking_user_enter user_enter context_tracking_enter __context_tracking_enter trace_user_enter
--skip-chdir --userspec=USER:GROUP
retint_user➝ prepare_exit_to_usermode➝ exit_to_usermode_loop➝ schedule➝ trace_hardirqs_off_thunk➝ __schedule➝ put_prev_task_fair➝ put_prev_entity➝ __account_cfs_rq_runtime➝
ret_from_fork➝ set_kthread_struct➝ kthread➝ smpboot_register_percpu_thread_cpumask➝ smpboot_thread_fn➝ schedule➝
select_task_rq
sched_energy_enabled find_idlest_cpu select_idle_sibling select_idle_cpu select_idle_core sched_idle_cpu(cpu) cpumask_test_cpu(cpu, p->cpus_ptr)) BTW: tsk->cpus_ptr = &tsk->cpus_mask;
schedule sched_submit_work __schedule➝ + hrtick_clear trace_sched_switch deactivate_task dequeue_task dequeue_task_fair dequeue_entity➝ update_stats_dequeue-> update_curr rq_clock_task assert_clock_updated WARNING: CPU: 2 PID: 54342 at kernel/sched/sched.h:1207 assert_clock_updated.isra.74.part.75+0x13/0x20 SCHED_WARN_ON(rq->clock_update_flags < RQCF_ACT_SKIP); rq->clock_task sum_exec_runtime -> usage_usec, sum_sched_runtime vruntime update_min_vruntime min_vruntime account_cfs_rq_runtime -> context_switch finish_task_switch finish_lock_switch raw_spin_rq_unlock_irq(rq); raw_spin_rq_unlock_irq set_tsk_need_resched set_tsk_thread_flag task_thread_info set_ti_thread_flag TIF_NEED_RESCHED need_resched tif_need_resched TIF_NEED_RESCHED TIF_NEED_RESCHED_LAZY
sched_update_worker
CONFIG_PREEMPT_DYNAMIC preempt_dynamic_mode cat /sys/kernel/debug/sched/preempt
preempt_model_none preempt_model_voluntary preempt_model_full
might_sleep
cond_resched __cond_resched should_resched preempt_schedule_common need_resched tif_need_resched ->
got_nohz_idle_kick NOHZ_KICK_MASK
task_sched_runtime update_curr_fair update_curr delta_exec = now - curr->exec_start statistics.exec_max curr->sum_exec_runtime += delta_exec; update_min_vruntime trace_sched_stat_runtime cgroup_account_cputime cpuacct_charge usages account_group_exec_runtime sum_exec_runtime account_cfs_rq_runtime delta_exec ... __account_cfs_rq_runtime cfs_rq->runtime_remaining -= delta_exec assign_cfs_rq_runtime sched_cfs_bandwidth_slice __assign_cfs_rq_runtime start_cfs_bandwidth -> cfs_b->runtime -= amount cfs_rq->runtime_remaining += amount; resched_curr_lazy ->
echo distribute_cfs_runtime > set_ftrace_filter
set_ftrace_notrace
echo function > current_tracer
echo nop > current_tracer
echo 1 > tracing_on echo 0 > tracing_on echo > trace
sched_create_group alloc_fair_sched_group init_cfs_bandwidth default_cfs_period period_timer sched_cfs_period_timer < __run_hrtimer cfs_bandwidth hrtimer_forward_now timer->base->get_time() hrtimer_bases ktime_get ->
hrtimer_forward hrtimer_get_expires timer->node.expires ktime_sub hrtimer_add_expires_ns timer->node.expires = timer->_softexpires = hrtimer_get_expires_tv64 hrtimer_add_expires ktime_add_safe ktime_add_unsafe do_sched_cfs_period_timer throttled = !list_empty(&cfs_b->throttled_cfs_rq) cfs_b->nr_periods += overrun __refill_cfs_bandwidth_runtime cfs_b->runtime = cfs_b->quota; cfs_b->nr_throttled += overrun; distribute_cfs_runtime cfs_rq list_for_each_entry_rcu cfs_b->throttled_cfs_rq
cfs_rq->runtime_remaining += runtime; cfs_b->runtime -= runtime
cfs_rq->runtime_remaining > 0 unthrottle_cfs_rq ^ hrtimer_init CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED
hrtimer_init(&cfs_b->slack_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL)
snd_hrtimer_callback hrtimer_resolution drift = ktime_sub(hrt->base->get_time(), hrtimer_get_expires(hrt)); snd_timer_interrupt
task_struct ..> task_group sched_entity -> cfs_rq rq load_weight sched_rt_entity sched_dl_entity
rq -> cfs_rq
task_group -> cfs_rq cfs_bandwidth throttled_cfs_rq
"throttled_usec" = throttled_time
cpu.cfs_period_us cpu.cfs_quota_us cpu.shares "cpu.stat" cpu_cfs_stat_show nr_periods nr_throttled throttled_time
"cfs_quota_us" tg_set_cfs_quota tg_set_cfs_bandwidth cfs_bandwidth->quota start_cfs_bandwidth cfs_b->period_active = 1 hrtimer_forward_now -> hrtimer_start_expires -> cfs_bandwidth_usage_inc __refill_cfs_bandwidth_runtime -> cfs_bandwidth_usage_dec unthrottle_cfs_rq ->
sched_cpu_deactivate set_rq_offline rq_offline ... cpu_attach_domain rq_attach_root set_rq_offline ->
wake_up_state: try_to_wake_up kernel/sched/core.c ttwu_state_match p == current trace_sched_waking trace_sched_wakeup ttwu_runnable task_on_rq_queued on_rq == TASK_ON_RQ_QUEUED ttwu_do_wakeup trace_sched_wakeup __state = TASK_RUNNING
trace_sched_waking ttwu_stat ttwu_queue ttwu_queue_wakelist TTWU_QUEUE ttwu_queue_cond
__ttwu_queue_wakelist llist_add llist_add_batch sched_clock_cp > sched_clock ttwu_do_activate if (p->sched_contributes_to_load) rq->nr_uninterruptible--; activate_task -> enqueue_task(rq, p, flags); p->on_rq = TASK_ON_RQ_QUEUED; ? inc_nr_running ttwu_do_wakeup ->
-
try_to_wake_up … __flush_smp_call_function_queue sched_ttwu_pending ttwu_do_activate ttwu_do_wakeup
< ttwu_do_activate ttwu_runnable
< wake_up_process wake_up_state default_wake_function
... try_to_freeze try_to_freeze_unsafe __refrigerator set_current_state(TASK_FROZEN) freezing freezing_slow_path cgroup_freezing task_freezer schedule ... kthread_freezable_should_stop __refrigerator
echo 'func * =pf' > control; dmesg -tw | cut -f1 -d: | while read a;do echo $a; echo "func $a =_" > control; done
dmesg -Tw | grep -v -e 'CDROM\|ADDRCONF\|promiscuous'
WQ_WATCHDOG workqueue.watchdog_thresh wq_watchdog_thresh wq_watchdog_timer_fn
/sys/module/workqueue/parameters/watchdog_thresh
workqueues i40e Intel 40 GB Ethernet cryptd MEM_RECLAIM WQ_UNBOUND WQ_MEM_RECLAIM
xfs_init_mount_workqueues
xxx INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
m_blockgc_wq
workqueue_struct pool_workqueue
wq_watchdog_timer_fn show_workqueue_state "Showing busy workqueues and worker pools:" workqueues pool_workqueue show_pwq pr_cont_work pr_cont_pool_info
pool_workqueue
git config remote.pushDefault my
unshare sys_unshare ksys_unshare unshare_fs
setns sys_setns commit_nsset set_fs_root
kcmp sys_kcmp kcmp_lock kcmp_ptr kcmp_unlock
hwlat_sample -> hwlat_entry wlat_tracer hwlat_tracer_init
init_tracer_tracefs "tracing_on" rb_simple_fops rb_simple_write start hwlat_tracer_start -> hwlat_tracer_stop stop_single_kthread rb_simple_read tracer_tracing_is_on ring_buffer_record_is_on tracing_set_tracer hwlat_tracer_reset hwlat_tracer_stop "current_tracer" set_tracer_fops tracing_set_trace_write tracing_set_tracer ->
init_hwlat_tracer ... hwlat_tracer hwlat_tracer_start start_per_cpu_kthreads start_cpu_kthread kthread_create_on_cpu kthread_fn -> start_single_kthread cpu_online_mask kthread_create -> kthread_fn move_to_next_cpu cpumask_next cpumask_equal(current_mask, current->cpus_ptr))
save_cpumask get_sample trace_hwlat_sample __buffer_unlock_commit
init_events trace_hwlat_event trace_hwlat_funcs trace_hwlat_print trace_seq_printf cpumask_and(current_mask, cpu_online_mask, tr->tracing_cpumask); cpu_online_mask &__cpu_online_mask sched_setaffinity(kthread->pid, current_mask); init_tracefs thread_mode_fops hwlat_mode_write hwlat_tracer_stop-> hwlat_data.thread_mode hwlat_tracer_start-> read_sum_exec_runtime sum_exec_runtime
? cpuacct.usage
__update_load_avg_cfs_rq ___update_load_avg
cgroup cgroup_root cgroup_subsys
cgroup_base_files "cpu.stat" cpu_stat_show cgroup_base_stat_cputime_show usage_usec < sum_exec_runtime
cpus_mask, __do_set_cpus_allowed family
proc_pid_status task_cpus_allowed cpus_mask set_cpus_allowed_ptr !! affinity_context __set_cpus_allowed_ptr __set_cpus_allowed_ptr_locked user_cpus_ptr task_cpu task_thread_info cpu __do_set_cpus_allowed -> >set_cpus_allowed -> set_cpus_allowed_common -> SCA_MIGRATE_... cpus_ptr cpumask_copy(&p->cpus_mask, ctx->new_mask); cpumask_any_and_distribute update_rq_clock clock_update_flags rq->clock += delta sched_clock_cpu -> sched_clock_stable sched_clock
update_rq_clock_task !(ctx->flags & (SCA_USER | SCA_MIGRATE_ENABLE | SCA_MIGRATE_DISABLE)) && affine_move_task move_queued_task
do_set_cpus_allowed affinity_context .user_mask = NULL __do_set_cpus_allowed dequeue_task ->
->set_cpus_allowed set_cpus_allowed_common cpumask_copy(&p->cpus_mask, new_mask); p->cpus_ptr = new_mask p->nr_cpus_allowed = cpumask_weight(ctx->new_mask); set_cpus_allowed_dl
kthread_bind_mask TASK_UNINTERRUPTIBLE __kthread_bind_mask wait_task_inactive raw_spin_lock_irqsave do_set_cpus_allowed -> PF_NO_SETAFFINITY do_taskset sched_setaffinity affinity_context find_process_by_pid find_task_by_vpid cpumask_copy(user_mask, in_mask) security_task_setscheduler task_setscheduler __sched_setaffinity alloc_cpumask_var alloc_cpumask_var_node kmalloc_node cpuset_cpus_allowed(p, cpus_allowed); spin_lock_irqsave(&callback_lock, flags); cpumask_copy cpu_possible_mask __cpu_possible_mask cpumask_and(new_mask, in_mask, cpus_allowed); __set_cpus_allowed_ptr ->
cpuset_cgrp_subsys dfl_files cpuset_write_resmask is_cpuset_online cpus_read_lock(); mutex_lock(&cpuset_mutex); update_cpumask -> FILE_EXCLUSIVE_CPULIST update_exclusive_cpumask cpumask_copy update_cpumasks_hier update_parent_effective_cpumask w2 update_isolation_cpumasks <- update_unbound_workqueue_cpumask housekeeping_exlude_isolcpus w1
migrate_live_tasks set_mempolicy migrate_enable set_cpus_allowed_common ->
tracing_read_pipe print_trace_line print_trace_fmt trace_print_context "comm-pid [cpu]" trace_print_lat_context lat_print_generic
date -d @1676347894.530839161 "+%y-%m-%d %T" date -d @410645.867062 "+%y-%m-%d %T" date -d @1676347894.530839161 "+%s"
echo raw > trace_options
export KUBECONFIG=~/kubeconfig export HTTPS_PROXY=socks5://localhost:1337 kubectl get pods -A
ssh root@192.168.13.14 root@192.168.13.14: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
BasePage._save
Request.submit
module_spi_driver spi_register_driver driver_register
spi_drv_probe sdrv->probe
CONFIG_MSM_SMD
cat /sys/kernel/debug/smd/int_stats
echo 0x37 > /sys/module/smd/parameters/debug_mask printf "0x%x\n" $(cat /sys/module/smd/parameters/debug_mask)
msm_smd_probe smd_get_intr_config private_intr_config smd_modem_irq_handler ++interrupt_stats[SMD_MODEM].smd_in_count handle_smd_irq ~ notify_modem_smd ++interrupt_stats[SMD_MODEM].smd_out_count; do_smd_probe handle_smd_irq_closing_list
HP G8 192.168.1.247 00:1f.3 Multimedia audio controller: Intel Corporation Tiger Lake-LP Smart Sound Technology Audio Controller (rev 20)
HP G4 192.168.1.139 00:1f.3 Audio device: Intel Corporation Sunrise Point-LP HD Audio (rev 21)
old
FP problem Linux swi-mdm9x28-wp 3.18.140 #1 PREEMPT Mon Aug 22 09:34:39 UTC 2022 armv7l GNU/Linux
killall klogd; /etc/init.d/syslog star
#!/bin/sh
pw=13 echo $pw > /sys/class/gpio/export; echo high > /sys/class/gpio/gpio$pw/direction
pw=41 echo $pw > /sys/class/gpio/export; echo high > /sys/class/gpio/gpio$pw/direction
lcdcs=1008 echo $lcdcs > /sys/class/gpio/v2/export echo high > /sys/class/gpio/v2/gpio$lcdcs/direction
export LD_LIBRARY_PATH=$PWD
./NBDevicesConsoleSampleC -sysfspath /sys/class/gpio/v2 -spi /dev/spidev1.1 16 1005 58
cs=8 # 58 echo $cs > /sys/class/gpio/export echo high > /sys/class/gpio/gpio$cs/direction echo $cs > /sys/class/gpio/unexport
Reset 2P (shut down) - the power cable must be disconnected!!!: write to address 0x6A, register 9, value 64: /bq25890/w 9 64
lua5.3
Add_A_to_C: inc C inc D dec A jnz Add_A_to_C // D is original A Move_D_to_A: inc A dec D jnz Move_D_to_A dec B jnz Add_A_to_C // B-1 times stop
USE_MDFILE_AS_MAINPAGE = DEVELOPERS.md
\xb4\x14\x0e\xb7\x1d\x0c\x88\xc5 + 3a78f4e48f3e30cb = \x7f\x24\x30\x38\xf9\xf8\xf0\xff
__isoc99_scanf@plt fexecve
sed -n 's/\(.*\):\(.*\):.*:.*warning: unused parameter .\(\w*\).*/ex -c "\2\/{\/|exec \\\"normal jwi(void)\3;\\n\\"|x" \1/p' cmake.log > a
Traceback (most recent call last): File "/usr/lib/python3/dist-packages/xdot/ui/window.py", line 171, in update current_mtime = os.stat(self.openfilename).st_mtime FileNotFoundError: [Errno 2] No such file or directory: 'colors.dot'
gpiod_to_irq nmap -T4 -A -v 192.168.0.100 # -Taggressive Aggressive sudo nmap polite
sys_timerfd_settime do_timerfd_settime
sys_timerfd_create anon_inode_getfd ▻ __anon_inode_getfd __anon_inode_getfile alloc_file_pseudo alloc_file ▻ anon_inode_getfile -> alloc_file ▻ if isalarm alarm_init hrtimer_init alarmtimer_fired timerfd_alarmproc ! isalarm hrtimer_init
pm_suspend enter_state suspend_devices_and_enter suspend_enter pm_wakeup_pending 3.18 pm_get_active_wakeup_sources sysdev_suspend
input_dev_suspend input_dev_release_keys
pm_print_active_wakeup_sources
3 sys_epoll_ctl
ep_remove ep_destroy_wakeup_source wakeup_source_unregister
do_epoll_ctl ep_insert ep_create_wakeup_source wakeup_source_register wakeup_source_create wakeup_source_sysfs_add wakeup_source_add wakeup_sources alarmtimer_init wakeup_source_register ->
nvme_alloc_ns device_add_disk nvme_loop_init_module nvme_loop_transport - host fabrics nvme_loop_create_ctrl nvme_loop_create_io_queues nvme_loop_mq_ops nvme_loop_init_request nvme_loop_init_iod nvme_loop_queue_rq
nvme_init_ctrl nvme_loop_ops - target nvme_loop_add_port nvme_loop_ports nvme_loop_queue_response nvmet_req
ssh ilan@ilan make -C /home/ilan/Leaf/swi-linux-src register_chrdev_region __register_chrdev_region alloc_chrdev_region major == 0 __register_chrdev_region find_dynamic_major mousedev_init mousedev_create cdev_init cdev_device_add cdev_add -> device_add
git-authors
corbet@lwn.net linux-doc@vger.kernel.org kernelnewbies@kernelnewbies.org
NETLINK_AUDIT
fbtft_display
ili9341_spi_driver ili9341_probe ili9341_pipe_funcs mipi_dbi_pipe_update mipi_dbi_fb_dirty MIPI_DCS_WRITE_MEMORY_START
spi_sync_transfer spi_message_init_with_transfers spi_message_init spi_message_add_tail ->
msm_spi_request_cs_gpio cs_gpios
spi_register_controller
pm_generic_runtime_suspend runtime_suspend
msm_spi_request_irq msm_spi_qup_irq devm_request_irq msm_spi_error_irq msm_spi_output_irq
spi_pump_messages spi_finalize_current_message transfer_one_message ? spi_transfer_one_message <- transfer_one_message transfers spi_set_cs true - sets run time chipselect, active high msm_spi_set_cs - active low SPI_IO_C_FORCE_CS SPI_CS_HIGH? transfer_one spi_set_cs false
spi_write spi_device spi_message_init spi_message_add_tail transfer_list list_add_tail __list_add spi_sync __spi_sync spi_async_locked __spi_validate __spi_async transfer spi_queued_transfer pump_messages ... spi_pump_messages -> gpio_free wait_for_completion
process_one_work fb_deferred_io_work ili9341_update fb_info creen_base screen_size fb_fix_screeninfo smem_start smem_len fb_deferred_io_cleanup cancel_delayed_work_sync fb_deferred_io_page a readcommand8 sendCommand spiWrite spiRead Adafruit_ILI9341::begin fillScreen fillRect ... setAddrWindow ILI9341_RAMWR writePixel drawPixel startWrite SPI_CS_LOW setAddrWindow(x, y, 1, 1); SPI_WRITE16(color); mipi_dbi_spi_init mipi_dbi_typec3_command mipi_dbi_typec3_command_read virtio_gpu_primary_helper_funcs virtio_gpu_primary_plane_update drm_atomic_helper_damage_merged drm_atomic_helper_damage_iter_init drm_helper_get_plane_damage_clips drm_plane_get_damage_clips drm_rect_equals mipi_dsi_dcs_set_page_address mipi_dsi_dcs_set_column_address MIPI_DCS_SET_COLUMN_ADDRESS git log -p --pretty=$'format:%ae\n%ce' -n100 --no-merges --since="1 year ago" -- Documentation/ ":(exclude)Documentation/devicetree/bindings" d=https://www.kernel.org/doc/html/latest/trace/index.html wget -q -O- https://www.kernel.org/doc/html/latest/core-api/index.html \ sed 's@<h.>\([^<]\+\).*headerlink.*href="\(#[^"]\+\).*@{{The Linux Kernel/doc|\1|core-api\2}}@p;d'
wget -q -O- https://www.kernel.org/doc/html/latest/core-api/ | sed 's@.*toctree-l\(3\).*href="\([^"]\+\)">\(.[^<]\+\)<.*@*\1 {{The Linux Kernel/doc|\3|core-api/\2}}@p;d' device_link_add device_register napi netif_napi_add napi_complete napi_complete_done e1000e_poll napi_complete_done gro_normal_list netif_receive_skb_list_internal __netif_receive_skb_list __netif_receive_skb_list_core __netif_receive_skb_core e1000_clean skb_queue_tail __skb_queue_tail skb_dequeue __skb_dequeue dev_cpu_dead netif_rx_ni netif_rx_internal enqueue_to_backlog MCE do_machine_check arch/x86/include/asm/mce.h mce_panic kill_me_maybe memory_failure memory_failure_init memory_failure
{ air w=wlp2s0 rfkill unblock 1 sudo airmon-ng start $w sudo airodump-ng ${w}mon
sudo airodump-ng ${w}mon -d 14:AE:DB:C7:18:52 -c 9 -w izylho sudo airodump-ng ${w}mon --bssid 00:11:6B:26:90:AC --channel 11 --write tkip
sudo airmon-ng stop ${w}mon
sudo aircrack-ng izylho-01.cap sudo aircrack-ng tkip-01.cap
sudo aireplay-ng -a $target_ap -c $clent --deauth 1
}
{ kernel/sched/rt.c enqueue_task_rt update_stats_wait_start_rt __update_stats_wait_start
set_next_task_rt update_stats_wait_end_rt __update_stats_wait_end
rt-tests cyclictest timerthread timer_settime clock_nanosleep sys_clock_nanosleep hrtimer_nanosleep -> oslat doit frc hwlatdetect
start_kthread osnoise_main run_osnoise s.noise = time_to_us(sum_noise); s.runtime = time_to_us(total); s.max_sample = time_to_us(max_noise); s.un_osnoise trace_osnoise_sample(&s); __trace_osnoise_sample notify_new_max_latency
rtla
trace_instance_init create_instance libtracefs tracefs_instance_create timerlat_aa_register_events tracefs_event_enable tracefs_instance
hwnoise_main osnoise_top_main osnoise_top_apply_config if (params->mode == MODE_HWNOISE) { retval = osnoise_set_irq_disable(tool->context, 1); osnoise_main osnoise_top_main osnoise_hist_main osnoise_set_tracing_thresh tracing_thresh osnoise_init_trace_tool tracefs_event_enable
osnoise_hist_update_multiple update_max(&data->hist[cpu].max_sample, &duration);
osnoise_top_handler max_noise update_max(&cpu_data->max_noise, &val); update_max(&cpu_data->max_sample, &val);
hook_irq_events register_trace_irq_handler_entry ->trace_irqentry_callback osnoise_trace_irq_entry -> register_trace_irq_handler_exit ->trace_irqexit_callback osnoise_tracer_start osnoise_workload_start osnoise_hook_events hook_irq_events osnoise_arch_register register_trace_irq_work_entry(trace_intel_irq_entry, NULL); "irq_work" register_trace_irq_work_exit(trace_intel_irq_exit, "irq_work"); trace_intel_irq_exit ->
register_trace_local_timer_entry register_trace_local_timer_exit
hook_softirq_events trace_softirq_exit_callback duration = get_int_safe_duration(osn_var, &osn_var->softirq.delta_start); trace_softirq_noise "duration" unhook_softirq_events trace_softirq_exit_callback ^ osnoise_unhook_events unhook_softirq_events ^
sched_rt_period_timer Scheduling classes SCHED_FIFO SCHED_RR
sched/rt.c implements SCHED_FIFO and SCHED_RR sched_rt_runtime_exceeded sched_rt_rq_dequeue
chrt/cyclictest sched_setscheduler sched_param _sched_setscheduler __sched_setscheduler
ktime CONFIG_DEBUG_TIMEKEEPING timekeeping_check_update timekeeping_get_delta read_seqcount_begin tk_clock_read read_seqcount_retry do_read_seqcount_retry clocksource_delta ktime_set ktime_get &tk_core.timekeeper timekeeping_get_ns timekeeping_get_delta timekeeping_delta_to_ns ktime_add_ns
ktime_get_real getnstimeofday timekeeper clocksource
hrtimers hrtimers_init HRTIMER_SOFTIRQ open_softirq hrtimer_run_softirq hrtimer_init debug_init debug_hrtimer_init hrtimer_debug_descr debug_object_init __hrtimer_init hrtimer_clockid_to_base timerqueue_init RB_CLEAR_NODE debug_activate trace_hrtimer_start
hrtimer_start hrtimer_start_range_ns ->
hrtimer_restart hrtimer_start_expires hrtimer_start_range_ns lock_hrtimer_base(timer, &flags); raw_spin_lock_irqsave(&base->cpu_base->lock, *flags); __hrtimer_start_range_ns HRTIMER_MODE_PINNED switch_hrtimer_base get_target_base timers_migration_enabled get_nohz_timer_target bpftrace -e 'kretprobe:get_nohz_timer_target {print(retval);}' idle_cpu
housekeeping_cpu(cpu, HK_TYPE_TIMER)) housekeeping_any_cpu -> enqueue_hrtimer timerqueue_add rb_add_cached hrtimer_reprogram hrtimer_bases __hrtimer_reprogram tick_program_event clock_event_device clockevents_program_event clockevents_program_min_delta unlock_hrtimer_base(timer, &flags); raw_spin_unlock_irqrestore(&timer->base->cpu_base->lock, *flags);
tick_sched_timer tick_sched_handle update_process_times run_local_timers hrtimer_run_queues -> hrtimer_switch_to_hres -> tick_setup_sched_timer x raise_timer_softirq CONFIG_HIGH_RES_TIMERS __hrtimer_peek_ahead_timers hrtimer_interrupt -> hrtimer_switch_to_hres
timer_list ->
/proc/timer_list timer_list_show print_cpu tick_get_tick_sched hrtimer_bases hrtimer_cpu_base hrtimer -> hrtimer_clock_base hrtimer_clock_base get_time -> hrtimer print_base print_active_timers timerqueue_getnext timerqueue_iterate_next print_timer
CONFIG_PREEMPT_VOLUNTARY might_sleep 300+ uses + might_resched _cond_resched _cond_resched should_resched __cond_resched __schedule ▻ CONFIG_PREEMPT resume_kernel retint_kernel preempt_schedule_irq __schedule ▻
preempt_check_resched preempt_schedule __schedule ▻
request_any_context_irq request_threaded_irq ▻
CONFIG_GENERIC_HARDIRQS request_irq ldt request_threaded_irq irq_desc affinity_hint irq_to_desc sparse_irqs < irq_insert_desc irq_chip_pm_get irq_get_pm_device pm_runtime_resume_and_get
irq_settings_can_request
__setup_irq register_irq_proc ▻
thread_fn
setup_irq __setup_irq desc->action = irqaction irq_desc irq_activate irq_domain_activate_irq __irq_domain_activate_irq irq_pm_install_action register_irq_proc -> register_handler_proc -> __enable_irq irq_startup irq_data_get_affinity_mask __irq_startup irq_state_set_started IRQD_IRQ_STARTED IRQF_NOBALANCING irq_settings_set_no_balancing IRQD_NO_BALANCING _IRQ_NO_BALANCING IRQF_PERCPU > IRQD_PER_CPU
irq_thread_fn ret_from_fork > kthread > irq_thread > irq_thread_fn PREEMPT_RT... PREEMPT_RT_BASE PREEMPT_RTB PREEMPT_RT_FULL spinlock_t rt_mutex raw_spinlock_t
interrupt_init_v2_hw devm_request_irq devm_request_threaded_irq devm_irq_release devres_alloc request_threaded_irq ▻
smp_apic_timer_interrupt local_apic_timer_interrupt
rt: cpupri_init check_preempt_equal_prio cpupri_find cpupri_find_fitness __cpupri_find }
{ Storage (file - disks)
libc: aiocbp aio_read aio_write io_setup io_submit aio_cancel aio_error aio_init aio_return aio_suspend aio_fsync io_cancel io_destroy io_getevents lio_listio(3) sys_io_submit iocb aio_data kioctx lookup_ioctx kill_ioctx io_submit_one aio_write aio_read kiocb aio_setup_rw import_iovec ▻ aio_rw_done aio_complete_rw aio_complete aio_poll
Virtual Filesystem (VFS) Inode Caches and Interaction with Dcache Filesystem Registration/Unregistration File Descriptor Management File Structure Management Superblock and Mountpoint Management Example Virtual Filesystem: pipefs Example Disk Filesystem: BFS Execution Domains and Binary Formats
-
The Virtual Filesystem The Role of the Virtual Filesystem (VFS) VFS Data Structures Filesystem Types Filesystem Mounting Pathname Lookup Implementations of VFS System Calls File Locking
sys_link sys_linkat lookup_create sys_unlink sys_unlinkat sys_waitpid sys_wait4 sys_close close_fd filp_close file filp->f_op->flush dnotify_flush fput delayed_fput __fput file_free file_free_rcu
sys_creat do_sys_open
sys_open ksys_open do_sys_open do_sys_openat2 struct filename file_open_name build_open_flags fd = get_unused_fd_flags __alloc_fd fsnotify_open fsnotify_parent fsnotify get_unused_fd do_filp_open set_nameidata path_openat struct file get_empty_filp __get_empty_filp do_last vfs_open x open_namei 150 LOC path_lookup_open ▻ may_open < do_open < path_openat < do_filp_open vfs_permission permission security_inode_permission security_ops->inode_permission nameidata_to_filp __dentry_open fops_get fd_install fd struct file __fd_install files_struct files_fdtable rcu_dereference((files)->fdt) rcu_assign_pointer getname do_getname strncpy_from_user filp_open do_filp_open nameidata open_namei open_namei_create vfs_create security_inode_create create ext3_create (ext3_dir_inode_operations) fsnotify_create fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); path_lookup do_path_lookup ▻ __emul_lookup_dentry path_walk link_path_walk dentry_open vfs_open do_dentry_open fops_get open ext4_file_open
linux/fs
sys_read vfs ksys_read struct fd fdget_pos __fdget_pos fd ▻ file __fdget __fget_light struct files_struct current->files __fcheck_files struct fdtable __fget struct file f_path path_get struct path struct vfsmount struct dentry dentry d_seq d_name d_dname d_path simple_dname prepend file->f_inode->i_ino fdget .. fdput ▻ fget_light vfs_read fsnotify_access FS_ACCESS fsnotify ▻ security_file_permission (file, MAY_READ) security_ops->file_permission file->f_op->read mtd_read > do_sync_read ./fs/read_write.c filp->f_op->aio_read ▻ generic_file_aio_read aio_read ./mm/filemap.c generic_file_direct_IO direct_IO do_generic_file_read do_generic_mapping_read readpage xx __generic_file_aio_read do_generic_mapping_read __lock_page __wait_on_bit_lock sync_page block_sync_page blk_backing_dev_unplug generic_unplug_device -- fire a request queue __generic_unplug_device do_ide_request ./drivers/ide/ide-io.c <- somewere ide_do_request <- ide_intr start_request ide_do_rw_disk ▻ elv_queue_empty
fdput fput sys_write fdget atomic_long_inc_not_zero vfs_write __vfs_write file->f_op->write new_sync_write filp->f_op->write_iter generic_file_write_iter __generic_file_write_iter x do_sync_write filp->f_op->aio_write fsnotify_modify FS_MODIFY fsnotify ▻
fput_light wchar
http://www.tldp.org/LDP/tlk/fs/filesystem.html#tth_sEc9.1
lfs ▻
== lfs
vfs ▻
init_smb_fs .. smb_file_operations smb_fs_type init_cifs .. cifs_file_ops cifs_fs_type cifs_get_sb cifs_read_super cifs_mount cifs_find_tcp_session
sys_nfsservctl fs/nfsctl.c do_open do_kern_mount("nfsd", 0, "nfsd", NULL); nfs_fhget nfs_file_operations nfs_flock
vfs_iter_read include/linux/fs.h iov_iter include/linux/uio.h
ext3_file_operations file_operations ext3_ioctl FITRIM: ext3_trim_fs ext3_trim_all_free sb_issue_discard blkdev_issue_discard REQ_DISCARD ??? sd_init_command REQ_DISCARD sd_setup_discard_cmnd UNMAP ext3_commit_super sync_dirty_buffer
ext3_new_blocks ext3_journal_dirty_metadata __ext3_journal_dirty_metadata journal_dirty_metadata iput iput_final evict ext3_evict_inode
sync_filesystem ext2_sync_fs ext2_sync_super ext3_sync_fs journal_start_commit ext4_sync_fs ext4_sb_bread
ext2_file_operations ext2_fsync generic_file_fsync __generic_file_fsync sync_mapping_buffers private_list fsync_buffers_list WRITE_SYNC write_dirty_buffer submit_bh .. end_buffer_write_sync ext3_sync_file filemap_write_and_wait_range ▻ ext4_sync_file
ext4_da_write_end generic_write_end block_write_end __block_commit_write
SyS_fanotify_mark > fanotify_mark_add_to_mask > fsnotify_set_inode_mark_mask_locked > igrab > _raw_spin_lock __raw_spin_lock
do_raw_spin_lock debug_spin_lock_before SPIN_BUG_ON spin_bug owner_cpu spin_dump __spin_lock_debug debug_spin_lock_after
__mark_inode_dirty ext3_dirty_inode ext3_mark_inode_dirty ext3_reserve_inode_write __ext3_journal_get_write_access journal_get_write_access journal_add_journal_head do_get_write_access journal_put_journal_head
new 3.17 usbip vhci_hcd_init usbip_host_init usbip_core_init F_SEAL_SHRINK memfd_create
sparse cgcc make C=1 all current: pinctrl
kmalloc -> devm_kcalloc devm_kmalloc_array devm_kmalloc devm_kzalloc __GFP_ZERO devm_kmalloc alloc_dr ... __kmalloc_track_caller kmalloc_slab slab_alloc -> devres ... devm_kzalloc_release devres_add add_dr devres_log list_add_tail devres_head devm_ioremap_resource (was devm_request_and_ioremap) __devm_ioremap_resource devm_request_mem_region __devm_request_region devres_alloc devm_region_release __release_region free_resource kfree __request_region devres_add ~ devm_release_mem_region __devm_release_region __release_region devres_destroy devm_region_release __devm_ioremap devres_alloc_node devm_ioremap_release ioremap ? devm_ioremap __devm_ioremap -> devres_alloc alloc_dr -> ioremap ▻ devres_add ~ devm_iounmap devm_ioremap_release iounmap ▻ devres_destroy devres_remove devres_free iounmap ▻
EXT4_GET_MB_CACHE ((ext4_sb_info *)inode->i_sb->s_fs_info)->s_mb_cache
ext4_put_super ext4_xattr_destroy_cache mb_cache_destroy
ext4_fill_super s_mb_cache = ext4_xattr_create_cache mb_cache_create ext4_xattr_destroy_cache ▻
ext4_file_operations file_operations ext4_file_open, do_sync_read ▻ x ext4_file_write < aio_write ext4_file_read_iter ext4_file_write_iter generic_file_aio_write x __generic_file_aio_write x generic_file_buffered_write __generic_file_write_iter generic_perform_write write_begin iov_iter_copy_from_user_atomic __copy_from_user_inatomic generic_write_sync vfs_fsync_range
ext3_writeback_aops B ext3_readpage mpage_readpage do_mpage_readpage
The Ext2 and Ext3 Filesystems General Characteristics of Ext2 Ext2 Disk Data Structures Ext2 Memory Data Structures Creating the Ext2 Filesystem Ext2 Methods Managing Ext2 Disk Space The Ext3 Filesystem
init_ext4_fs init_ext3_fs register_filesystem ext3_fs_type x ext4_get_sb get_sb x ext3_get_sb get_sb x get_sb_bdev sget super_block
ext3_file_operations do_sync_read ▻
genhd_device_init subsystem_register block_subsys
linux/blkdev.h
buffer_head
block_device gendisk * bd_disk
block_device_operations
unregister_blkdev
blk_mq_requeue_request __blk_mq_requeue_request ... requeue
include/linux/genhd.h partition gendisk capability disk_capability_show gendisk ( brd_alloc flags |= GENHD_FL_SUPPRESS_PARTITION_INFO sd, ide, md: GENHD_FL_EXT_DEVT )
hd_struct block_device_operations-> request_queue request_fn_proc struct request bio io_vec
alloc_disk <- floppy_init, ide_cd_probe, alloc_disk_node kmalloc_node put_disk add_disk blk_register_region kobj_map bdev_map register_disk fs/partitions/check.c blkdev_get __blkdev_get rescan_partitions check_partition blk_register_queue class_register sd_disk_class ? blk_put_request
blk_init_queue blk_init_queue_node
struct request end_request blkdev_dequeue_request elv_dequeue_request list_del_init
do_fsync .. schedule sys_fdatasync do_fsync vfs_fsync vfs_fsync_range ovl_fsync fs/overlayfs/file.c vfs_fsync_range xfs_file_fsync trace_xfs_file_fsync xfs_ilock xfs_iunlock
file_write_and_wait_range __filemap_fdatawait_range __filemap_fdatawrite_range -> do_writepages --> writepages xfs_vm_writepages iomap_writepages write_cache_pages iomap_submit_ioend write_cache_pages trace_wbc_writepage iomap_writepage_map submit_bio generic_make_request do_make_request make_request_fn blk_mq_make_request rq_qos_throttle __rq_qos_throttle throttle wbt_wait @ throttle @ wbt_rqos_ops writeback throttling. __wbt_wait &wbt_inflight_cb rq_qos_wait prepare_to_wait_exclusive_return __wake_up_common rq_qos_wake_function rq_qos_wake_function ->wbt_inflight_cb rq_wait_inc_below get_limit limit = rwb->wb_background; limit = rwb->wb_normal; data->got_token = true; !data.got_token io_schedule ->
io_schedule schedule __schedule trace_event_raw_event_sched_switch
wbt_enable_default wbt_init wbt_rqos_ops wbt_done wb_timer_fn scale_up calc_wb_limits wb_normal wb_background scale_down calc_wb_limits ^ wbt_queue_depth_changed wbt_update_limits calc_wb_limits ^ "wbt_lat_usec" queue_wb_lat_entry queue_wb_lat_store wbt_init ^ wbt_set_min_lat wbt_update_limits ^
do_idle cpuidle_enter cpuidle_enter_state ret_from_intr do_IRQ handle_irq handle_edge_irq handle_irq_event handle_irq_event_percpu __handle_irq_event_percpu nvme_irq nvme_process_cq nvme_handle_cqe nvme_end_request ?? end_io=abort_endio? blk_mq_free_request rq_qos_done __rq_qos_done wbt_done __wbt_done wbt_rqw_done wake_up_all __wake_up __wake_up_common_lock __wake_up_common rq_qos_wake_function wake_up_process try_to_wake_up ttwu_do_wakeup trace_sched_wakeup
sys_fsync ▻ fs/sync.c sys_sync ▻ sys_fdatasync do_fsync sys_fsync ▻ lkm2 do_fsync ▻ sys_sync_file_range filemap_fdatawrite_range __filemap_fdatawrite_range ->
address_space address_space_operations nfs_file_aops def_blk_aops blkdev_readpage B block_read_full_page blkdev_writepage B block_write_full_page __block_write_full_page hfs_file_operations file_fsync fs/sync.c write_inode_now fs/fs-writeback.c mapping_cap_writeback_dirty writeback_single_inode ▻
sysrq_handle_sync orderly_poweroff emergency_sync do_sync_work sync_filesystems;
sys_sync lkm2 wakeup_flusher_threads bdi_writeback_all bdi_alloc_queue_work bdi_work_init bdi_queue_work wake_up_process(wb->task); x --> bdi_start_fn sync_filesystems __sync_filesystem writeout_quota_sb quota_sync writeback_inodes_sb bdi_start_writeback bdi_alloc_queue_work ▻ sync_quota_sb quota_sync sync_inodes_sb bdi_sync_writeback wait_sb_inodes sb->s_op->sync_fs return __sync_blockdev(sb->s_bdev, wait);
x do_sync x wakeup_pdflush x pdflush x __pdflush x sync_inodes x __sync_inodes sync_blockdev filemap_fdatawrite sync_supers write_super
sys_fsync lkm2 do_fsync vfs_fsync lkm2 vfs_fsync_range filemap_write_and_wait_range __filemap_fdatawrite_range -> filemap_fdatawait_range __filemap_fdatawait_range wait_on_page_writeback fop->fsync ext3_sync_file ext4_sync_file nfs_file_fsync nfs_do_fsync nfs_wb_all nfs_write_mapping __nfs_write_mapping nfs_writepages write_cache_pages nfs_writepages_callback nfs_do_writepage nfs_page_async_flush ... nfs_fsync_dir bdi_register_dev bdi_register kthread_run(bdi_forker_thread () bdi_writeback_thread ( old bdi_start_fn ) wb_do_writeback ▻
wb_do_writeback wb_writeback writeback_inodes_wb requeue_io writeback_single_inode do_writepages lkm2 address_space_operations mapping->a_ops->writepages ext4_da_writepages write_cache_pages __mpage_da_writepage generic_writepages write_cache_pages ... __writepage mapping->a_ops->writepage ext4_writepage write_inode inode->i_sb->s_op->write_inode ext3_write_inode ext4_write_inode inode_sync_complete inode_wait_for_writeback wb_check_old_data_flush wb_writeback
func trace point blk_mq_submit_bio block_bio_queue blk_mq_submit_bio block_getrq blk_account_io_start block_io_start blk_add_rq_to_plug block_plug blk_mq_commit_rq block_unplug nvme_setup_cmd blk_mq_start_request block_rq_issue nvme_handle_cqe nvme_sq nvme_complete_rq nvme_complete_rq blk_complete_request block_rq_complete blk_account_io_done block_io_done mark_buffer_dirty block_dirty_buffer
submit_bio_noacct_nocheck block_bio_queue trace_block_bio_queue __submit_bio blk_mq_submit_bio block_getrq trace_block_getrq blk_account_io_start -> block_io_start blk_mq_start_request trace_block_rq_issue io_start_time_ns = ktime_get_ns
tracepoint:block: block_bio_queue submit_bio_noacct_nocheck __submit_bio block_getrq blk_mq_submit_bio block_io_start NEW blk_account_io_start block_rq_issue blk_mq_start_request ... block_rq_complete < blk_complete_request blk_update_request block_io_done blk_account_io_done block_bio_complete
blk_stat_add io_start_time_ns blk_throtl_stat_add
# echo 'hist:keys=delta.buckets=100,stack.stacktrace:sort=delta' > events/synthetic/block_lat/trigger # cat events/synthetic/block_lat/hist
__blk_mq_update_nr_hw_queues blk_mq_debugfs_register_hctxs
block/blk-mq-debugfs.c
blk_mq_debugfs_register_hctxs blk_mq_debugfs_register_hctx blk_mq_debugfs_hctx_attrs hctx_state_show hctx_state_name
mq_map blk_mq_queue_map set, msi_desc used by blk_mq_map_queues blk_mq_hw_queue_to_node blk_mq_pci_map_queues blk_mq_virtio_map_queues get_vq_affinity blk_mq_map_swqueue blk_mq_alloc_tag_set blk_mq_free_tag_set blk_mq_map_queue_type blk_mq_clear_mq_map ublk_ctrl_get_queue_affinity hisi_sas_queue_command map_queues_v2_hw virtio_fs virtio_fs_ktype_release virtio_fs_map_queues virtio_fs_setup_vqs blk_mq_queue_map
cpuhp_invoke_callback -> hlist_for_each trace_cpuhp_multi_enter blk_mq_hctx_notify_offline CPUHP_AP_BLK_MQ_ONLINE blk_mq_hw_ctx !blk_mq_hctx_has_online_cpu Ming Lei for_each_online_cpu blk_mq_map_queue_type hctx_table set_bit(BLK_MQ_S_INACTIVE, &hctx->state); blk_mq_hctx_has_requests blk_mq_all_tag_iter __blk_mq_all_tag_iter bt_tags_for_each bt_tags_iter_data sbitmap_for_each_set __sbitmap_for_each_set blk_mq_has_request iter_data->has_rq = true; data.has_rq; blk_mq_hctx_notify_dead CPUHP_BLK_MQ_DEAD blk_mq_cpu_mapped_to_hctx blk_mq_map_queue_type cpuhp_dead list_splice_init blk_mq_hctx_clear_pending sbitmap_clear_bit(&hctx->ctx_map, bit); blk_mq_run_hw_queue blk_queue_quiesced QUEUE_FLAG_QUIESCED blk_mq_hctx_has_pending blk_mq_sched_has_work has_work __blk_mq_run_dispatch_ops blk_mq_delay_run_hw_queue kblockd_mod_delayed_work_on mod_delayed_work_on __queue_delayed_work -> blk_mq_run_dispatch_ops blk_mq_sched_dispatch_requests __blk_mq_sched_dispatch_requests blk_mq_do_dispatch_ctx bio_cpu_dead CPUHP_BIO_DEAD -> bio_alloc_cache_prune bio_alloc_irq_cache_splice __bio_alloc_cache_prune bio_free blk_softirq_cpu_dead CPUHP_BLOCK_SOFTIRQ_DEAD blk_complete_reqs(&per_cpu(blk_cpu_done, cpu)); nvme_pci_complete_rq (nvme_mq_ops)
blk_mq_init cpuhp_setup_state_nocalls cpuhp_setup_state_multi __cpuhp_setup_state -> CPUHP_BLOCK_SOFTIRQ_DEAD &blk_softirq_cpu_dead CPUHP_AP_BLK_MQ_ONLINE &blk_mq_hctx_notify_offline CPUHP_BLK_MQ_DEAD &blk_mq_hctx_notify_dead blk_mq_hctx_notify_online clear_bit(BLK_MQ_S_INACTIVE, &hctx->state);
__blk_mq_alloc_disk blk_mq_alloc_queue blk_mq_init_allocated_queue blk_mq_realloc_hw_ctxs blk_mq_alloc_and_init_hctx blk_mq_alloc_hctx blk_mq_init_hctx init_hctx -> nvme_init_hctx cpuhp_state_add_instance_nocalls CPUHP_AP_BLK_MQ_ONLINE cpuhp_online CPUHP_BLK_MQ_DEAD cpuhp_dead blk_mq_init_request nvme_pci_init_request
blk_mq_end_request blk_update_request trace_block_rq_complete block_rq_complete bpf_map_lookup_elem __blk_mq_end_request blk_account_io_done trace_block_io_done
blk_mq_sched_insert_requests blk_mq_insert_requests trace_block_rq_insert block_rq_insert
blk_mq_alloc_tag_set mq_map blk_mq_free_tag_set mq_map blk_mq_hw_queue_to_node mq_map usage cpu_to_node
blk_mq_update_nr_hw_queues __blk_mq_update_nr_hw_queues blk_mq_map_swqueue mq_map usage request_queue hctx_idx = set->map[j].mq_map[i] usage __blk_mq_alloc_map_and_rqs hctx_idx blk_mq_alloc_map_and_rqs blk_mq_alloc_rq_map blk_mq_get_hctx_node hctx_idx_to_type blk_mq_hw_queue_to_node -> blk_mq_alloc_rqs blk_mq_free_rq_map Ming Lei: queue_for_each_hw_ctx cpu_is_isolated cpumask_clear_cpu blk_mq_hw_ctx cpumask
map_queues ?
pci_irq_vector(to_pci_dev(nvmeq->dev->dev), nvmeq->cq_vector) IRQF_NOBALANCING desc = irq_to_desc(pci_irq_vector(to_pci_dev(nvmeq->dev->dev), nvmeq->cq_vector)); irq_settings_set_no_balancing(desc); irqd_set(&desc->irq_data, IRQD_NO_BALANCING); queue_request_irq blk_mq_pci_map_queues
really_probe pci_device_probe local_pci_probe nvme_probe blk_mq_tag_set tagset nvme_alloc_io_tag_set blk_mq_alloc_tag_set blk_mq_update_queue_map map_queues nvme_pci_map_queues-> blk_mq_alloc_set_map_and_rqs __blk_mq_alloc_rq_maps nvme_pci_enable->
nvme_probe nvme_mq_ops: .map_queues nvme_pci_map_queues (nvme-pci: allow unmanaged interrupts) map->nr_queues = dev->io_queues[i]; blk_mq_queue_map blk_mq_tag_set offset = queue_irq_offset(dev); (0,1) blk_mq_pci_map_queues Ming Lei blk_mq_queue_map pci_irq_get_affinity msi_desc pci_irq_vector msi_get_virq MSI_DEFAULT_DOMAIN msi_domain_get_virq ..msi_device_data msi_dev_domain msi_desc irq_get_msi_desc -> msi_desc irq_affinity_desc mask &desc->affinity[idx].mask; mq_map set, CPU ID to hardware queue index map. HCTX_TYPE_POLLL: blk_mq_map_queues group_cpus_evenly __group_cpus_evenly get_nodes_in_cpumask cpumask_intersects alloc_nodes_groups mq_map
common_interrupt __common_interrupt handle_edge_irq handle_irq_event __handle_irq_event_percpu action->handler nvme_irq ->
init_scsi drivers/scsi/scsi.c scsi_init_queue kmem_cache_create ▻ mempool_create_slab_pool mempool_create ▻ scsi_init_procfs proc_scsi_operations scsi_init_devinfo proc_scsi_devinfo_read proc_scsi_devinfo_write scsi_init_hosts class_register &shost_class scsi_init_sysctl scsi_table_header = register_sysctl_table(scsi_root_table, 1); scsi_sysfs_register bus_register scsi_bus_type class_register sdev_class scsi_netlink_init netlink_register_notifier(&scsi_netlink_notifier); netlink_kernel_create(NETLINK_SCSITRANSPORT, __netlink_create ▻ scsi_driver drv->bus = &scsi_bus_type bus_type ▻ device_driver #Scsi_Device_Template
#Scsi_Device scsi_device request_queue scsi_cmnd ▻
SCSI Generic (sg) Driver
sd.c scsi_disk Scsi_Disk sd_ioctl blk_ioctl scsi_ioctl ... sg_write SG_DXFER_FROM_DEV sg_common_write init_sd register_blkdev major_names
scsi_register_driver driver_register ▻ sd_template scsi_driver sd_probe sd_probe drivers/scsi/sd.c alloc_disk add_disk ▻ sd_fops sd_open sd_probe_async "Attached SCSI %sdisk" sd_printk sdev_printk ▻ sd_revalidate_disk limits.max_sectors blk_queue_max_hw_sectors max_hw_sectors sd_read_block_characteristics scsi_get_vpd_page queue_flag_set_unlocked QUEUE_FLAG_NONROT
sd.h sd.c scsi.c scsi_ioctl.c scsicam.c scsi_proc.c scsi_error.c scsi_queue.c scsi_lib.c scsi_merge.c scsi_dma.c scsi_scan.c scsi_syms.c constants.h constants.c hosts.h hosts.c scsi_obsolete.h scsi_obsolete.c scsi_debug.h scsi_debug.c scsi_module.c
proc cat /proc/scsi/scsi scsi_proc_info
proc_scsi_gen_write scan_scsis
echo "scsi dump 0" > /proc/scsi/scsi scsi_dump_status
headres
include/scsi/scsi.h _LINUX_SCSI_H INQUIRY READ_CAPACITY include/scsi/scsi_ioctl.h _SCSI_IOCTL_H drivers/scsi/scsi.h _SCSI_H
data
scsi_cmnd Scsi_Cmnd use_sg cmnd request_buffer
scsi_request Scsi_Request scsi_allocate_request scsi_release_request
scsi_ioctl ioctl_internal_command scsi_wait_req scsi_do_req scsi_insert_special_req
? scsi_do_cmd scsi_release_command scsi_queue_next_request scsi_initialize_queue Scsi_Device::request_queue scsi_request_fn
scsi_hostlist
CONFIG_SCSI CONFIG_SCSI_MODULE
SCSI low
/usr/src/linux/drivers/scsi
aic94xx_init aic94xx_pci_driver asd_pci_probe Scsi_Host scsi_host_alloc scsi_add_host
Scsi_Host_Template
Scsi_Host
Scsi_Cmnd::use_sg Scsi_Cmnd::request_buffer
linux/drivers/scsi low
blkdevs blk_dev_struct blk_dev
commands: dd mount fdisk iscsi_tcp_init iscsi_register_transport iscsi_tcp_transport iscsi_tcp_conn_create
rx_data iscsit_do_rx_data
ata_init
scsi_dispatch_cmd atomic_inc(&cmd->device->iorequest_cnt); queuecommand ? ata_scsi_queuecmd ata_scsi_dump_cdb ATA_DEBUG scsi_done trace_scsi_dispatch_cmd_done(cmd); blk_complete_request __blk_complete_request ATA_BASE_SHT ata_scsi_queuecmd __ata_scsi_queuecmd ibata-scsi.c ata_scsi_translate ata_scsi_qc_new
ata_wait_ready ata_link ata_link_online ata_phys_link_online "link is slow to respond, please be patient " ata_link_warn ata_link_printk link->ap->print_id
ata_std_postreset sata_print_link_status ata_phys_link_online if (sata_scr_read(link, SCR_STATUS, &sstatus) == 0 && ata_sstatus_online(sstatus)) (sstatus & 0xf) == 0x3; "SATA link down" sata_scr_read: sata_scr_read(link, SCR_STATUS, &sstatus)) sata_scr_read(link, SCR_CONTROL, &scontrol); ata1: SATA link up 1.5 Gbps (SStatus 113 SControl F310) ata2: SATA link up 3.0 Gbps (SStatus 123 SControl F300)
ata_port_pbar_desc ata_port_desc
scsi_host_alloc shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1; scsi_error_handler host_eh_scheduled host_failed eh_strategy_handler ata_scsi_error scsi_eh_flush_done_q(&ap->eh_done_q); scsi_eh_flush_done_q (++scmd->retries <= scmd->allowed)) scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY); sata_pmp_error_handler .error_handler mv_pmp_error_handler sata_pmp_error_handler sata_pmp_eh_recover ata_eh_recover ▻ scsi_proc_hostdir_add proc_mkdir
sata_mv
Stack: < submit_bio < submit_bh < block_read_full_page < __do_page_cache_readahead < page_cache_sync_readahead < generic_file_aio_read < do_sync_read < vfs_read < sys_read < ret_fast_syscall
Stack: < ata_sff_port_init < ata_port_alloc < ata_host_alloc < ata_host_alloc_pinfo < mv_platform_probe < platform_drv_probe < driver_probe_device < __driver_attach < bus_for_each_dev < bus_add_driver < driver_register < mv_init < do_one_initcall < kernel_init < kernel_thread_exit
Stack: < ata_sff_tf_load < ata_sff_qc_issue < mv_qc_issue < ata_qc_issue < ata_scsi_translate < scsi_dispatch_cmd < scsi_request_fn < __blk_run_queue < blk_run_queue < scsi_run_queue < scsi_next_command < scsi_io_completion < blk_done_softirq
Stack: < ata_sff_exec_command < ata_sff_qc_issue < mv_qc_issue < ata_qc_issue < ata_scsi_translate < scsi_dispatch_cmd < scsi_request_fn < __blk_run_queue < elv_insert < __make_request < generic_make_request < submit_bio < write_page < md_update_sb < md_allow_write < md_ioctl < __blkdev_driver_ioctl < blkdev_ioctl < vfs_ioctl < do_vfs_ioctl < sys_ioctl < ret_fast_syscall Stack: < ata_bmdma_qc_issue < mv_qc_issue < ata_qc_issue < ata_scsi_translate < scsi_dispatch_cmd < scsi_request_fn < __blk_run_queue < __blk_put_request < blk_end_bidi_request < scsi_io_completion < blk_done_softirq < __do_softirq < irq_exit < asm_do_IRQ < __irq_svc < scsi_dispatch_cmd < scsi_request_fn < __blk_run_queue < elv_insert < __make_request < generic_make_request < submit_bio < write_page < md_update_sb < md_allow_write < md_ioctl < __blkdev_driver_ioctl < blkdev_ioctl < vfs_ioctl < do_vfs_ioctl < sys_ioctl < ret_fast_syscall
Stack: < ata_sff_tf_read < ata_sff_qc_fill_rtf < fill_result_tf < ata_qc_complete < ata_hsm_qc_complete < ata_sff_hsm_move < ata_sff_pio_task < worker_thread < kthread < kernel_thread_exit
Stack: < ata_sff_data_xfer < ata_pio_sector < ata_pio_sectors < ata_sff_hsm_move < ata_sff_pio_task < worker_thread < kthread < kernel_thread_exit
ata_sff_exec_command: ata2: cmd 0xEA
ata_sff_hsm_move ata_hsm_qc_complete ata_qc_complete
mv_init mv_platform_driver
sas_ata_init_host_and_port ata_sas_port_alloc ata_port_alloc ata_link_init ata_dev_init ata_sff_port_init INIT_DELAYED_WORK(&ap->sff_pio_task, ata_sff_pio_task);
mv_platform_probe ata_host_alloc_pinfo ata_host_alloc ata_port_alloc ▻ &mv_port_info .port_ops = &mv5_ops &ata_sff_port_ops .sff_data_xfer = ata_sff_data_xfer, ata_host_activate mv_init_host mv_port_init CONFIG_ATA_SFF port->data_addr = shd_base + (sizeof(u32) * ATA_REG_DATA); port->error_addr = port->feature_addr = shd_base + (sizeof(u32) * ATA_REG_ERR); reset_hc mv_soc_reset_hc mv_soc_reset_hc_port mv_reset_channel ▻ enable_leds SATALED find /sys/ | grep "ctera:green:disk.*/brightness"
echo 0 > /sys/devices/platform/leds-gpio/leds/ctera:green:disk1/brightness echo 1 > /sys/devices/platform/leds-gpio/leds/ctera:green:disk4/brightness
mv_soc_enable_leds mv_soc_led_blink_enable SOC_LED_CTRL = 0x2c, mv_soc_led_blink_disable
ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, IRQF_SHARED, &mv6_sht); mv_interrupt ▻ ata_host_start ata_finalize_port_ops port_start mv_port_start dma_pool_alloc devm_request_irq -> ata_host_register ata_scsi_add_hosts scsi_add_host scsi_add_host_with_dma scsi_setup_command_freelist device_add scsi_sysfs_add_host scsi_proc_host_add ata_port_is_dummy ata_dummy_port_ops
ata_port_desc
ahci_pci_driver ahci_init_one &ata_dummy_port_ops
mv6_sht ATA_NCQ_SHT ATA_BASE_SHT ▻ piix_init piix_init_one
ata_port struct Scsi_Host *scsi_host; /* our co-allocated scsi host */ shost_gendev shost_dev ata_port_operations ata_link ata_eh_context eh_context ata_eh_info eh_info serror ata_port ata_link* sff_pio_task_link
mv_interrupt main_irq_cause = readl(hpriv->main_irq_cause_addr); mv_host_intr ata_host mv_port_intr ata_port mv_err_intr ata_port sata_scr_read(&ap->link, SCR_ERROR, &serr); struct ata_eh_info *ehi ehi->serror |= serr; SERR_10B_8B_ERR 1 << 19 SERR_DISPARITY 1 << 20
edma_err_cause == 20 if (edma_err_cause & EDMA_ERR_SERR)
ata_std_error_handler ata_port_operations ops->hardreset mv_hardreset mv_reset_channel phy_errata mv6_phy_errata mv_soc_65n_phy_errata PHY_MODE3 = 0x310, sata_link_hardreset sata_link_resume ops->softreset mv_softreset ata_sff_softreset ata_do_eh ata_eh_autopsy ata_eh_link_autopsy drivers/ata/libata-eh.c rc = sata_scr_read(link, SCR_ERROR, &serror); scr_read mv_scr_read mv_scr_offset mv_ap_base readl ehc->i.serror |= serror; ata_eh_analyze_serror ata_eh_analyze_ncq_error qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; ata_eh_done ata_eh_clear_action
ata_eh_report ata_eh_report < sata_pmp_error_handler < ata_scsi_error < scsi_error_handler < kthread < kernel_thread_exit ata_eh_link_report drivers/ata/libata-eh.c ata_eh_context ata_eh_info serror "exception Emask 0x100 SAct 0x1 SErr 0x400000 action 0x6 frozen" ATA_PFLAG_FROZEN ▻ "frozen" - ignore ata_get_cmd_descript drivers/ata/libata-eh.c "failed command: WRITE FPDMA QUEUED" FPDMA = First Party DMA ata_err_string err_mask AC_ERR_ATA_BUS = (1 << 4), /* ATA bus error */ AC_ERR_ATA_BUS Emask 0x410 (ATA bus error) "SError:" SERR_DISPARITY Dispar SErr 0x4000000 ▻ SERR_DEV_XCHG DevExch "device exchanged" SErr - ehc->i.serror ata_queued_cmd *qc qc->err_mask & AC_ERR_NCQ ? " <F>" : "" ncq, NCQ = SATA Native Command Queueing ata_eh_recover ata_eh_reset reset = hardreset; "hard resetting link" ata_eh_about_to_do ata_eh_clear_action ata_do_reset ata_for_each_dev ata_eh_finish ata_eh_qc_retry scmd->retries--; __ata_eh_qc_complete scsi_eh_finish_cmd(scmd, &ap->eh_done_q); list_move_tail(&scmd->eh_entry, done_q); ata_eh_qc_complete scmd->retries = scmd->allowed; __ata_eh_qc_complete
ata_scsi_error ./drivers/ata/libata-eh.c:787 --ap->eh_tries) "EH pending after %d tries, giving up\n",
ATA_EH_MAX_TRIES ATA_LINK_RESUME_TRIES ? ATA_DEBUG
ata_qc_issue ata_sg_setup DPRINTK
__irq_svc asm_do_IRQ handle_level_irq handle_IRQ_event mv_ial_lib_int_handler mvSataInterruptServiceRoutine libata-core.c e eeesync_port_probe ata_bus_probe ata_dev_configure ata_device dev->horkage |= ata_dev_blacklisted(dev); ata_do_link_spd_horkage if (dev->horkage & ATA_HORKAGE_1_5_GBPS) target = 1; target_limit = (1 << target) - 1; ata_port_schedule_eh sata_link_hardreset sata_set_spd __sata_set_spd_needed limit = link->sata_spd_limit; sata_spd_limit sata_scr_write(link, SCR_CONTROL, scontrol) mv_scr_write sata_mv.c <- scr_write writelfl
mv_ial_init driver_template.module
echo /dev/sd{a,b}|xargs -n1 smartctl -l selftest
CONFIG_SATA_MV ./drivers/ata/sata_mv.c mv_platform_driver-> mv_platform_probe ▻
piix_init PCI IDE/ISA Xcelerator (Intel IC) piix_pci_driver PIIX PCI IDE ISA Xcelerator, aka Intel 82371 ICH I/O Controller Hub
fs/dcache.c directory-entry cache (dcache) sys_getcwd current->fs_struct->pwd __d_path usb_stor_init usb_storage_driver storage_wrobe scsi_host_alloc(&usb_stor_host_template, sizeof(*us)); usb_stor_host_template
fs/buffer.c:
touch_buffer mark_buffer_dirty
sys_dup fs/fcntl.c fget lkm2 fd > file task_struct ▻ files_struct ▻ fdtable ▻ file (f_dentry) current : task_struct files : files_struct fdt : fdtable fd : file file file_operations *f_op fcheck_files files_fdtable rcu_dereference atomic_long_inc_not_zero get_unused_fd alloc_fd files_fdtable find_next_zero_bit expand_files files_fdtable expand_fdtable files_fdtable copy_fdtable fd_install ▻ fput atomic_long_dec_and_test sys_dup2 sys_dup3 expand_files files_fdtable rcu_assign_pointer FD_SET(newfd, fdt->open_fds); sys_fcntl fs/fcntl.c fget ▻ security_file_fcntl security_ops->file_fcntl do_fcntl F_DUPFD: alloc_fd get_file(filp); fd_install(err, filp); set_close_on_exec setfl fcntl_getlk fcntl_dirnotify fput sys_sysfs fs/filesystems.c file_systems : file_system_type lkm2 see /proc/filesystems fs_index fs_name fs_maxindex get_filesystem_list file_systems
sys_ioprio_get fs/ioprio.c get_task_ioprio ioprio_best sys_ioprio_set fs/ioprio.c set_task_ioprio task->io_context->ioprio sys_flock fs/locks.c lkm2 flock_make_lock filp->f_op->flock nfs_flock fuse_file_flock flock_lock_file_wait flock_lock_file locks_insert_block locks_insert_lock wait_event_interruptible ▻ fs/namei.c sys_link ▻ sys_mkdir lkm2 sys_mkdirat vfs_mkdir dir->i_op->mkdir nfs_mkdir ext3_mkdir sys_mknod ▻ sys_rename sys_renameat vfs_rename vfs_rename_dir old_dir->i_op->rename sys_rmdir do_rmdir vfs_rmdir sys_symlink sys_symlinkat vfs_symlink sys_unlink ▻ fs/namespace.c sys_mount copy_mount_string strndup_user memdup_user copy_from_user copy_mount_options exact_copy_from_user access_ok __range_ok do_mount do_new_mount x do_kern_mount file_system_type get_fs_type find_filesystem request_module vfs_kern_mount alloc_vfsmnt type->get_sb mount_fs do_new_mount_fc vfs_create_mount do_add_mount graft_tree attach_recursive_mnt attach_mnt __attach_mnt
.... squashfs_mount mount_bdev blkdev_get_by_path set_bdev_super sget fill_super ▻ squashfs_fill_super squashfs_fill_super squashfs_read_table squashfs_read_data sb->s_fs_info sb_getblk sb->s_bdev __getblk_gfp __find_get_block lookup_bh_lru bh_lrus.bhs __getblk_slow __find_get_block ▻ grow_buffers alloc_page ▻ ll_rw_block buffer_head submit_bh submit_bh_wbc submit_bio generic_make_request SQUASHFS_MAGIC sys_pivot_root detach_mnt attach_mnt sys_umount do_umount umount_tree
fs/notify/inotify/inotify_user.c sys_inotify_init lkm2 sys_inotify_init1 inotify_fops inotify_read inotify_event get_one_event fsnotify_peek_notify_event copy_event_to_user inotify_new_group alloc_file ▻ sys_inotify_add_watch inotify_find_inode user_path_at pathname > path do_path_lookup inode_permission inotify_update_watch inotify_update_existing_watch inotify_new_watch sys_inotify_rm_watch fs/open.c sys_access sys_faccessat user_path_at ▻ inode_permission sys_fchdir file = fget(fd); set_fs_pwd ▻ sys_chdir lkm2 ksys_chdir set_fs_pwd current task_struct ▻fs_struct->pwd inode_permission lkm2 security x user_path_dir user_path_at ▻ sys_fchmod notify_change ▻ sys_chmod lkm2 security sys_fchmodat mnt_want_write notify_change lkm2 inode_change_ok inode->i_op->setattr (inode_operations) ext3_setattr ext4_setattr vfs_dq_transfer security_inode_setattr inode_setattr lkm2 selinux_inode_setattr inode->i_uid simple_setattr setattr_copy fsnotify_change fsnotify_parent __fsnotify_parent fsnotify fsnotify lkm2 send_to_group fsnotify_create_event group->ops->handle_event fsnotify_ops inotify_handle_event fsnotify_add_notify_event dnotify_handle_event fanotify_handle_event lkm2 fsnotify_add_notify_event audit_watch_handle_event audit_tree_handle_even sys_lchown chown_common ▻ sys_fchownat chown_common ▻ sys_fchown chown_common ▻ sys_chown chown_common struct inode *inode = path->dentry->d_inode;
security_path_chown security_ops->path_chown notify_change ▻ sys_chroot lkm2 security_path_chroot set_fs_root fs->root
sys_close ▻ sys_creat ▻ sys_fallocate do_fallocate inode->i_op->fallocate sys_truncate do_sys_truncate do_truncate ▻ sys_ftruncate do_sys_ftruncate do_truncate notify_change sys_openat do_sys_open ▻ sys_open ▻ sys_fstatfs vfs_statfs_native ▻ sys_statfs user_path pathname > path user_path_at vfs_statfs_native vfs_statfs dentry ▻ kstatfs dentry->d_sb->s_op->statfs sys_vhangup tty_vhangup_self tty_vhangup do_tty_hangup
dentry path inode fs/pipe.c sys_pipe lkm2 sys_pipe2 do_pipe_flags create_write_pipe alloc_file ▻ create_read_pipe alloc_file ▻ audit_fd_pair ▻ fd_install ▻ fs/quota/quota.c sys_quotactl do_quotactl fs/readdir.c sys_getdents64 vfs_readdir file->f_op->readdir sys_getdents vfs_readdir ▻ file->f_op->readdir nfs_readdir ext3_readdir ext4_readdir ext4_rec_len_from_disk filldir fs/read_write.c sys_lseek vfs_llseek default_llseek lock_kernel unlock_kernel file->f_op->llseek sys_pread64 vfs_read ▻ sys_preadv vfs_readv ▻ sys_pwrite64 sys_pwritev sys_read ▻ sys_readv iovec lkm2 vfs_readv x do_readv_writev import_iovec rw_copy_check_uvector iov_iter_init do_iter_read iov_iter_count do_iter_readv_writev init_sync_kiocb file->f_op->read_iter generic_file_read_iter mapping->a_ops->direct_IO x do_sync_readv_writev file->f_op->aio_read file->f_op->aio_write do_loop_readv_writev iov_iter_iovec iov_iter_advance iterate_and_advance iterate_iovec iov_length iov_len iov_iter_truncate i->count = count
sys_copy_file_range fs/read_write.c vfs_copy_file_range do_copy_file_range generic_copy_file_range MAX_RW_COUNT do_splice_direct -> sys_sendfile lkm2 fs/read_write.c sys_sendfile64 do_sendfile do_splice_direct lkm2 fs/splice.c splice_direct_to_actor do_splice_to ▻ splice_read sock_splice_read ▻ ./net/socket.c direct_splice_actor do_splice_from splice_write generic_splice_sendpage fs/splice.c actor = pipe_to_sendpage sendpage sock_sendpage ▻ ./net/socket.c splice_from_pipe ▻ out->f_op->splice_write default_file_splice_write actor = write_pipe_buf kernel_write vfs_write ▻ splice_from_pipe __splice_from_pipe
sys_write ▻ sys_writev iovec vfs_writev iov_iter import_iovec do_iter_write do_iter_readv_writev call_read_iter read_iter call_write_iter write_iter do_loop_readv_writev fs/select.c DEFAULT_POLLMASK POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM sys_poll lkm2 do_sys_poll poll_initwait qproc = __pollwait init_poll_funcptr do_poll do_pollfd file->f_op->poll poll_schedule_timeout
xxx poll_wait p->qproc __pollwait init_waitqueue_func_entry add_wait_queue __add_wait_queue sys_ppoll poll_select_set_timeout do_sys_poll ▻ sys_pselect6 do_pselect core_sys_select ▻ sys_select ▻ lkm2
fs/signalfd.c sys_signalfd sys_signalfd4 anon_inode_getfd ▻ fs/splice.c sys_splice lkm2 do_splice splice_pipe_to_pipe do_splice_to splice_read sock_splice_read ▻ sys_tee lkm2 do_tee ipipe_prep pipe_wait_readable pipe_wait_writable opipe_prep link_pipe pipe_buffer wakeup_pipe_readers sys_vmsplice vmsplice_to_pipe splice_to_pipe vmsplice_to_user __splice_from_pipe fs/stat.c sys_newfstatat vfs_fstatat user_path_at ▻ vfs_getattr lkm2 inode->i_op->getattr nfs_getattr generic_fillattr inode ▻ kstat cp_new_stat kstat ▻ stat sys_newfstat lkm2 vfs_fstat fget vfs_getattr cp_new_stat sys_newlstat vfs_lstat vfs_fstatat ▻ cp_new_stat sys_newstat vfs_stat vfs_fstatat ▻ cp_new_stat sys_readlink sys_readlinkat fs/super.c sys_ustat vfs_statfs fs/timerfd.c sys_timerfd_create anon_inode_getfd ▻ sys_timerfd_gettime sys_timerfd_settime -> fs/utimes.c sys_utimes sys_futimesat ▻ sys_futimesat do_utimes utimes_common sys_utime do_utimes sys_utimensat do_utimes fs/xattr.c sys_setxattr user_path ▻ setxattr vfs_setxattr xattr_permission __vfs_setxattr_noperm inode->i_op->setxattr sys_listxattr listxattr vfs_listxattr sys_getxattr getxattr vfs_getxattr sys_removexattr removexattr sys_fgetxattr audit_inode __audit_inode sys_flistxattr sys_fremovexattr sys_fsetxattr sys_lgetxattr sys_lsetxattr user_lpath user_path_at ▻ mnt_want_write sys_llistxattr sys_lremovexattr blkdev_ioctl fio fio_options engines psync fio_psyncio_queue pread pwrite do_io_u_sync
bio_endio trace_block_bio_complete block_bio_complete
__trace_req_completion bpf_ktime_get_ns
./biosnoop.bt kprobe:blk_account_io_start kprobe:blk_account_io_done
blk_execute_rq_nowait blk_account_io_start trace_block_io_start
bioset_init cpuhp_state_add_instance_nocalls(CPUHP_BIO_DEAD, &bs->cpuhp_dead); __cpuhp_state_add_instance __cpuhp_state_add_instance_cpuslocked hlist_add_head
init_bio cpuhp_setup_state_multi CPUHP_BIO_DEAD &bio_cpu_dead
./bcc/tools/xfsslower.py events.perf_submit xfsslower "trace_fsync_entry" attach_kprobe bpf_attach_kprobe bpf_attach_probe bpf_try_perf_event_open_with_probe perf_event_open
fsslower bpf_program__attach_kprobe
strace --follow-forks --attach="$(pidof etcd)" -Tt --signal='!SIGURG,SIGPIPE' --status=successful -e trace=\!futex |& grep -v --line-buffered -F '0.0'
del_timer_sync try_to_del_timer_sync
=> ftrace_ops_list_func => ftrace_call => ttwu_do_wakeup => try_to_wake_up => hrtimer_wakeup => __hrtimer_run_queues => hrtimer_interrupt => smp_apic_timer_interrupt => apic_timer_interrupt => __x86_indirect_thunk_rax => __rq_qos_track => blk_mq_make_request => generic_make_request => submit_bio => iomap_submit_ioend.isra.38 => xfs_vm_writepages => do_writepages => __filemap_fdatawrite_range => file_write_and_wait_range => xfs_file_fsync => do_fsync => __x64_sys_fdatasync => do_syscall_64 => entry_SYSCALL_64_after_hwframe
=> trace_event_raw_event_sched_switch => __schedule => schedule => schedule_timeout => io_schedule_timeout => balance_dirty_pages => balance_dirty_pages_ratelimited => iomap_write_actor => iomap_apply => iomap_file_buffered_write => xfs_file_buffered_aio_write => new_sync_write => vfs_write => ksys_pwrite64 => do_syscall_64 => entry_SYSCALL_64_after_hwframe
blkcg_iolatency_ops blkcg_iolatency_throttle __blkcg_iolatency_throttle rq_qos_wait ^ }
mtk_star_probe net_device devm_alloc_etherdev devm_platform_ioremap_resource devm_regmap_init_mmio devm_clk_bulk_get devm_register_netdev
inet_init ▻ copy_process <- copy_namespaces create_new_namespaces copy_net_ns mutex_lock_killable(&net_mutex);
/proc/net
bt_init bt_sysfs_init sock_register(&bt_sock_family_ops); bt_sock_family_ops bt_sock_create, hci_sock_init proto_register(&hci_sk_proto, 0); bt_sock_register(BTPROTO_HCI, &hci_sock_family_ops);
ipw2100_pci_init_one ipw2100_open
usbnet_probe usbnet_netdev_ops usbpn_open usb_set_interface rx_submit netif_wake_queue usbnet_start_xmit register_netdev usbnet_ethtool_ops
kevent rx_submit __netdev_alloc_page usb_submit_urb rx_complete defer_bh rx_submit ▻
cdc_init cdc_driver usbnet_probe
ip_rt_do_proc_init rt_cache_seq_fops rt_cache_seq_show
rt_cpu_seq_show
udp4_proc_init udp4_net_ops net_dev_init dev_proc_ops dev_seq_fops dev_seq_ops sg_proc_seq_show_dev dev_proc_init
sys_socketcall <- system_calls sys_socket sock_create create __sock_create 100 LOC socket sock_alloc new_inode security_socket_create RCU Read-Copy Update pf = rcu_dereference(net_families[family]); pf->create ? inet_create inetsw sk_alloc sock_init_data ? .init = tcp_v4_init_sock, (tcp_prot) ipv4_specific inet_connection_sock_af_ops af = address family .queue_xmit = ip_queue_xmit, ... sock_map_fd sys_connect connect sock->ops->connect inet_stream_connect inet_dgram_connect sys_setsockopt sock_setsockopt sock->ops->setsockopt sys_getsockopt sock_getsockopt sys_sendmsg ▻ sock_sendmsg sys_recvmsg ▻ sock_recvmsg ▻
sys_accept sys_accept4 sys_bind sys_listen inet_listen inet_stream_ops inet_csk_listen_start sk->sk_prot->get_port
sockfd_lookup sock_map_fd
socket_file_ops file_operations sock_ioctl sock_aio_read ▻ ?? af_unix_init sock_register unix_family_ops sock_sendpage sendpage kernel_sendpage proto sendpage inet_sendpage tcp_sendpage ▻ udp_sendpage ip_append_page
generic_splice_sendpage, .splice_write sock_splice_read lkm2 .splice_read splice_read tcp_splice_read, lkm2 __tcp_splice_read tcp_read_sock tcp_recv_skb sock_poll poll
netdev_alloc_skb __netdev_alloc_skb __alloc_skb skb_reserve dev_alloc_skb __dev_alloc_skb alloc_skb __alloc_skb kmem_cache_alloc_node kmem_cache_alloc ▻ skb_reserve netif_rx
input output samples sk_buff
=== eth_data net_device linux/netdevice.h alloc_netdev kzalloc hard_start_xmit dev_base // All devices alloc_etherdev linux/etherdevice.h net/ethernet/eth.c alloc_etherdev_mq alloc_netdev_mq lkm2 ether_setup dev->hard_header = eth_header; alloc_netdev register_netdev lkm2 dev_alloc_name register_netdevice dev->init netdev_register_sysfs class_device_add ethhdr h_dest h_source h_proto ksoftirqd dm9000_init platform_driver_register(&dm9000_driver); dm9000_probe dm9000_poll_work
netpoll_poll ndo_poll_controller dm9000_poll_controller dm9000_interrupt ▻
dm9000_timeout netif_stop_queue set_bit(__LINK_STATE_XOFF, &dev->state); dm9000_reset dm9000_init_dm9000 netif_wake_queue __netif_schedule dm9000_stop del_timer netif_stop_queue netif_carrier_off dm9000_shutdown dm9000_open dm9000_reset dm9000_init_dm9000 dm9000_hash_table init_timer mii_check_media netif_start_queue clear_bit(__LINK_STATE_XOFF, &dev->state); dev_queue_xmit hard_start_xmit dm9000_start_xmit netif_stop_queue
dev_watchdog netif_queue_stopped dm9000_timeout
dm9000_interrupt dm9000_rx dev_alloc_skb netif_rx input_pkt_queue __skb_queue_tail process_backlog netif_receive_skb
dm9000_timer mii_check_media netif_carrier_ok mii_link_ok mdio_read netif_carrier_on netif_carrier_off
== eth_output output dev_queue_xmit ▻ hard_start_xmit
== eth_input input intrerrupt (old) netif_rx cpu_raise_softirq NET_RX_SOFTIRQ net_rx_action .... netif_receive_skb ?? __netif_receive_skb ip_rcv ▻ tcp socket_input == eth_samples samples pci_driver e100_driver e100_probe net_device *netdev = alloc_etherdev e100_open e100_close e100_xmit_frame e100_get_stats e100_set_multicast_list e100_set_mac_address e100_change_mtu e100_do_ioctl e100_ethtool_ops e100_tx_timeout e100_poll e100_netpoll
e1000 e1000_init_module e1000_exit_module e1000_driver e1000_probe e1000_netdev_ops e1000_open
netdev hard_start_xmit .ndo_start_xmit e1000_xmit_frame sk_buff lkm2 e1000_tso skb->data
e1000_tx_queue writel e1000_up e1000_intr lkm2 e1000_clean_rx_irq (2.4-18-3) // Send received data up the network stack skb_put e1000_rx_checksum netif_rx net/core/dev.c ... e1000_receive_skb netif_receive_skb ▻
e1000_poll (2.4-20) rx_ring e1000_process_intr netif_receive_skb ▻
e100_found1 sis900_pci_driver
ieee80211_init
ieee80211_alloc_hw mac80211_config_ops ieee80211_add_iface, ieee80211_if_add alloc_netdev_mq ▻ ieee80211_if_setup, ether_setup ieee80211_dataif_ops ieee80211_open, drv_add_interface ieee80211_register_hw ieee80211_if_add
x eepro100_init_module eepro100_driver eepro100_init_one speedo_found1 speedo_open speedo_interrupt speedo_rx speedo_tx_buffer_gc
ethtool_ops speedo_get_link get_link mii_link_ok mdio_read BMSR_LSTATUS iowrite32 dev_ethtool ETHTOOL_GLINK ethtool_get_link if (!dev->ethtool_ops->get_link) ethtool_op_get_link netif_carrier_ok __LINK_STATE_NOCARRIER
netif_carrier_on lkm2 netif_carrier_off
bond_check_dev_link netif_carrier_ok if_mii BMSR_LSTATUS slave_dev->ethtool_ops->get_link(slave_dev);
net\ipv4\icmp.c
fib (Forwarding Information Base)
net\ipv4\ls net\ipv4\af_inet.c include\net
tcp4_proc_init register_pernet_subsys(&tcp4_net_ops); tcp4_net_ops tcp4_seq_show
inet_family_ops net_proto_family inet_create ▻ inet_init proto_register proto_list tcp_prot ▻ udp_prot ip4_datagram_connect udp_sendmsg sock_tx_timestamp ip_append_data __skb_queue_tail(&sk->sk_write_queue, skb); ip_route_output_flow ? ip_cmsg_send udp_push_pending_frames ip_push_pending_frames ip_local_out dst_output skb->dst->output ? ip_output ip_rt_put udp_recvmsg __skb_recv_datagram sock_rcvtimeo skb_peek ? ip_cmsg_recv wait_for_packet ? dst_input ? ip_local_deliver ▻ raw_prot ip4_datagram_connect, sock_register inet_family_ops net_families icmp_protocol udp_protocol .handler = udp_rcv, __udp4_lib_rcv udp_queue_rcv_skb tcp_protocol tcp_v4_rcv igmp_protocol inetsw_array inet_register_protosw inetsw
arp_init ip_init tcp_v4_init(&inet_family_ops); if (register_pernet_subsys(&tcp_sk_ops)) inet_csk_ctl_sock_create sock_create_kern tcp_socket tcp_init udplite4_register icmp_init #if defined(CONFIG_IP_MROUTE) ip_mr_init(); #endif dev_add_pack(&ip_packet_type); packet_type ip_packet_type .type = __constant_htons(ETH_P_IP), .func = ip_rcv, .gso_send_check = inet_gso_send_check, .gso_segment = inet_gso_segment,
include\linux\net.h, BSD SYS_SOCKET - syscalls list socket socket_state state; unsigned long flags; const struct proto_ops *ops; struct fasync_struct *fasync_list; struct file *file; struct sock *sk; wait_queue_head_t wait; short type; proto_ops net_proto_family net_proto sock (8) TCP/IP
net\ipv4\arp.c
include\linux\netdevice.h net_device
include\linux\inetdevice.h in_device net\ipv4\devinet.c drivers/net
-
Networking Main Networking Data Structures System Calls Related to Networking Sending Packets to the Network Card Receiving Packets from the Network Card
Documentation\networking include\net net net\ipv4
eth
ifconfig ... up dev_ioctl dev_ifsioc SIOCSIFFLAGS: dev_change_flags __dev_change_flags __dev_open ops->ndo_open __dev_close __dev_close_many ops->ndo_stop ieee80211_stop ▻ zd1201_net_stop lbs_eth_stop airo_close netif_stop_queue ▻ dev->flags &= ~IFF_UP; rtmsg_ifinfo __dev_notify_flags call_netdevice_notifiers(NETDEV_DOWN, dev); raw_notifier_call_chain __raw_notifier_call_chain notifier_call_chain notifier_call CB ieee80211_stop ieee80211_do_stop .... ieee80211_stop_device drv_stop ieee80211_ops:stop ath9k_stop ath9k_htc_stop htc_stop ath9k_htc_hif::stop iwlagn_mac_stop iwl_down __iwl_down iwl_clear_driver_stations iwl3945_mac_stop zd_op_stop
..... ieee80211_mgd_assoc ieee80211_add_work ieee80211_assoc_done ieee80211_assoc_success ieee80211_set_associated
ieee80211_reconfig case NL80211_IFTYPE_STATION: changed |= BSS_CHANGED_ASSOC; mutex_lock(&sdata->u.mgd.mtx); ieee80211_bss_info_change_notify(sdata, changed);
iwlagn_mac_start ieee80211_ops::start __iwl_up iwl_prepare_card_hw iwlagn_hw_nic_init iwl_nic_start
netdevice->flags
IFF_UP
IFF_RUNNING
include/linux/ip.h _LINUX_IP_H iphdr
ip_queue_xmit # sk_buff (net/ipv4/ip_output.c) ip_route_output ▻ rt = (struct rtable *)__sk_dst_check(sk, 0); NF_HOOK rt->u.dst.dev nf_hook_slow # skb net_device okfn = ip_queue_xmit2 nf_queue status = queue_handler[pf].outfn(skb, info, queue_handler[pf].data);
??? ip_queue_xmit2 # skb, net/ipv4/ip_output.c skb->dst->output(skb) ip_output ? # sk_buff ip_finish_output ip_fragment ip_finish_output2 dst = skb->dst; dst->hh; hh->hh_output(skb); (hh_cache hardware header) ? dev_queue_xmit (net/core/dev.c) ...qdisc_restart dev->hard_start_xmit dev_queue_xmit_nit -> eth_output dst->neighbour->output(skb); neigh_resolve_output dst_entry *dst = skb->dst; neighbour *neigh = dst->neighbour dev->hard_header neigh->ha eth_header # Create the Ethernet MAC header neigh->ops->queue_xmit(skb); # ha = hardware address, mac! -> eth_output
link_rtnetlink_table rtnetlink_links ? neigh_add neigh_update - sets neigh->ha
net/ipv4/ip_input.c ip_rcv <- eth eth_input ip_rcv_finish ip_route_input lkm2 skb->dst->input ip_local_deliver NF_HOOK NF_HOOK_THRESH nf_hook_thresh nf_hook_slow ▻
ret = ipprot->handler ? udp_rcv ? tcp_v4_rcv (tcp_protocol , net/ipv4/tcp_ipv4.c) tcp_v4_do_rcv tcp_rcv_established tcp_rcv_state_process ip_local_deliver_finish dst_input
eth destination selection - sk_buff.ethernet source interface selection - ip_route_output_slow include/net/route.h rt_key rtable ip_route_connect # rtable dst src ip_route_output # rtable daddr saddr ip_route_output_key (35 lines) # rtable rt_key ip_route_output_slow (300 lines) { # nh = next hop # fib = forward information base main vars rt_key key; dst src fib_result res; fib_rule rtable *rth; net_device *dev_out specific cases: ip_dev_find dev_get_by_index inet_select_addr
# searching route in routing table
#if !CONFIG_TUX_LOOPBACK_PHYSICAL if (fib_lookup(&key, &res)) tb_lookup #else if (main_table->tb_lookup(main_table, &key, &res)) fn_hash_lookup? #endif
# get device to route
make_route: rth = dst_alloc(&ipv4_dst_ops); rt_set_nexthop(rth, &res, 0); err = rt_intern_hash(hash, rth, rp); arp_bind_neighbour done: if (free_res) fib_res_put(&res); }
sock->dst_cache rt_intern_hash
forwarding net/ipv4/ip_forward.c ip_forward ip_send ip_finish_output ▻ arp arp_constructor arp_generic_ops arp_send arp_rcv
# linux TCP/IP API
keys create route connect send output input ops socket INET TCP UDP IP tcp eth-> output send, sendto, sendmsg input recv, recvfrom, recvmsg
#include <sys/types.h>
#include <sys/socket.h>
== inet_layers sys_socketcall socket INET sk_buff sock TCP UDP inet_stream_ops proto_ops IP eth
O_NONBLOCK F_SETFL fcntl
MSG_DONTWAIT ▻ EAGAIN
msghdr msg_iter : iov_iter iov_iter user_msghdr kvec iovec (linux/uio.h) iov_iter iov_offset iterate_and_advance iov_iter_init used in import_iovec import_single_range fuse_ioctl_copy_user
== socket # linux/net.h _LINUX_NET_H net_proto_family create sk sock ▻ proto_ops ops sendpage splice_read socket - BSD socket no connect sock_sendmsg sock_ioctl sock_release sock_create sock_release
== socket_input socket input sock_recvmsg __sock_recvmsg tcp_recvmsg used by kernel_recvmsg sock_read_iter recvfrom iscsit_do_rx_data
== socket_output socket output sock_sendmsg inet_sendmsg tcp_sendmsg ▻ sock_sendpage ▻
... ? tcp_sendpage do_tcp_sendpages skb_fill_page_desc tcp_push
== INET PF_INET inet_family_ops ops inet_stream_ops ▻ inet_dgram_ops ▻ subprotocols inetsw_array .prot = &tcp_prot, .ops = &inet_stream_ops, ... .prot = &udp_prot, .ops = &inet_dgram_ops,
.prot = &raw_prot, .ops = &inet_sockraw_ops, inetsw inet_register_protosw inet_opt (net/sock.h)
== sock # net/sock.h _SOCK_H INET socket, transport layer sock # internal low level socket data, after sock_lock_init tp_pinfo af_tcp tcp_opt proto (after sk_add_backlog) sock_setsockopt net/core/sock.c x-> inet_setsockopt inet_sendmsg (af_inet.c) sock_ioctl ▻ inet_ioctl
== TCP # when dst or route mac are detected? # ref: ha inet_stream_ops proto_ops .connect = inet_stream_connect, .accept = inet_accept, .sendmsg = inet_sendmsg, .recvmsg = sock_common_recvmsg, .sendpage = inet_sendpage, .splice_read = tcp_splice_read, inet_stream_connect connect sk->prot->connect tcp_v4_connect ▻ inet_wait_for_connect tcp_prot proto .init = tcp_v4_init_sock, .connect = tcp_v4_connect, .disconnect = tcp_disconnect, .sendmsg = tcp_sendmsg, .recvmsg = tcp_recvmsg, tcp_sendmsg tcp_close tcp_v4_connect (100 lines connect) # sock sockaddr ip_route_connect ▻ (route) # # sk_buff tcp_connect # sock sk_buff (100 lines) tcp_transmit_skb ▻ tcp_ioctl tcp_sendmsg net/tcp.h _TCP_H tcp_sendmsg (net/ipv4/tcp.c)
== tcp_output output tcp_sendmsg iov from # 220 LOC skb_add_data tcp_copy_to_page - csum_and_copy_from_user - csum_partial_copy_generic ? tcp_push (net/ipv4/tcp.c) __tcp_push_pending_frames tcp_write_xmit (net/ipv4/tcp_output.c) tcp_transmit_skb ▻
...??? .. tcp_send_skb (net/ipv4/tcp_output.c) tcp_write_xmit (net/ipv4/tcp_output.c) tcp_transmit_skb # sock sk_buff, net/ipv4/tcp_output.c) struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); tp->af_specific->send_check(sk, th, skb->len, skb); ???? tcp_v4_send_check # This routine computes an IPv4 TCP checksum err = tp->af_specific->queue_xmit(skb); ?? ip_queue_xmit ▻
ip_build_xmit getfrag ip_queue_xmit
== tcp_input tcp input tcp_recvmsg # 300 lines, linux/net/ipv4/tcp.c tcp_data_wait skb = skb_peek(&sk->receive_queue); cleanup_rbuf tcp_data_wait ! tcp_prequeue_process sk->sk_backlog_rcv tcp_v4_rcv ▻ skb_copy_datagram_iovec ▻ tcp_prequeue_process ▻ cleanup_rbuf
tcp_recv_urg
sock_queue_rcv_skb
receive_queue writers tcp_data_queue tcp_ofo_queue tcp_rcv_established readers tcp_check_urg tcp_recv_skb tcp_recvmsg
raw_prot raw_sendmsg ip_cmsg_send ip_build_xmit
== UDP inet_dgram_ops proto_ops inet_dgram_connect inet_sendmsg udp_prot proto (ops net/ipv4/udp.c, net/udp.h) net/udp.h udp_sendmsg (net/ipv4/udp.c) ▻ low level: eth->
== sk_buff sk_buff skb ( linux/skbuff.h _LINUX_SKBUFF_H) dst (dst_entry) include/net/dst.h neighbour (neighbour) ha hh (hh_cache) hh_output input output alloc_ieee80211 dev->hard_start_xmit = ieee80211_xmit; skb_pull ieee80211_device
zd1201_probe zd1201_net_open drivers/net/wireless/zd1211rw usb_init linux/drivers/net/wireless/zd1211rw/zd_usb.c ? zd_usb_enable_rx alloc_urb rx_urb_complete handle_rx_packet zd_mac_r x_irq tasklet_schedule(&mac->rx_tasklet); do_rx ▻ usb_submit_urb
usb_register driver probe zd_mac_init_hw zd_chip_enable_int zd_usb_enable_int usb_alloc_urb usb_fill_int_urb int_urb_complete usb_submit_urb zd_chip_init_hw register_netdev zd_netdev_alloc alloc_ieee80211softmac zd_netdev_mac ieee80211softmac_priv
do_rx zd_mac_rx ieee80211_rx netif_rx
zd_mac_init tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac); ieee_init ieee->hard_start_xmit = netdev_tx; zd_mac_tx zd_usb_tx usb_alloc_urb usb_buffer_alloc usb_fill_bulk_urb tx_urb_complete ieee80211s_init net/socket.c sys_accept sys_accept4 sockfd_lookup_light sock->ops->accept sock_from_file socket_file_ops sock_alloc_fd sys_bind ▻ sys_connect ▻ sys_getpeername sock->ops->getname sys_getsockname sock->ops->getname sys_getsockopt ▻ sys_listen ▻ sys_recvfrom sock_recvmsg ▻ sys_recvmmsg __sys_recvmmsg sys_recvmsg ▻ sock_recvmsg ▻ sys_sendmsg ▻ sys_sendto sock_sendmsg ▻ sys_setsockopt ▻ sys_shutdown sock->ops->shutdown sys_socket ▻ sys_socketpair sock_create sock1->ops->socketpair sock_alloc_file audit_fd_pair __audit_fd_pair current->audit_context fd_install ▻ netlink_kernel_create sock_create_lite _netlink_create
rtl8139_open rtl8139_interrupt rtl8169_open
iwl iwl3945_hw_ops iwl3945_mac_stop iwl3945_down __iwl3945_down
iwl_bss_info_changed iwl_set_no_assoc priv->assoc_id = 0; priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
mac80211_config_ops ...
MLME Media Access Control (MAC) Sublayer Management Entity nl80211 is the new 802.11 netlink interface public header. SME station management entity Together with cfg80211 it is intended to replace Wireless-Extensions. SSID Service set identifier BSS single access point (AP) together with all associated stations (STAs)
nl80211_disassociate NL80211_CMD_DISASSOCIATE nl80211_ops nl80211_send_deauth nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_DEAUTHENTICATE, gfp);
ieee80211_deauth cfg80211_deauth_request ieee80211_mgd_deauth ieee80211_set_disassoc ieee80211_send_deauth_disassoc ▻
cfg80211_mlme_disassoc __cfg80211_mlme_disassoc disassoc = ieee80211_disassoc ?? ieee80211_disassoc ieee80211_mgd_disassoc ieee80211_set_disassoc ieee80211_hw_config ieee80211_bss_info_change_notify ieee80211_send_deauth_disassoc cfg80211_send_deauth __cfg80211_send_deauth ▻ __cfg80211_send_deauth nl80211_send_deauth ▻ __cfg80211_send_disassoc cfg80211_sme_disassoc __cfg80211_mlme_deauth nl80211_send_disassoc NL80211_CMD_DISASSOCIATE nl80211_send_mlme_event nl80211hdr_put genlmsg_put genlmsg_multicast_netns nlmsg_multicast netlink_broadcast ▻ ieee80211_tx_skb ieee80211_xmit ieee80211_tx __ieee80211_tx drv_tx local->ops->tx
fragmentation __pskb_pull_tail pskb_pull dev_forward_change addrconf_ifdown
udp_gro_receive NETIF_F_GRO_UDP_FWD
veth_skb_is_eligible_for_gro NETIF_F_GRO_UDP_FWD
inet_gro_receive gro_receive geneve_gro_receive
ipip_init ipip_init_net ipip_tunnel_setup
call_function_single_interrupt irq_exit irq_exit_rcu do_softirq net_rx_action napi_poll gro_cell_poll napi_gro_receive netif_receive_skb_internal ? inet_gro_receive netif_receive_skb_core ? ip6_protocol_deliver_rcu br_handle_frame [bridge] br_handle_frame_finish [bridge] br_forward [bridge] ? fdb_find_rcu [bridge] br_forward_finish [bridge] br_dev_queue_push_xmit [bridge] dev_queue_xmit sch_direct_xmit validate_xmit_skb_list validate_xmit_skb skb_gso_segment skb_gso_segment skb_mac_gso_segment inet_gso_segment __udp_gso_segment
skb_segment if ( hsize <= 0 && i >= nfrags && skb_headlen(list_skb) && (skb_headlen(list_skb) == len || sg))
while (pos < offset + len) { if (i >= nfrags) { if (skb_headlen(list_skb)) BUG_ON(!list_skb->head_frag);
}
arch/x86/kernel/process.c sys_execve do_execve fs/exec.c do_execveat_common bprm_execve sched_exec stop_one_cpu wake_up_q
open_exec ▻ mm_alloc kernel/fork.c allocate_mm kmem_cache_alloc ▻ mm_init mm_alloc_pgd pgd_alloc arch/i386/mm/pgtable.c. pgd= Page Global Directory kmem_cache_alloc ▻ SMP sched_exec init_new_context prepare_binprm copy_strings_kernel copy_strings search_binary_handler static struct linux_binfmt *formats; load_binary (linux_binfmt) load_elf_binary ▻ proc_exec_connector
arch/x86/kernel/process.c sys_fork, sys_vfork, sys_clone arch/i386/kernel/process.c kernel_clone x do_fork kernel/fork.c copy_process 400 LOC copy_mm !CLONE_VM ▻ dup_mm CLONE_VM ▻ atomic_inc(&oldmm->mm_users); dup_mm mm_struct allocate_mm mm_init dup_mm_exe_file get_mm_exe_file dup_mmap dup_task_struct task_struct copy_thread arch/i386/kernel/process.c
file file_operations ldt ioctl ldt O_NONBLOCK ldt splice_read mmap ldt generic_file_mmap generic_file_vm_ops ?? filemap_nopage,
kernel/exit.c linux_binfmt register_binfmt search_binary_handler
elf_format load_elf_library load_elf_binary open_exec elf_interpreter path_lookup_open __path_lookup_intent_open do_path_lookup ... link_path_walk __link_path_walk do_lookup elf_map do_mmap do_mmap_pgoff ▻ start_thread load_elf_interp set_brk do_brk
script_format load_script open_exec
init_aout_binfmt load_aout_binary create_aout_tables start_thread sys_munmap do_munmap sys_brk mm/mmap.c find_vma (do_munmap) do_brk_munmap do_brk_flags klm find_vma_links may_expand_vm vm_area_alloc kmem_cache_alloc mm/slub.c __kmem_cache_alloc_lru static slab_alloc static vma_init mas_set_range vma_merge x find_vma_prepare vm_area_struct vma_merge get_user_pages vma_link __vma_link x __anon_vma_link __vma_link_file vma_interval_tree_insert via INTERVAL_TREE_DEFINE, near vma_interval_tree_insert_after vma_start_pgoff vma_last_pgoff
Chapter 10 Judicious Use of Data Types Contents: Use of Standard C Types Assigning an Explicit Size to Data Items Interface-Specific Types Other Portability Issues Linked Lists
linux/fs/devfs
Memory (mmap - ram)
mm/page-writeback.c strictlimit_store BDI_CAP_STRICTLIMIT wb_position_ratio BDI_CAP_STRICTLIMIT
generic_perform_write <- balance_dirty_pages_ratelimited balance_dirty_pages wb_dirty_limits wb_thresh wb_bg_thresh
PFN - Page Frame Number
include/linux/page-flags.h SetPageReserved PG_reserved set_bit ClearPageReserved PG_reserved __clear_bit
alloc_pages_exact get_order __get_free_pages make_alloc_exact
/proc/meminfo proc_meminfo_init meminfo_proc_fops ... meminfo_proc_show si_meminfo ▻ si_swapinfo get_vmalloc_info VMALLOC_TOTAL
high_memory
pgd_index PGDIR_SHIFT 22 pmd_index PMD_SHIFT 21 pte_index PAGE_SHIFT 12
early_param mem early_mem arch/arm/kernel/setup.c parse_memopt arch/x86/kernel/e820.c e820_remove_range
Global Descriptor Table GDT Local Descriptor Table LDT Task State Segment Descriptor TSSD
paging_init ▻
gdt_page get_cpu_gdt_table
mm_struct->pgd
pgd_t PGD pgd Page Global Directory lkm2 pmd_t PMD pmd Page Middle Directory lkm2 pte_t PTE pte Page Table Entry lkm2 http://en.wikipedia.org/wiki/Page_table virt ▻ phys -> page
tlb Translation Lookaside Buffer
86_init lkm2 .memory_setup = default_machine_specific_memory_setup, boot_params.screen_info.ext_mem_k
page include/linux/mm_types.h
kmem_cache kmem_cache_create 200 LOC mempool_s mempool_t mempool_create mempool_create_node kmalloc_node __kmalloc DMA /proc/dma
#include <asm/dma.h>
davinci_request_dma
show_mem ** show_free_areas show_free_areas_core nr_free_pages
== pci_alloc_consistent arch/sh/kernel/pci-dma.c __get_free_pages gfp_mask=0x21? alloc_pages ▻ 2.4 _alloc_pages linux/mm/page_alloc.c contig_page_data __alloc_pages + !!!!!!!!!!!! zone_free_pages pg_data_t # check * page = rmqueue(z, order);# alloc page = list_entry(curr, struct page, list); page = expand(zone, page, index, order, curr_order, area); list_add(&(page)->list, &(area)->free_list); MARK_USED(index, high, area); set_page_count x _alloc_pages linux/mm/numa.c x alloc_pages_pgdat pgdat_list pg_data_t kmalloc or trace_mm_page_alloc mm_page_alloc page_address = (page)->virtual dma_cache_wback_inv __flush_purge_region ocbp
nr_free_pages global_page_state(NR_FREE_PAGES) vm_stat lkm2 NR_VM_ZONE_STAT_ITEMS global zone->vm_stat //for_each_zone pgdat_list free_pages
== mem gup get_user_pages __gup_longterm_locked get_user_pages_fast internal_get_user_pages_fast gup_pgd_range gup_huge_pgd gup_huge_pd __gup_longterm_unlocked __gup_longterm_locked __get_user_pages_locked __get_user_pages get_gate_page get_user_pages_fast_only FOLL_GET | FOLL_FAST_ONLY internal_get_user_pages_fast -> pin_user_pages_fast_only FOLL_PIN | FOLL_FAST_ONLY internal_get_user_pages_fast -> unpin_user_pages_dirty_lock unpin_user_pages unpin_user_page __unpin_devmap_managed_user_page vmtruncate vmtruncate_list zap_page_range zap_pmd_range zap_pte_range tlb_remove_page __free_pte free_page_and_swap_cache do_mmap mmap_region do_munmap find_vma_prev split_vma find_vma detach_vmas_to_be_unmapped unmap_region free_pgtables
remove_vma_list
exit_mmap free_pgtables
chr_dev_init bdi_init(&zero_bdi); devlist zero_fops ▻ /dev/zero mem_fops ▻ /dev/mem kmem_fops mmap_kmem MEM_MAJOR, memory_fops memory_open mem_fops write_mem do_write_mem read_mem copy_to_user mmap_mem remap_pfn_range pmd_alloc remap_pmd_range remap_pte_range pte_alloc_map_lock set_pte_at native_set_pte_at native_set_pte
== page_mem
__get_free_pages ▻
alloc_page gfp ./include/linux/gfp.h alloc_pages gfp_mask order numa_node_id() alloc_pages_node nid gfp order NODE_DATA(nid) (&contig_page_data) __alloc_pages ▻
NUMA alloc_pages_current
__alloc_pages gfp order zonelist __alloc_pages_nodemask get_page_from_freelist ▻
wakeup_kswapd zone_watermark_ok kswapd_wait get_page_from_freelist zonelist lkm2 extern struct pglist_data contig_page_data zonelist zone buffered_rmqueue rmqueue_bulk __rmqueue __rmqueue_smallest __mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order)); zone_pcp bad_range page_outside_zone_boundaries page_is_consistent __mod_page_state prep_new_page set_page_refs zone_statistics
try_to_free_pages
== pci_mem __pa(x) - PAGE_OFFSET (0x80000000UL) phys_to_page(__pa(kaddr)) ({ unsigned int node = PHYSADDR_TO_NID(phys); \ NODE_MEM_MAP(node) \ + (((phys) - NODE_DATA(node)->node_start_paddr) >> PAGE_SHIFT); })
== pci_free_consistent P1SEGADDR 0x8... virt_to_page phys_to_page(__pa(kaddr)) free_pages ? __free_pages lkm2 free_hot_page free_hot_cold_page free_pcppages_bulk __free_one_page x free_pages_bulk __free_pages_ok *** page_zone zone_table list_add(&page->list, ¤t->local_pages); free_one_page __free_one_page lkm2 &zone->free_area[order].free_list lkm2 __mod_zone_page_state(zone, NR_FREE_PAGES, 1 << order); #include <linux/malloc.h>
free_area_init free_area_init_core mem_map lkm?
contig_page_data : pglist_data zonelist zone free_area
x pgdat_list pglist_data
kmalloc_array __kmalloc == kmalloc kmalloc_large kmalloc_order_trace kmalloc_order __alloc_pages_nodemask -> __alloc_pages_slowpath x warn_alloc_failed __kmalloc_node __do_kmalloc_node linux/mm/slab.c slob_alloc
kmalloc_sizes.h constexp kmalloc_caches kmalloc_type kmem_cache_alloc_trace kmem_cache_alloc lkm2 slab_alloc -> variable __kmalloc - generic slub.c kmalloc_slab kmalloc_caches[kmalloc_type slab_alloc slab_alloc_node __slab_alloc ___slab_alloc get_freelist __do_cache_alloc slob.c __do_kmalloc_node slab.c __do_kmalloc kmem_cache __find_general_cachep kmem_cache cache_sizes malloc_sizes __cache_alloc kmem_cache slab --- CONFIG_NUMA alternate_node_alloc ____cache_alloc array_cache cpu_cache_get cache_alloc_refill array_cache cache_grow kmem_getpages slab alloc_pages_node ▻ alloc_slabmgmt set_slab_attr init_once inode_init_once ac->entry
vm_area_struct
== kfree lkm2 kfree source/mm/slab.c c = virt_to_cache(objp); virt_to_head_page page_get_cache __cache_free(c, (void *)objp); kfree source/mm/slob.c min embedded systems kfree source/mm/slub.c virt_to_head_page __free_pages slab_free(page->slab, page, object, _RET_IP_); do_slab_free set_freepointer __slab_free
__kmem_cache_free kmem_cache_free_one -> cachep->slabs_free
#include <linux/mm.h> GFP_KERNEL GFP_ATOMIC __GFP_DMA __GFP_HIGHMEM
#include <linux/vmalloc.h> void * vmalloc(unsigned long size);
== vmalloc __vmalloc_node mm/vmalloc.c __vmalloc_node_range __vmalloc_area_node ->
vm_struct get_vm_area_node __get_vm_area_node vmlist vm_struct kmem_cache_alloc ▻ __vmalloc_area_node static mm/vmalloc.c __vmalloc_node ▻ kmalloc_node static __kmalloc_node __do_kmalloc_node static kmalloc_slab __kmem_cache_alloc_node slab_alloc_node __slab_alloc ___slab_alloc new_slab allocate_slab
xxx vm_area_alloc_pages alloc_pages_node ▻ map_vm_area vmap_pud_range vmap_pmd_range vmap_pte_range pte_t pte_alloc_kernel __pte_alloc_kernel init_mm pte_alloc_one_kernel 2.4 __vmalloc get_vm_area pmd_alloc pte_alloc
x early_trap_init lkm2 set_intr_gate(14, &page_fault); x page_fault arch/i386/kernel/entry.S:631: lkm2 do_page_fault current .. mm_structlt lkm2 mm_struct mm = tsk->mm; current .. mm_struct ?? notify_die notifier_call_chain vma = find_vma mm_struct ▻ vm_area_struct handle_mm_fault __handle_mm_fault handle_pte_fault do_swap_page lkm2 pte_to_swp_entry swap_free do_no_page filemap_nopage find_get_page radix_tree_lookup mark_page_accessed do_wp_page - protection fault do_file_page do_find_get_page alloc_page_vma alloc_pages ▻ swap_readpage get_swap_bio map_swap_page submit_bio mm_fault_error out_of_memory oom_kill_process select_bad_process pagefault_out_of_memory try_set_system_oom out_of_memory clear_system_oom
kswapd balance_pgdat shrink_zone shrink_cache shrink_list pageout swap_writepage get_swap_bio end_swap_bio_write end_page_writeback ▻
sys_swapon lkm2 filp_open bd_claim read_mapping_page setup_swap_extents add_swap_extent swap_info
vfree __vunmap vm_struct pages : page remove_vm_area find_vmap_area xx __remove_vm_area xx unmap_vm_area __free_page linux/gfp.h __free_pages ▻
<include/asm/uaccess.h>
copy_to_user() copy_from_user __copy_from_user __copy_from_user_ll __copy_user_zeroing __copy_user movsl get_user __get_user_x __get_user_ put_user()
#include <asm/io.h> BUILDIO inb/inw/inl/outb/outw/outl kmalloc'ed memory virt_to_phys __virt_to_phys x - PAGE_OFFSET + PHYS_OFFSE __pa __phys_addr v - PAGE_OFFSET phys_to_virt __va + PAGE_OFFSET __PAGE_OFFSET CONFIG_PAGE_OFFSET 0xC0000000 ioremap ▻ iounmap arch_iounmap __iounmap vunmap __vunmap ▻ ioport_map
traps.c do_address_error handle_unaligned_access
cache ▻ page_cache
pci_map_page
remap_page_range
flush_cache_all CONFIG_SH_CACHE_ASSOC CACHE_OC_ADDRESS_ARRAY CCR_CACHE_INIT
CCR Address of Cache Control Register
== sys_cacheflush find_vma
states coherent, cache = mem contains new data (after write to cache) invalid, necessary (contains no data) operations write back, cache ▻ mem, ▻ coherent CACHEFLUSH_D_WB dma_cache_wback __flush_wback_region asm ocbwb purge = write back + purge inv, cache ▻ mem, ▻ invalid CACHEFLUSH_D_PURGE dma_cache_wback_inv __flush_purge_region ocbp invalidate CACHEFLUSH_D_INVAL dma_cache_inv __flush_invalidate_region ocbi
dma_alloc_coherent 2.6 __get_free_pages ▻
davinci_map_io davinci_io_desc { IO_VIRT, IO_PHYS, IO_SIZE, MT_DEVICE }, 0xe1000000 0x01c00000 { DAVINCI_IRAM_VIRT, DAVINCI_IRAM_BASE, SZ_16K, MT_DEVICE }, { DAVINCI_FLASH_VIRT, DAVINCI_ASYNC_EMIF_DATA_CE0_BASE, SZ_16K, MT_DEVICE }, 0xe2000000 0x02000000 iotable_init create_mapping ... alloc_init_section alloc_init_page
nand_davinci_init nand_davinci_probe nand_davinci_read_buf nandobj.regs = (nandregsovly)IO_ADDRESS (DAVINCI_NAND_BASE_ADDR); 0x01E00000 this->IO_ADDR_R = (void __iomem *) DAVINCI_FLASH_VIRT;
0x01E00000 0x01E0 0FFF 4K EMIFA Control
==> ./oo/storage/mem_man/page/notes.txt <== struct page l/include/linux/mm_types.h pgoff_t index; /* Our offset within mapping. */ flags ZONES_MASK NODES_MASK SECTIONS_MASK ZONEID_MASK
linux/mm.h remap_page_range struct mm_struct *mm = current->mm; struct rw_semaphore mmap_sem; trvp(page); trvx(page_to_phys(page)); trvx(phys_to_virt(page_to_phys(page)));
-
Swapping: Methods for Freeing Memory What Is Swapping? Swap Area The Swap Cache Transferring Swap Pages Swapping Out Pages Swapping in Pages Reclaiming Page Frame mm/fadvise.c sys_fadvise64 sys_fadvise64_64 mm/filemap.c sys_readahead mm/fremap.c sys_remap_file_pages mm/madvise.c sys_madvise mm/mempolicy.c sys_get_mempolicy sys_mbind sys_migrate_pages sys_set_mempolicy mm/migrate.c sys_move_pages mm/mincore.c sys_mincore do_mincore mm/mlock.c sys_mlock2 sys_mlockall sys_mlock VM_LOCKED do_mlock apply_vma_lock_flags mlock_fixup vma_merge sys_munlockall sys_munlock mm/mmap.c sys_brk → sys_munmap mm/mprotect.c sys_mprotect mprotect do_mprotect_pkey
mprotect_fixup pgprot_modify
mm/mremap.c sys_mremap do_mremap mremap_to do_munmap vma_adjust move_vma mm/msync.c sys_msync lkm2 vfs_fsync ▻ mm/swapfile.c swappiness sys_swapoff sys_swapon ▻ show_smap walk_page_range pgd_offset PGDIR_SHIFT find_vma huge_pte_offset walk_pud_range pud_offset pud_addr_end walk_pmd_range walk_pte_range pte_offset_map addr += PAGE_SIZE; pte++; get_vmalloc_info vmlist
}
v4l2_device_register_subdev v4l2_subdev_fops security/ include/linux/security.h security_init security_ops register_security
selinux_init selinux_ops selinux_inode_create may_create permission ▻ video4linux v4l videodev_init register_chrdev video_fops video_open cx8800_devlist video_read videobuf_read_one video_mmap video_ioctl video_do_ioctl class_register(&video_class); video_register_device video_device __video_register_device
video_ioctl2 __video_do_ioctl VIDIOC_QUERYCAP v4l2_capability VIDIOC_QUERYCTRL v4l2_queryctrl sound init_soundcore soundcore_fops soundcore_open __look_for_unit chains snd_soc_skl - headphones snd_hda_intel - internal alsa_sound_last_init snd_cards snd_soc_instantiate_card snd_card_register snd_device_register_all __snd_device_register init_info_for_card snd_cards /proc/asound/cards snd_device_register __snd_device_register
esd/mplayer > /dev/dsp c 14 3 esd ?
0000:00:02.7 0401: 1039:7012 (rev a0) 0000:00:02.7 Multimedia audio controller: Silicon Integrated Systems [SiS] Sound Controller (rev a0) Subsystem: C-Media Electronics Inc: Unknown device 0300 Flags: bus master, medium devsel, latency 64, IRQ 11 I/O ports at dc00 [size=256] I/O ports at d800 [size=128] Capabilities: [48] Power Management version 2
azx_driver ./sound/pci/hda/hda_intel.c Intel HD Audio azx_probe snd_card_new skl_driver ./sound/soc/intel/skylake/skl.c ASoC Intel SKL HD Audio driver request_threaded_irq
alsa
alsa_sound_init register_chrdev snd_fops snd_open
snd_intel8x0.ko intel8x0 intel8x0_driver -> snd_intel8x0_probe ->
11: 1192578 XT-PIC ohci_hcd:usb2, eth0, SiS SI7012
d800-d87f : 0000:00:02.7 d800-d87f : SiS SI7012 dc00-dcff : 0000:00:02.7 dc00-dcff : SiS SI7012
snd_intel8x0_playback_ops snd_intel8x0_playback_open snd_intel8x0_pcm_pointer
x alsa_card_intel8x0_init module_init pci_register_driver
snd_intel8x0_proc_init snd_card_proc_new
snd_intel8x0_ids snd_intel8x0_probe snd_card_new snd_intel8x0_create pci_enable_device PCI snd_device_new sound/core/device.c / snd_card_free snd_intel8x0_chip_init snd_intel8x0_ich_chip_init pci_request_regions ▻ pci_resource_start pci_iomap request_irq snd_intel8x0_interrupt --> snd_card_set_dev snd_intel8x0_mixer snd_intel8x0_pcm snd_card_register -> snd_intel8x0_remove intel8x0_suspend intel8x0_resume
request_irq snd_intel8x0_interrupt snd_intel8x0_update
pci_driver ▻ PCI snd_audiopci_ids snd_audiopci_probe snd_card_new kernel.lnk/build/sound/core/init.c
alsa_card_ens137x_init pci_register_driver PCI
register_sound_dsp sound_insert_unit __sound_insert_unit devfs_mk_cdev SOUND_MAJOR devfs_mk_dev class_device_create class_device_register ... class_device_create_file
oss 11: 761694 XT-PIC ohci_hcd:usb2, eth0, SiS 7012
d800-d87f : 0000:00:02.7 d800-d83f : SiS 7012 dc00-dcff : 0000:00:02.7 dc00-dcff : SiS 7012
i810_audio.c * i810_init_module i810_pci_driver i810_probe register_sound_dsp i810_audio_fops ▻ i810_audio_fops i810_open i810_alloc_pcm_channel i810_ioctl i810_set_dac_rate ac97_set_dac_rate i810_write
+ ac97_codec ac97_register_driver input EV_LED hid_process_event usb_kbd_event atkbd_event kbd_init keyboard kbd
EV_KEY EV_MSC /dev/input/event c 113, 65 input_register_handler kbd_handler input_match_device class_device_add class_dev ▻ input_table handler->connect handler->start
kbd_handler input_handler kbd_connect input_dev alloc input_handle input_dev input_handler input_open_device input_handle input_dev->open kbd_start input_inject_event input_event -> kbd_event kbd_keycode handle_sysrq ▻ k_handler k_self put_queue tty_insert_flip_char tty->flip.char_buf_ptr++ = ch tasklet_schedule(&keyboard_tasklet); kbd_bh input_inject_event schedule_console_callback console_work, console_callback
input_init register_chrdev ▻ input_fops input_open_file, input_class input_dev_release input_dev_uevent input_add_uevent_modalias_var input_print_modalias class_register input_proc_init
evdev_init evdev_handler evdev_fops evdev_read input_event -> evdev_write evdev_connect input_register_handle evdev_install_chrdev
mousedev_init INPUT_MAJOR 13 hexdump /dev/input/mice # 13, 63 mousedev_handler input_register_handler input_handler ▻ class_device_create ▻
misc_register device_create ▻ misc_deregister device_destroy
mousedev_handler input_handler mousedev_event ▻ mousedev_connect input_dev input_open_device ▻ class_device_create ▻ mousedev_fops mousedev_read sys_read mousedev_read mousedev_packet usbhid_probe static usb_register hid_driver hid_add_device
module_hid_driver
hidinput_getkeycode hidinput_locate_usage
input_default_getkeycode input_fetch_keycode keycode keycodesize keycodemax;
input_configured
hid_input_report hid_report_raw_event ... hid_usage hid_process_event KEY_RESERVED KEY_A ... KEY_MAX
hid_device
common_interrupt __irq_exit_rcu local_softirq_pending invoke_softirq __do_softirq tasklet_action_common usb_giveback_urb_bh __usb_hcd_giveback_urb➝hid_irq_in➝hid_input_report➝hid_report_raw_event hid_input_array_field hid_process_event event hidinput_hid_event hiddev_hid_event hiddev_send_event
hid_driver semitek_driver my semitek_event input_report_key
lg_ultrax_remote_mapping ts_input_mapping
hid_debug_init hid_debug_register
KEY_HOME KEY_END
usb_kbd_init NOT USED usb_kbd_driver ... USB_INTERFACE_PROTOCOL_KEYBOARD usb_kbd_probe usb_kbd input_dev input_dev = input_allocate_device input_register_device(kbd->dev); input_dev class_device_add ▻ input_handle handler->connect input_dev_list input_handler_list input_dev = input_allocate_device
input_dev->event = usb_kbd_event usb_submit_urb input_dev->open = usb_kbd_open usb_submit_urb usb_set_intfdata usb_kbd_irq input_report_key
usb_mouse_init NOT USED usb_mouse_driver usb_mouse_probe input_dev = input_allocate_device tty_class_init tty_class = class_create tty_register_device tty_class device_create tty_init device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), "console"); TTYAUX_MAJOR cdev_add tty_fops tty_read ▻ tty_write <-vfs_write <- do_tty_write drivers/char/tty_io.c copy_from_user tty_ldisc->write write_chan drivers/char/n_tty.c opost_block con_flush_chars con_write do_con_write scr_writew out to screen con_write_room con_flush_chars set_cursor drivers/char/vt.c add_softcursor vgacon_cursor vgacon.c write_vga vgacon_set_cursor_size con_start release_console_sem call_console_drivers
register_chrdev_region /dev/tty device_create TTYAUX_MAJOR
cdev_init(&console_cdev, &console_fops); console_fops tty_open console_device console_drivers tty_read drivers/char/tty_io.c: tty_ldisc_ref_wait "Line Discipline" tty_ldisc_try ld->read read_chan drivers/char/n_tty.c job_control read_buf
cdev_add console_cdev register_chrdev_region /dev/console
tty? do_sys_open ? filp_open file_open_name do_filp_open ▻ x nameidata_to_filp __dentry_open chrdev_open tty_open init_dev n_tty_open
register_console
flush_to_ldisc drivers/char/tty_io.c disc->receive_buf tty->flip.char_buf ▻ -> n_tty_receive_buf drivers/char/n_tty.c ? n_tty_receive_char put_tty_queue_nolock put_tty_queue read_buf <= c
kgdb8250_add_platform_port
tty_struct read_buf
i8042_init i8042_platform_init platform_driver_register i8042_driver i8042_create_aux_port i8042_port_register i8042_create_kbd_port i8042_open ( on insert) request_irq i8042_interrupt i8042_read_data return inb(I8042_DATA_REG); serio_interrupt atkbd_interrupt input_event atkbd_report_key input_report_key input_event atkbd_event ./drivers/input/keyboard/atkbd.c schedule_work atkbd_event_work ps2_command ?? kbd_event ▻ psmouse_interrupt psmouse_process_byte input_report_rel input_event mousedev_event mousedev.c:296 mousedev_rel_event mousedev->packet.dx mousedev_notify_readers input_report_key ->
i8042_timer_func
./arch/i386/kernel/head.S
sysenter_entry sysenter_past_esp
proc_kmsg_operations kmsg_read vfs_read do_syslog
/dev/snd /dev/dsp snd_pcm_oss_write sound/core/oss/pcm_oss.c <- vfs_write sys_write snd_pcm_oss_write1 snd_pcm_oss_make_ready snd_pcm_oss_change_params snd_pcm_kernel_ioctl .... snd_intel8x0_setup_pcm_out
snd_intel8x0_interrupt
/dev/video
cam
sys_ioctl fs/ioctl.c lkm2 do_vfs_ioctl file_ioctl vfs_ioctl filp->f_op->unlocked_ioctl ext4_ioctl v4l2_unlocked_ioctl
lock_kernel filp->f_op->ioctl autofs_root_ioctl i2c_ioctl smb_ioctl fat_generic_ioctl ata_scsi_ioctl tcp_ioctl inet_ioctl video_ioctl2 unlock_kernel
sys_select core_sys_select do_select poll pipe_poll __pollwait fs/select.c:101 __get_free_pages -- frequent poll_freewait free_pages
cache_reap drain_array_locked free_block slab_destroy kmem_freepages slab free_pages virt_to_page __free_pages ▻
== procfs proc_file_read <- vfs_read
== fb fbmem_init register_chrdev fb_ops
register_framebuffer device_create ▻ registered_fb fb_init_device device_create_file ▻ fbmem_read_proc fb_write fb_get_fix fbcon_setup
consw fb_con fbcon_init
fb_console_init fbcon_takeover take_over_console
fbcon_putcs get_color vc_data
display fb_display
sisfb_init_module sisfb_init sisfb_setup sisfb_driver sisfb_probe ivideo sisfb_inverse sisfb_ops sisfb_set_disp display vt8623fb_init linux-2.6.22.9/drivers/video/vt8623fb.c fb_get_options("vt8623fb", &option)) pci_register_driver vt8623fb_pci_driver vt8623_pci_probe pci_request_regions ▻ framebuffer_alloc + vt8623fb_info register_framebuffer vt8623fb_ops fb_ops vt8623fb_open vt8623fb_imageblit pci_iomap == console vc vc_cons vc_data con_init save_screen update_screen
console_init
drivers/gpu DRM_IOCTL_BASE drm_init drm_driver lkm2 drm_platform_init drm_get_platform_dev drm_pci_init pci_register_driver
radeon_init drm_init
i915_init drm_init nouveau_init drm_init
amdgpu_init hl_init habanalabs_drv.c hl_pci_driver hl_pci_probe hl_pci_remove hl_device_init device_early_init goya_set_asic_funcs goya_funcs goya_early_init hl_pm_ops hl_pmops_suspend hl_device_suspend pci_save_state pci_disable_device pci_set_power_state hl_pci_err_handler hl_pci_err_detected
drivers/media/video/ uvc_init uvc_driver uvc_probe uvc_register_video video_device video_device_alloc video_register_device ▻ gspca_init gspca_dev_probe gspca_dev_probe2 video_register_device ▻
sd_mod_init usb_register(&sd_driver); sd_driver (many) sd_probe ▻ gspca_dev_probe ▻
serial8250_isa_driver serial8250_probe plat_serial8250_port serial8250_register_port uart_add_one_port tty_register_device
uvc_mc_init_entity media_entity_init
g_webcam from 2.6.35 uvc_gadget_trace_param drivers/usb/gadget/f_uvc.c UVC_TRACE_PROBE uvc_trace
uvc_trace_param
webcam_init drivers/usb/gadget/webcam.c return usb_composite_probe(&webcam_driver, webcam_bind); webcam_bind usb_add_config(cdev, &webcam_config_driver, webcam_config_bind) webcam_config_bind uvc_bind_config drivers/usb/gadget/f_uvc.c uvc_device drivers/usb/gadget/uvc.h usb_add_function bind uvc_function_bind uvc_video_init --- drivers/media/video/uvc/uvc_video.c drivers/usb/gadget/uvc_video.c uvc_register_video drivers/usb/gadget/f_uvc.c video_device_alloc uvc_v4l2_fops uvc_v4l2_open-> uvc_v4l2_ioctl ▻
uvc_v4l2_mmap video_register_device usb_add_gadget_udc ▻ usb_composite_probe usb_gadget_probe_driver &udc_list composite_bind
uvc_v4l2_open uvc_function_connect usb_function_activate usb_gadget_connect gadget->ops->pullup ▻ ? musb_gadget_pullup
uvc_v4l2_ioctl uvc_v4l2_do_ioctl uvc_v4l2_set_format
camorama -D --width=640 --height=480
stk_camera_init ./drivers/media/video/stk-webcam.c usb_register ▻ stk_camera_driver stkwebcam_table stk_camera_probe stk_register_video_device stk_v4l_data v4l_stk_ioctl_ops stk_vidioc_s_fmt_vid_cap stk_vidioc_try_fmt_vid_cap stk_initialise ~= dev_stk11xx_initialize_device stk1125_initvals ~= dev_stk0408_configure_device stk_camera_write_reg usb_control_msg stk_setup_format stk_sizes stk_sensor_configure stk_vidioc_streamon stk_start_stream ~= dev_stk0408_start_stream stk_camera_read_reg stk_camera_write_reg v4l_stk_fops v4l_stk_read stk_initialise ~= dev_stk11xx_initialize_device v4l_stk_open video_ioctl2 __video_do_ioctl video_register_device ▻
syntekdriver 2.6.31-16-generic OK rmmod stk11xx; modprobe stk11xx norm=1 0=NTSC, 1=PAL usb_stk11xx_init usb_register usb_stk11xx_driver usb_stk11xx_probe dev_stk11xx_camera_on :0501 SYNTEK_STK_M811 05e1:0408 Syntek Semiconductor Co., Ltd udev->descriptor.idVendor udev->descriptor.idProduct webcam_model webcam_type
dev_stk11xx_initialize_device dev_stka311_initialize_device dev_stk0408_initialize_device usb_stk11xx_write_registry dev_stk0408_configure_device dev->vsettings.norm dev_stk0408_set_resolution v4l_stk11xx_register_video_device ▻ usb_stk11xx_default_settings dev->vsettings.norm
v4l_stk11xx_register_video_device video_register_device ▻ v4l_stk11xx_fops
v4l_stk11xx_fops v4l_stk11xx_open v4l_stk11xx_select_video_mode dev_stk11xx_init_camera dev_stk0408_init_camera dev_stk0408_camera_asleep dev_stk0408_configure_device usb_stk11xx_read_registry usb_stk11xx_write_registry dev_stk0408_sensor_settings dev_stk11xx_camera_on usb_set_interface dev_stk11xx_reconf_camera err = usb_stk11xx_isoc_init dev_stk11xx_start_stream ▻ dev_stk11xx_camera_settings dev_stk0408_camera_settings dev_stk0408_set_camera_quality v4l_stk11xx_read stk11xx_handle_frame v4l_stk11xx_ioctl VIDIOC_DQBUF stk11xx_handle_frame dev_stk11xx_decompress dev_stk0408_decode stk11xx_copy_uvyv stk11xx_copy_rgb video_usercopy v4l_stk11xx_do_ioctl VIDIOC_STREAMON usb_stk11xx_isoc_init VIDIOC_STREAMOFF usb_stk11xx_isoc_cleanup stk11xx_next_image dev_stk11xx_init_camera dev_stk11xx_camera_on dev_stk11xx_reconf_camera dev_stk11xx_start_stream dev_stka311_start_stream dev_stk0408_start_stream dev_stk11xx_camera_settings video_set_drvdata video_register_device ▻
emac_dev_xmit emac_send emac_write
usbtest_init usbtest_driver usbtest_ioctl
usb_serial_generic_register usb_serial_register usb_serial_generic_device usb_register generic_driver
ast_init ast_pci_driver ast_pci_probe ast_driver ast_pci_driver mgag200_pci_driver mgag200_driver
.vmap = drm_gem_vram_object_vmap drm_gem_vram_vmap drm_gem_shmem_funcs .vmap = drm_gem_shmem_object_vmap drm_clflush_pages drm_cache_flush_clflush drm_clflush_page clflushopt mgag200_handle_damage drm_gem_shmem_vmap drm_fb_memcpy_dstclip 6 drm_fb_memcpy + drm_clflush_virt_range clflushopt clflush Flush Cache Line wbinvd_on_all_cpus on_each_cpu wbinvd native_wbinvd asm wbinvd mgag200_set_startadd mgag200_set_offset
drm_gem_object drm_gem_object_funcs : {{The Linux Kernel/man|2|membarrier}} arch/x86/include/asm/cacheflush.h clflush_cache_range arch/x86/mm/pat/set_memory.c mb arch/x86/include/asm/barrier.h asm "mfence" : : : "memory" clflush_cache_range_opt CPA - Change Page Attribute clflushopt mb
x drm_gem_fb_simple_display_pipe_prepare_fb x drm_gem_fb_prepare_fb
drm_simple_display_pipe_funcs DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS .prepare_fb drm_gem_simple_kms_prepare_shadow_fb drm_gem_vmap vmap
drm_gem_shmem_vmap drm_gem_shmem_vmas_locked map_wc pgprot_writecombine ->
drm_gem_shmem_object map_wc pgprot_writecombine __pgprot(pgprot_val(prot) | cachemode2protval(_PAGE_CACHE_MODE_WC));
gem_create_object = mgag200_create_object
vi /etc/default/grub; update-grub; reboot
# argv = "/usr/bin/gdb -q -batch -ex run -ex bt --args".split() + argv
do_int3 do_trap(X86_TRAP_BP, SIGTRAP, "int3", regs, error_code, NULL); -->int3 @ arch/x86/kernel/entry_32.S ?? do_int3
pr_debug #undef pr_fmt #define pr_fmt(fmt) "%s.c:%d %s " fmt, KBUILD_MODNAME, __LINE__, __func__
pr_debug("\n"); pr_debug("ret = %d\n",ret); pr_info pr_devel
ctracer KBUILD_CFLAGS:= $(filter-out -Werror-implicit-function-declaration,$(KBUILD_CFLAGS)) KBUILD_CFLAGS:= $(filter-out -Wdeclaration-after-statement,$(KBUILD_CFLAGS)) ccflags-y+= -D CTRACER_ON -include linux/printk.h -include linux/kern_levels.h -include ctracer.h subdir-ccflags-y+= -D CTRACER_ON -include ctracer.h ccflags-y+= -DDEBUG subdir-ccflags-y = -D DEBUG
dynamic_debug_init_debugfs
dev_dbg #undef CONFIG_DYNAMIC_DEBUG #define DEBUG dynamic_dev_dbg dev_printk kdb kdb_init(KDB_INIT_FULL); kdb_inittab kdb_initbptab kdb_cmd_init kdb_cmds
kdb_stub
echo ttyS0 > /sys/module/kgdboc/kernel/kgdboc echo kbd > /sys/module/kgdboc/kernel/kgdboc echo g > /proc/sysrq-trigger
kdb_inittab
kprobes init_kprobes arch_init_kprobes
register_kretprobes register_kretprobe register_kprobe lkm2 arch_prepare_kprobe arch_copy_kprobe
URL=http://lkcd.sourceforge.net/
==> ./stages/testing/debug/crash/notes.txt <== do_page_fault die show_registers show_regs show_stack stack = esp show_trace lookup_symbol do_exit ▻ panic dump_stack dump_stack_lvl show_stack trace_nvme_complete_rq show_trace_log_lvl printk_stack_address x dump_backtrace x unwind_backtrace unwind_frame dump_backtrace_entry x print_symbol == oops
kgdb ▻ do_page_fault show_state
debugging CONFIG_MAGIC_SYSRQ proc_sysrq_trigger_operations handle_sysrq sysrq_key_table GDB_OP sysrq_handle_showstate show_state show_state_filter sched_show_task x show_task show_workqueue_state ->
2.4 handle_sysrq __handle_sysrq_nolock __sysrq_get_key_op sysrq_key_table /* 1 */ &sysrq_loglevel_op, /* b */ &sysrq_reboot_op, sysrq_handle_reboot /* e */ &sysrq_term_op, sysrq_handle_term /* g */ GDB_OP, breakpoint BREAKPOINT /* h */ NULL, /* i */ &sysrq_kill_op, sysrq_handle_kill /* k */ &sysrq_SAK_op, /* m */ &sysrq_showmem_op, show_mem /* p */ &sysrq_showregs_op, sysrq_handle_showregs show_regs /* r */ &sysrq_unraw_op, /* s */ &sysrq_sync_op, /* t */ &sysrq_showstate_op, sysrq_handle_showstate show_state /
traps.c CHK_REMOTE_DEBUG kgdb_debug_hook ▻ kgdb
== kgdb arm-none-linux-gnueabi-gdb vmlinux
target remote /dev/ttyUSB0
http://kgdb.sourceforge.net/ http://kgdb.linsyssoft.com/
x kgdb_initialized kgdb_breakpoint kgdb_early_entry kgdb_arch_init kgdb_internal_init kgdb_io_ops.init init_kgdboe kgdb_eth.c kgdb8250_init serial_outb
kgdb8250_local_init serial_outb = io_outb
CONFIG_KGDB CONFIG_KDB x kgdb_init breakpoint do_page_fault __do_page_fault oops ▻ kgdb_bus_err_hook force_sig_info_fault
kgdb_parse_options kgdb_debug_hook = kgdb_handle_exception; breakpoint BREAKPOINT
CONFIG_FRAME_POINTER
kgdb_io kgdb_io_ops
==> ./stages/testing/debug/knotes.txt <== -> kgdb
== log control_devkmsg ___ratelimit memdev kmsg_fops devkmsg_release ratelimit_state_exit devkmsg_write - kmsg_write == printk print_hex_dump pr_crit_ratelimited dprintk --- various implementations
default_message_loglevel DEFAULT_MESSAGE_LOGLEVEL console_printk printk_ratelimit __printk_ratelimit log_buf log_buf_len_setup __log_buf __LOG_BUF_LEN CONFIG_LOG_BUF_SHIFT emit_log_char LOG_BUF log_buf do_syslog call_console_drivers _call_console_drivers console_loglevel DEFAULT_CONSOLE_LOGLEVEL __call_console_drivers console_drivers con->write printk_once vprintk_default vprintk_emit vscnprintf
trace_printk do_trace_printk __trace_bprintk trace_vbprintk vbin_printf __trace_printk trace_vprintk __trace_array_vprintk vscnprintf -> trace_puts printk_deferred printk_index_wrap __printk_index_emit _printk_deferred vprintk_deferred vprintk_emit printk_store perf vsnprintf printk /proc/sys/kernel/printk debug_kernel quiet_kernel vprintk CONFIG_DEBUG_LL printascii senduart vscnprintf vsnprintf format_decode bitmap_string kstrtoint simple_strtol simple_strtoul number
klogd
KERN_EMERG 0 .. KERN_DEBUG 7
sys_syslog do_syslog
seq_file seq_operations
console_verbose console_loglevel console_printk
log_start
CONFIG_PROFILING
proc - discouraged
URL=http://ltp.sourceforge.net/ https://github.com/linux-test-project/ltp ltp ltpmenu runltp scenario_groups/default runltplite.sh ./runtest/ltplite CREATE_ENTRIES=1 time ./runltplite.sh -q -d /var/volumes/vol1/tmp | tee $(uname -r).ltplite.txt cd /var/volumes/vol1/ltp CREATE_ENTRIES=1 time ./runltp -q -d /var/volumes/vol1/tmp | tee $(uname -r).ltp.txt
https://codeload.github.com/pjd/pjdfstest/zip/master
/fs/devfs/base.c depricated devfs_mk_cdev devfs_mk_dev
==> ./oo/subsystems/notes.txt <== == oprofile oprofile_operations oprofile_init lkm2 oprofile_arch_init op_nmi_init op_amd_spec op_ppro_spec nmi_start nmi_cpu_start op_amd_start ppro_start rdmsrl rdmsr wrmsrl wrmsr nmi_timer_init timer_start nmi_timer_callback oprofile_add_sample x86_backtrace dump_backtrace oprofile_add_trace add_sample oprofilefs_register oprofilefs_type oprofilefs_get_sb oprofilefs_fill_super oprofile_create_files enable_fops enable_write oprofile_start lkm2 nmi_start ▻ quiet + cat /proc/sys/kernel/printk 10 4 1 7
# echo 'hist:keys=delta.buckets=100,stack.stacktrace:sort=delta' > events/synthetic/block_lat/trigger # cat events/synthetic/block_lat/hist
# ./bcc/tools/xfsslower.py bpf_ktime_get_ns xfs_file_fsync min_ms FILTER_US
./bcc/examples/tracing/biolatpcts.py io_start_time_ns bpf_ktime_get_ns
bcc/tools/biolatpcts.py io_start_time_ns
./bcc/examples/tracing/disksnoop.py bpf_ktime_get_ns bpf_trace_printk
./bcc/libbpf-tools/biolatency.c bpf_program__set_autoload progs.block_rq_complete
./bcc/libbpf-tools/biolatency.bpf.c trace_block_rq_insert block_rq_issue trace_rq_start bpf_map_update_elem(&start, &rq, &ts, 0); block_rq_complete handle_block_rq_complete bpf_map_update_elem bpf_map_lookup_elem
./bcc/libbpf-tools/biosnoop.c min_lat_ms perf_buffer__new bpf_program__set_autoload bpf_program__set_attach_target
./bcc/libbpf-tools/biosnoop.bpf.c block_rq_insert trace_rq_start bpf_map_update_elem(&start, &rq, stagep, 0); block_rq_complete min_ns bpf_perf_event_output
./bcc/tools/biolatency.py - BPF_HISTOGRAM
./bcc/libbpf-tools/wakeuptime.bpf.c ./bcc/tools/wakeuptime.py ./bcc/tools/runqslower.py
samples bpf_helpers.h __BPF_HELPERS_H tracex4_kern bpf_prog2 PT_REGS_RC tracex2_kern bpf_prog3 kprobe/sys_write tracex5_kern bpf_prog1 bpf_probe_read syscall_nrs syscall_defines SYS__NR_write bpf_trace_printk syscall_tp_user load_bpf_file do_load_bpf_file get_sec elf_getdata kprobe/ tracepoint/ bpf_map_lookup_elem syscall_tp_kern trace_enter_open
make O=/home/costa/App/Platforms/X86/ bpf -C tools/ tools/bpf/Makefile tools/bpf/bpftool/Makefile tools/lib/bpf/Makefile user lib bpf_raw_tracepoint_open BPF_RAW_TRACEPOINT_OPEN bpf_prog_get_type bpf_prog_get_type_dev __bpf_prog_get ____bpf_prog_get trace_bpf_prog_get_type bpf_probe_register __bpf_probe_register tracepoint_probe_register tracepoint_probe_register_prio tracepoint_add_func func_add do_batch do_prog do_load bpf_prog_load BPF_PROG_LOAD bpf_object__load bpf_object__load_progs bpf_program__load load_program bpf_load_program_name sys_bpf BPF_PROG_LOAD sys_bpf BPF_PROG_LOAD bpf_prog_load find_prog_type BPF_PROG_TYPE_TRACEPOINT BPF_PROG_TYPE_RAW_TRACEPOINT BPF_PROG_TYPE_KPROBE BPF_PROG_TYPE_PERF_EVENT bpf_obj_name_cpy bpf_prog_select_runtime bpf_prog_kallsyms_add bpf_attr pf_trace_printk bpf_get_current_comm bpf_perf_prog_read_value bpf_trace_printk_proto bpf_trace_printk BPF_CALL_5 SEC("kprobe/sys_open") bpf_sys_open bpf_probe_read_str bcc BPF_PERF_OUTPUT events.perf_submit bpf_ctx["BPF_PERF_OUTPUT"].open_perf_buffer(print_event) perf_buffer_poll detach_kprobe_event bpf_detach_kprobe bpf_detach_probe TestKprobe HelloWorld BPF.init load_string load_cfile BPF_PROGRAM attach_kprobe load_func bpf_prog_load ▻ bpf_attach_kprobe bpf_attach_tracing_event __NR_perf_event_open get_syscall_fnname detach_kprobe get_syscall_fnname attach_kprobe bpf_attach_kprobe
trace_print src/python/bcc/__init__.py trace_readline trace_open trace_pipe kprobe__sys_clone bpf_usdt_readarg
{ other audit_init netlink_kernel_create(&init_net, NETLINK_AUDIT, 0, audit_receive, NULL, THIS_MODULE); audit_receive audit_receive_skb audit_receive_msg kauditd_thread
== lists struct list_head list_add LIST_HEAD list_for_each_entry list_for_each_entry_reverse ?? list_head list_add_tail == config
qconf configApp
conf_parse conf_read ConfigMainWindow
gtk glib pango
==> ./deb <== fakeroot make-kpkg --initrd --revision=2.6.15.1-conan kernel_image make-kpkg --initrd --revision=2.6.15.1-conan kernel_image dpkg -i linux-image-2.6.15.1_2.6.15.1.conan_i386.deb
==> ./snd-remove <== rmmod snd snd_ens1371 snd_rawmidi snd_seq_device snd_ac97_codec snd_pcm_oss snd_mixer_oss snd_pcm snd_timer
==> ./linked_list_pp <== grep -Prn ' *= *&\w+ *-> *next *;' kernel.lnk/linux-2.6.13-conan/
==> ./grep_dm <== grep ^exec /var/log/dmesg | sort | uniq -c | sort -n
}
git branch --edit-description
git format-patch -3 --cover-letter --cover-from-description=subject
git fetch origin merge-requests/$mrid/head:$branchname
git describe --contains --match 'v*' 5a80bd075f3b
ICA InterCallings Analysis http://tldp.org/HOWTO/KernelAnalysis-HOWTO-2.html ctags -x -R include/ | while read a b c; do echo $b; done | sort | uniq -c ctags -x --c-kinds=-mde+p -R include/ | while read -a a ; do echo -e "${a[3]} ${a[1]} \t${a[0]}"; done ctags -x --c-kinds=d -R include/ | while read -a a ; do echo -e "${a[0]}"; done > include-defines.ids
grep pci include-defines.ids | while read a ; do echo -ne "$a\t"; grep -r --include='*.c' --include='*.h' $a | wc -l; done | tee pci-defines-usage
atomic_t cmpxchg circ_buf clamp_val clamp_t include/uapi/linux/types.h __sum16 compiler-gcc.h __packed native_irq_return_iret _LINUX_SYSCALLS_H
pthread_mutex_lock __pthread_mutex_lock __pthread_mutex_lock_full atomic_compare_and_exchange_val_acq __sync_val_compare_and_swap arch_atomic_val_compare_and_exchange libgcc kselftest
random_fops random_write write_pool drivers/char/random.c arch_get_random_int arch/x86/include/asm/archrandom.h arch_has_random rdrand_int
arch_get_random_longs rdrand_long
{ unsorted levels virtual real/physical dma_cache_wback_inv
panic
communication
usb_serial_driver : usb_driver
IOMMU: buss address <-> phys address
dma_pool dma_pool_create
i2c_smbus_xfer
i2c_algorithm smbus_algorithm .smbus_xfer = vt596_access, .functionality = vt596_func,
netfilter_init nf_hooks
nf_register_hooks nf_register_hook nf_hooks
CONFIG_NETFILTER ipv4_netfilter_init nf_register_afinfo nf_ip_afinfo nf_afinfo nf_ip_route ip_route_output_key
iptable_raw_init nf_register_hooks ▻ mmap_mem
sys_timer_create
TIME time sys_gettimeofday do_gettimeofday xtime getnstimeofday sys_time get_seconds xtime_cache.tv_sec
sys_times do_sys_times jiffies_64_to_clock_t(get_jiffies_64()); jiffies_64 jiffies
sys_fstat64 oprofile sys_lookup_dcookie fs/dcookies.c
sys_epoll_create fs/eventpoll.c lkm2 sys_epoll_create1 anon_inode_getfd anon_inode_getfile d_alloc_pseudo d_alloc alloc_file lkm2 get_empty_filp special_file file_take_write mnt_clone_write ima_counts_get
sys_eventfd fs/eventfd.c sys_eventfd2 eventfd_file_create eventfd_fops eventfd_read eventfd_ctx_do_read anon_inode_getfile ▻ fd_install ▻ }
{
{ Hardware name: HPE ProLiant RL300 Gen11/ProLiant RL300 Gen11, BIOS 1.70 05/23/2024 50.00 BogoMIPS 5.14.0-284.67.1.el9_2.aarch64+64k (mockbuild@aarch64-024.brew-001.prod.us-east-1.aws.redhat.com) (gcc (GCC) 11.3.1 20221121 (Red Hat 11.3.1-4), GNU ld version 2.35.2-37.el9) #1 SMP PREEMPT_DYNAMIC Mon May 13 15:24:28 UTC 2024 LPI Locality-specific Peripheral Interrupt AIC Apple Interrupt Controller GIC Generic Interrupt Controller SGI Software Generated Interrupt TGC Trusted Computing Group TPM Trusted Platform Module https://en.wikipedia.org/wiki/Trusted_Platform_Module PCR Platform Configuration Register
rcu_spawn_one_boost_kthread rcub
syscall_exit_to_user_mode irqentry_exit_to_user_mode ... rseq_handle_notify_resume __rseq_handle_notify_resume rseq_update_cpu_id trace_rseq_update
? __schedule rcu_note_context_switch "Start context switch" trace_rcu_utilization rcu_utilization rcu_qs rcu_tasks_qs(current, preempt);
gic_irq_domain_alloc gic_irq_domain_map gic_chip gic_ipi_send_mask gic_send_sgi arch_send_call_function_single_ipi smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC); ipi_raise __ipi_send_mask(ipi_desc[ipinr], target); chip->ipi_send_single(data, cpu);
irq_create_mapping irq_create_mapping_affinity irq_create_mapping_affinity_locked irq_domain_alloc_descs ->
gic_smp_init irq_domain_alloc_irqs __irq_domain_alloc_irqs irq_domain_alloc_descs __irq_alloc_descs -> set_smp_ipi_range ipi_desc request_percpu_irq __request_percpu_irq IRQF_PERCPU | IRQF_NO_SUSPEND irqaction __setup_irq-> >ipi_handler do_handle_IPI [IPI_CALL_FUNC] = "Function call interrupts", ipi_types trace_ipi_entry ipi_entry generic_smp_call_function_interrupt generic_smp_call_function_single_interrupt __flush_smp_call_function_queue ->
__secondary_switched secondary_start_kernel cpu_startup_entry do_idle -> cpuidle_idle_call cpuidle_enter cpuidle_enter_state trace_cpu_idle_miss schedule_idle __schedule
dnf install -y -q bpftrace; mount null -t tracefs /sys/kernel/tracing/ bpftrace -e "kprobe:generic_handle_domain_irq { @[kstack()] = count();}" bpftrace -e "kprobe:generic_smp_call_function_single_interrupt { @[kstack()] = count();}" eval 'bpftrace -e "kprobe:$1 { @[kstack()] = count();}"'
bpftrace -e "kprobe:set_cpus_allowed_common { @[kstack()] = count();}"
sh -c 'sudo bpftrace -e "kprobe:$0 { @[kstack()] = count();}"' $ARG
arch/arm64/kernel/entry.S generate_el1_vector entry_handler kernel_ventry el1h_64_irq
el1h_64_irq_handler handle_arch_irq el1_interrupt __el1_irq do_interrupt_handler call_on_irq_stack gic_handle_irq -> generic_handle_domain_irq-> gic_acpi_init gic_init_bases set_handle_irq handle_arch_irq > gic_handle_irq __gic_handle_irq_from_irqson __gic_handle_irq generic_handle_domain_irq->
generic_handle_domain_irq irq_resolve_mapping __irq_resolve_mapping handle_irq_desc generic_handle_irq_desc ->
generic_handle_domain_irq+48 handle_percpu_devid_irq+140 ipi_handler ->
call_on_irq_stack gic_handle_irq __gic_handle_irq_from_irqson.isra.0 generic_handle_domain_irq handle_percpu_devid_irq arch_timer_handler_phys hrtimer_interrupt hrtimer_wakeup
crb_acpi_driver crb_acpi_add acpi_get_table acpi_tb_get_table acpi_tb_validate_table acpi_tb_acquire_table acpi_os_map_memory acpi_os_map_iomem acpi_table_tpm2 start_method tpm_chip_register tpm_chip_start tpm_request_locality tpm_cmd_ready tpm_relinquish_locality crb_relinquish_locality __crb_relinquish_locality CRB_LOC_CTRL_RELINQUISH crb_wait_for_reg_32 tpm_auto_startup tpm2_auto_startup tpm2_startup tpm2_do_selftest TPM2_CC_SELF_TEST tpm_transmit_cmd tpm2_get_cc_attrs_tbl tpm2_get_tpm_pt tpm_transmit_cmd -> tpm_buf_append_u32 tpm_buf_append tpm_add_hwrng hwrng_register hwrng https://docs.kernel.org/admin-guide/hw_random.html
el0t_64_sync el0t_64_sync_handler el0_svc do_el0_svc el0_svc_common invoke_syscall __arm64_sys_read ksys_read -> vfs_read -> rng_dev_read
rng_dev_read reading_mutex get_current_rng get_current_rng_nolock
rng_get_data ->
/sys/devices/virtual/misc/hw_random/rng_current:tpm-rng-0 devm_hwrng_register hwrng_register hwrng_manage_rngd hwrng_fillfn - thread ? data_read rng_get_data tpm_hwrng_read tpm_get_random tpm2_get_random tpm_transmit_cmd tpm_transmit bpftrace -e "kprobe:tpm_transmit { @[kstack()] = count();}" bpftrace -e 'kprobe:tpm_transmit { printf("%s \n",ksym(((struct tpm_chip *)arg0)->ops->send));}' tpm_try_transmit chip->ops->send crb_send len=12 chip->ops->recv crb_recv tpm_calc_ordinal_duration tpm2_calc_ordinal_duration -> crb_cancel crb_do_acpi_start -> tpm_msleep -> tpm2_calc_ordinal_duration tpm2_ordinal_duration_index tpm_msleep usleep_range usleep_range_state schedule_hrtimeout_range schedule_hrtimeout_range_clock TASK_UNINTERRUPTIBLE add_hwgenerator_randomness credit_entropy_bits
crb_send iowrite32 memcpy_toio __memcpy_toio __raw_writeq wmb crb_do_acpi_start acpi_evaluate_dsm bpftrace -e "kprobe:acpi_evaluate_dsm { @[kstack()] = count();}" SMCCC System Monitor Call Convention https://developer.arm.com/Architectures/SMCCC SMC Secure Monitor Call priv->smc_func_id tpm_crb_smc_start arm_smccc_smc __arm_smccc_smc Perform the Secure Monitor Call arch/arm64/kernel/smccc-call.S SMCCC __arm_smccc_sve_check crb_recv CRB Command Response Buffer ioread32 memcpy_fromio bpftrace -e 'kprobe:__memcpy_fromio { @start[tid] = nsecs;} kprobe:__memcpy_fromio /@start[tid] != 0/ {printf("%d ms\n",(nsecs - @start[tid])/1e3);delete(@start[tid]);}' crb_cmd_ready __crb_cmd_ready crb_wait_for_reg_32 ioread32
hisi_rng_read add_hwgenerator_randomness
taskset -cp 1 $(pgrep -f hwrng) ps -o psr,pid,comm -C hwrng
for c in {10..12};do echo 0 > /sys/devices/system/cpu/cpu$c/online; echo 1 > /sys/devices/system/cpu/cpu$c/online; done for c in {16..127};do echo 0 > /sys/devices/system/cpu/cpu$c/online; done
enum tpm2_pt_props { TPM2_PT_NONE = 0x00000000, TPM2_PT_GROUP = 0x00000100, TPM2_PT_FIXED = TPM2_PT_GROUP * 1, TPM2_PT_FAMILY_INDICATOR = TPM2_PT_FIXED + 0, TPM2_PT_LEVEL = TPM2_PT_FIXED + 1, TPM2_PT_REVISION = TPM2_PT_FIXED + 2, TPM2_PT_DAY_OF_YEAR = TPM2_PT_FIXED + 3, TPM2_PT_YEAR = TPM2_PT_FIXED + 4, TPM2_PT_MANUFACTURER = TPM2_PT_FIXED + 5, TPM2_PT_VENDOR_STRING_1 = TPM2_PT_FIXED + 6, TPM2_PT_VENDOR_STRING_2 = TPM2_PT_FIXED + 7, TPM2_PT_VENDOR_STRING_3 = TPM2_PT_FIXED + 8, TPM2_PT_VENDOR_STRING_4 = TPM2_PT_FIXED + 9, TPM2_PT_VENDOR_TPM_TYPE = TPM2_PT_FIXED + 10, TPM2_PT_FIRMWARE_VERSION_1 = TPM2_PT_FIXED + 11, TPM2_PT_FIRMWARE_VERSION_2 = TPM2_PT_FIXED + 12, }
static check_ver(struct tpm_chip *chip) { // crb_acpi_add // tpm_chip_register // tpm_add_hwrng u32 val1, val2; u64 version;
tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val, NULL); tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_1, &val1, NULL); tpm2_get_tpm_pt(chip, TPM2_PT_FIRMWARE_VERSION_2, &val2, NULL); version = ((u64)val1 << 32) | val2; }
armada_370_pinctrl_driver "armada-370-pinctrl" "marvell,mv88f6710-pinctrl" armada_370_pinctrl_probe armada_370_pinctrl_info mvebu_pinctrl_probe LED gpio_led_init gpio_led_probe ▻ gpio_led_driver of_gpio_leds_match "gpio-leds" "leds-gpio"
gpio_led_probe ... gpio_blink_set led_dat->platform_gpio_blink_set create_gpio_led gpio_request gpio_direction_output CONFIG_DEBUG_GPIO chip->request mv_gpio_request mv_gpio_is_valid chip->direction_output mv_gpio_direction_output gpio_leds_create device_for_each_child_node fwnode_property_read_string
arch_irq_work_raise apic->send_IPI_self(IRQ_WORK_VECTOR); // X86_TRAP_MF default_send_IPI_self __default_send_IPI_shortcut(APIC_DEST_SELF, vector, apic->dest_logical); __prepare_ICR(shortcut, vector, dest); native_apic_mem_write(APIC_ICR, cfg); ... irq_work_interrupt
platform_get_irq platform_get_resource resource_type
CONFIG_SPI_SPIDEV spidev_init
CONFIG_REGULATOR CONFIG_REGULATOR_FIXED_VOLTAGE regulator_fixed_voltage_init ... reg_fixed_voltage_probe of_get_fixed_voltage_config of_get_regulator_init_data of_get_regulation_constraints of_get_property ... regulator-name
CONFIG_OF of_unittest of_unittest_property_string of_property_match_string of_property_count_strings of_property_read_string of_find_property ▻ of_property_read_string_array of_property_read_string_helper of_property_read_* of_property_read_bool of_find_property __of_find_property of_prop_cmp properties of_property_read_u8 of_property_read_u8_array of_find_property_value_of_size ▻ of_property_read_u32 of_property_read_u32_array of_find_property_value_of_size of_find_property ▻ be32_to_cpup __be32_to_cpup fdt_translate_address count_cells of_match_bus of_busses count_cells of_bus_default_count_cells of_n_addr_cells of_n_size_cells
/proc/device-tree of_core_init for_each_of_allnodes for_each_of_allnodes_from __of_find_all_nodes of_root prev->child np->parent np->sibling of_unittest_platform_populate platform_device of_find_device_by_node of_parse_phandle __of_parse_phandle_with_args of_get_child_by_name for_each_child_of_node of_get_next_child __of_get_next_child next = next->sibling of_node_get(next)) kobject_get kref_get atomic_inc_return atomic_add_return ATOMIC_OP_RETURN raw_local_irq_save op raw_local_irq_restore of_node_put(prev); of_node_cmp of_find_node_by_name of_get_child_count for_each_child_of_node of_node_put kobject_put kref_put kobject_release kobject_cleanup kobject_del t->release
i2c_register_adapter of_i2c_register_devices of_i2c_register_device of_get_property be32_to_cpup
ofdev->dev.of_node struct device_node *np = pdev->dev.of_node; of_get_gpio of_get_gpio_flags of_get_named_gpio_flags
unflatten_dt_node device_type of_find_compatible_node of_device_is_compatible __of_device_is_compatible compat type name device_type __of_find_property of_prop_cmp np->properties of_prop_next_string of_compat_cmp strcasecmp ptr = of_get_property of_find_property ▻ if (ptr) value = be32_to_cpup(ptr); of_iomap of_address_to_resource of_get_address of_irq_to_resource irq_of_parse_and_map of_irq_map_one of_get_property ▻ irq_create_of_mapping irq_create_mapping irq_domain_associate irq_domain_associate_many DTC of_attach_node of_selftest device_node of_find_node_by_path allnodes of_selftest_parse_phandle_with_args of_selftest_property_match_string device_node dlpar_attach_node of_attach_node allnodes add_node_proc_entries proc_device_tree_add_node samples reg-init bcm87xx_of_reg_init of_get_property be32_to_cpup marvell_of_reg_init of_get_property be32_to_cpup i2c_new_client_device i2c_new_device i2c_bus_type i2c_device_match of_driver_match_device of_match_device ▻ of_match_table acpi_driver_match_device i2c_match_id platform_bus_init platform_bus_type platform_match of_driver_match_device of_match_device of_match_node __of_match_node __of_device_is_compatible of_compat_cmp strcasecmp CONFIG_PM dev_pm_ops platform_legacy_suspend platform_pm_suspend serial8250_suspend
of_device_id
PRCM Power Reset and Clock Management
PCS = Pinctrl Single pcs_probe devm_request_mem_region pcs_allocate_pin_table pcs_add_pin pcs_add_pin devm_ioremap ▻ pinctrl_register
pinctrl CONFIG_PINCTRL mount null -t debugfs /sys/kernel/debug/ head /sys/kernel/debug/pinctrl/* pinctrl_init pinctrl_init_debugfs pinctrl_ops (static var) pinctrl_open single_open seq_open pinctrl_show pinctrl_list pinctrl_register pinctrl_desc pinctrl_pin_desc PINCTRL_PIN pinctrl_ops (struct) pinmux_ops pinconf_ops
pinctrl_request_gpio <- at91_gpio_request, tegra_gpio_request pinctrl_get_device_gpio_range pinctrl_match_gpio_range pinmux_request_gpio pin_request pin_desc_get devm_pinctrl_get_select_default API device ▻ pinctrl device PINCTRL_STATE_DEFAULT PTR_ERR(dev->pins) == -EPROBE_DEFER is called from pinctrl serial_omap_probe omap2_mcspi_probe omap_hsmmc_probe omap_i2c_probe pinctrl devm_pinctrl_get_select devm_pinctrl_get devres_alloc pinctrl_get pinctrl_get_locked find_pinctrl pinctrl_list device ▻ pinctrl create_pinctrl pinctrl_dt_to_map for_each_maps pinctrl_maps if (strcmp(map->dev_name, devname)) add_setting pinctrl_list pinctrl_lookup_state pinctrl_lookup_state_locked find_state &p->states create_state pinctrl_select_state pinctrl_provide_dummies pinctrl_dummy_state = true
pinctrl_register_mappings pinctrl_register_map < nhk8815_platform_init < mop500_href_family_pinmaps_init < dt_remember_or_free_map pinctrl_maps pinctrl_map
samples
at91_pinctrl_probe at91_pinctrl_probe_dt of_match_device of_match_node __of_match_node __of_device_is_compatible ▻ at91_pinctrl_desc platform_set_drvdata ▻ pinctrl_register pinctrl_add_gpio_range pinctrl_gpio_range gpio_ranges irq_chip gpio_irqchip irq_set_chip_and_handler
at91_pinctrl_init drivers/pinctrl/pinctrl-at91.c at91_gpio_driver at91_gpio_probe at91_gpio_template : gpio_chip at91_gpio_set at91_gpio_request pinctrl_request_gpio ▻ gpiochip_add ▻ u300_pmx_init u300_pmx_probe pinctrl_register u300_pmx_desc pinctrl_add_gpio_range ▻ u300_gpio_ranges U300_GPIO_RANGE u300_init_machine pinctrl_map u300_pinmux_map PIN_MAP_CONFIGS_PIN pinctrl_register_mappings ▻
u300_gpio_init u300_gpio_probe drivers/pinctrl/pinctrl-coh901.c u300_gpio_chip : gpio_chip u300_gpio_request pinctrl_request_gpio ▻ gpiochip_add ▻
omap_gpio_drv_reg (init) omap_gpio_driver omap_gpio_probe omap_gpio_chip_init omap_gpio_request <- chip.request gpio_bank _set_gpio_triggering bank->base + bank->regs->pinctrl gpiochip_add ▻
serial_omap_init serial_omap_driver serial_omap_probe up->DTR_gpio = omap_up_info->DTR_gpio; gpio_request(omap_up_info->DTR_gpio, "omap-serial");
depends on SERIAL_8250=m CONFIG_SERIAL_8250=m serial8250_init ... serial8250_isa_init_ports serial8250_pops serial8250_config_port autoconfig serial8250_startup up->ier = UART_IER_RLSI | UART_IER_RDI; serial_port_out(port, UART_IER, up->ier);
serial_link_irq_chain serial8250_interrupt serial8250_rx_chars serial8250_start_tx serial8250_tx_chars size_fifo serial_out io_serial_out serial_in io_serial_in serial8250_suspend stty tty_mode_ioctl TCGETS set_termios tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); tty_set_termios set_termios ? uart_set_termios serial8250_set_termios serial8250_do_set_termios uart_get_baud_rate tty_termios_baud_rate tty_termios_encode_baud_rate
hid_init ret = bus_register(&hid_bus_type); hidraw_init
hidg_touchscreen_dev_data
// HID_MAIN_ITEM_TAG_END_COLLECTION hidg_dev_init platform_device_unregister(&hidg_dev) hidg_dev .name = "hidg", .dev.platform_data = &hidg_dev_data, hidg_func_descriptor
mknod /dev/hidg0 c 254 0 hid_gadget_test /dev/hidg0 keyboard hidg_init drivers/usb/gadget/hid.c platform_driver_probe(&hidg_plat_driver, hidg_plat_driver_probe); hidg_plat_driver_probe struct hidg_func_descriptor *func = pdev->dev.platform_data; list_add_tail(&entry->node, &hidg_func_list); usb_composite_register usb_gadget_register_driver drivers/usb/musb/musb_gadget.c ... bind composite_bind composite_unbind hid_bind ghid_setup usb_add_config(cdev, &config_driver); config_driver struct usb_device_descriptor device_desc do_config drivers/usb/gadget/hid.c hidg_bind_config drivers/usb/gadget/f_hid.c
hidg_desc : hid_descriptor .bInterfaceClass = USB_CLASS_HID, hidg->bInterfaceProtocol = fdesc->protocol; hidg->report_desc = kmemdup(fdesc->report_desc, status = usb_add_function(c, &hidg->func);
... hidg_bind hidg_fs_descriptors hidg_interface_desc : usb_interface_descriptor hidg_interface_desc.iInterface = status; hidg_hs_in_ep_desc hidg_hs_descriptors ghid_setup drivers/usb/gadget/f_hid.c usb_add_config
gpio_request gpio_request_one pca953x_probe gpiochip_add gpio_chip of_gpiochip_add gpiochip_export gpiochip_add_export_v2 alias_export_store gpio_map_name_to_num
iomem I/O Memory
/proc/iomem
./include/linux/ioport.h
check_mem_region request_mem_region __request_region release_mem_region
./kernel/resource.c
resource ioresources_init proc_ioports_operations ioport_resource /proc/ioports proc_iomem_operations iomem_resource /proc/iomem ioremap __arm_ioremap arch_ioremap_caller __arm_ioremap_caller __arm_ioremap_pfn_caller !CONFIG_MMU return (void __iomem*) (unsigned long)offset;
? __ioremap __pgprot ioremap_page_range pgd_addr_end ioremap_pud_range pud_alloc pud_addr_end ioremap_pmd_range ioremap_pte_range set_pte_at __ioremap get_vm_area __get_vm_area remap_area_pages pmd_alloc __pmd_alloc pgd_present pmd_offset remap_area_pmd pte_alloc_kernel remap_area_pte set_pte flush_cache_vmap x86? ioremap_nocache __ioremap_caller ioremap_page_range ▻
I/O Ports
/proc/ioports
depricated check_region
request_region __request_region kernel/resource.c __request_resource release_region
resource_op
void release_region(unsigned long start, unsigned long len); resource
linux/ioport.h
kernel/resource.c
==> ./oo/comm/reg/notes.txt <== Chapter 8 Hardware Management I/O Ports I/O Memory /proc/ioports
spi_register_board_info spi_board_info spi_match_master_to_boardinfo spi_new_device spi_alloc_device spi_add_device
API SPI_IOC_MESSAGE spi_ioc_transfer spi_dev_init spidev_fops spidev_open spi_dev_get_by_minor spi_dev_array spi_get_adapter adapters filp->private_data = spidev; spidev_write ( file ) spi_write ( spi_client ) spi_transfer ( spi_adapter ) -> spi_davinci_xfer ( spi_adapter ) spidev_ioctl ▻
spi_client -> spi_adapter spi_algorithm spi_davinci_device spi_adapter -> davinci_spi_algo spi_davinci_xfer spi_davinci_readbytes spi_davinci_cmd_complete davinci_spiConfig spi_davinci_sendbytes spiregs SPIDAT0 SPIDAT1 -> spi_davinci_hw_init
spi_davinci_init spi_davinci_saved_oadap : spi_davinci_device spi_davinci_dev->regs = (spiregsovly)DAVINCI_SPI_BASE_ADDR; if (spi_add_adapter(adap) < 0)
spidev_ioctl SPI_IOCTL_SET_CONFIG spi_control algo_control spi_davinci_control SPI_IOCTL_SET_CONFIG spi_davinci_hw_init spi_davinci_hwConfig spidev_message spidev_sync spi_async __spi_async
common i2c_client i2c_master_send
i2c_add_driver i2c_driver
i2c-davinci i2c-davinci.c i2c_davinci_isr icdrr
i2cdev_write i2c_master_send i2cdev_read i2c_master_recv i2cdev_ioctl i2c-dev.c I2C_SLAVE client->addr = arg; i2c_transfer I2C_RDWR I2C_SMBUS i2c_smbus_xfer
i2c_smbus_read_byte_data i2c_smbus_xfer smbus_xfer i2c_smbus_xfer_emulated
pcf_work
i2c-core.c i2c_transfer master_xfer i2c_davinci_xfer i2c_davinci_xfer_msg davinci_i2cregs i2c_master_send master_xfer i2c_master_recv I2C_M_RD master_xfer
i2c_adapter i2c_davinci_device davinci_i2cregsovly davinci_i2cregs
i2c_davinci_init i2c_davinci_dev.regs = (davinci_i2cregsovly)I2C_BASE; IO_ADDRESS(DAVINCI_I2C_BASE) DAVINCI_I2C_BASE (0x01C21000) io_p2v(pa) (((pa) & (IO_SIZE-1)) + IO_VIRT) #define IO_PHYS 0x01c00000 #define IO_VIRT 0xe1000000 #define IO_SIZE 0x00400000
module_usb_driver usb_register usb_register_driver libusb http://www.libusb.org/ http://libusb.sourceforge.net/api-1.0/index.html /mnt/1TB/main/tests/iboard/usbtouch-irq.c libusb_open_device_with_vid_pid ehci_hcd ehci_hcd_init PLATFORM_DRIVER ehci_hcd_omap_driver ehci_hcd_omap_probe regulator_get _regulator_get create_regulator usb_create_hcd ehci_omap_hc_driver usb_add_hcd ▻ ehci_pci_driver usb_hcd_pci_probe ▻ ehci_pci_hc_driver urb_enqueue ehci_urb_enqueue irq ehci_irq ohci_hcd ohci_hcd_pci_init pci_register_driver ohci_pci_driver pci_driver ohci_pci_hc_driver ohci_irq urb_enqueue ohci_urb_enqueue usb_hcd_pci_probe dev->irq pci_enable_device ▻ ... pirq_enable_irq usb_create_hcd usb_bus_init pci_resource_start (dev, 0); pci_resource_len (dev, 0); request_mem_region pci_set_master pcibios_set_master usb_add_hcd usb_register_bus usb_host_class class_device_create ▻ usb_alloc_dev usb_hcd.usb_bus usb_hcd_irq hcd->driver->irq hc_driver irq ohci_irq ohci_readl ohci_writel ehci_irq ▻ register_root_hub usb_hcd_request_irqs request_irq(irqnum, &usb_hcd_irq device_reprobe usb_hcd .usb_bus device *controller hc_driver generic usb_exit usb_init drivers/usb/core/usb.c bus_register subsystem_register bus_type ▻ usb_bus_type usb_device_match usb_hotplug usb_generic_suspend usb_generic_resume usb_register(&usbfs_driver); usb_register_driver driver_register ▻ usbdev_init register_chrdev_region(USB_DEVICE_DEV, USB_DEVICE_MAX, "usb_device"); cdev_init(&usb_device_cdev, &usbfs_device_file_operations); retval = cdev_add(&usb_device_cdev, USB_DEVICE_DEV, USB_DEVICE_MAX); usb_device_class = class_create(THIS_MODULE, "usb_device"); usb_register_notify blocking_notifier_chain_register(&usb_notifier_list, nb); notifier_chain_register rcu_assign_pointer ????
usbfs_init usb_fs_type usb_hub_init usb_register_device_driver(&usb_generic_driver, THIS_MODULE);
usb_driver probe usb_interface usbdrv_wrap usb_device_driver usbdrv_wrap device_driver
usb_bulk_msg usb_fill_bulk_urb usb_start_wait_urb
"send_packet" usb_submit_urb ▻ usb_fill_int_urb / usb_fill_bulk_urb wait_for_completion
irda_usb_open
kernel.lnk/build/drivers/usb/serial/ir-usb.c ir_init usb_serial_register ir_device : usb_serial_driver ir_write usb_serial_bus_register usb_register
usb_set_interface
checkintf claimintf usb_driver_claim_interface usbdev_release releaseintf usb_driver_release_interface
libusb_claim_interface op_claim_interface detach_kernel_driver_and_claim IOCTL_USBFS_DISCONNECT_CLAIM op_detach_kernel_driver IOCTL_USBFS_DISCONNECT claim_interface (kernel) proc_disconnect_claim claimintf claim_interface IOCTL_USBFS_CLAIMINTF
usb_reset_configuration usb_disable_endpoint usb_disable_device
hub_port_connect_change usb_new_device
usbfs_devices_fops usb_device_read usb_device_dump usb_dump_desc usb_dump_device_descriptor usb_dump_device_strings usb_dump_config usb_dump_config_descriptor usb_dump_interface usb_dump_endpoint_descriptor
mon_init debugfs_create_dir debugfs_create_file debugfs_create_by_name ... debugfs_remove mon_bus_init mon_fops_text mon_text_open rnf_complete = mon_text_complete; mon_reader_add usb_hcd_giveback_urb ehci_irq ehci_work scan_async qh_completions ? ehci_urb_done usb_hcd_giveback_urb hcd.c printk RCV usbmon_urb_complete ( mon_reader_add ) urb_complete mon_complete rnf_complete mon_text_event mon_text_get_setup mon_text_get_data usb_api_blocking_completion complete((struct completion *)urb->context); -> wait_for_completion usb_put_urb
ehci_urb_enqueue submit_async
usb_skel_init usb_register .skel_driver skel_probe usb_register_dev .skel_class skel_fops ▻ class_device_create ▻
skel_fops skel_open usb_find_interface __find_interface driver_for_each_device usb_autopm_get_interface pm_runtime_get_sync -> skel_write
usb_alloc_urb kmalloc usb_init_urb usb_fill_bulk_urb usb_submit_urb printk SBM usb_hcd_submit_urb hcd->driver->urb_enqueue { obsolete submit_urb hcd_submit_urb usbmon_urb_submit urb_enqueue uhci_urb_enqueue uhci_submit_control uhci_submit_interrupt uhci_submit_common uhci_append_queued_urb uhci_submit_bulk uhci_submit_common uhci_inc_fsbr hcd->driver->urb_enqueue } usbfs_nb
usbfs_add_bus create_special_files usbfs_devices_fops ▻
usb_reset_device hub_port_init usb_get_device_descriptor usb_get_descriptor usb_control_msg usb_internal_control_msg usb_fill_control_urb usb_start_wait_urb usb_submit_urb ▻ wait_for_completion ▻
uhci_hcd_init uhci_irq uhci_scan_schedule uhci_transfer_result uhci_result_control uhci_result_common uhci_finish_completion uhci_finish_urb uhci_destroy_urb_priv usb_hcd_giveback_urb ▻ usbdev_add class_device_create usb_device_class