diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-17 11:58:04 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-17 11:58:04 -0400 |
| commit | 57a8ec387e1441ea5e1232bc0749fb99a8cba7e7 (patch) | |
| tree | b5fb03fc6bc5754de8b5b1f8b0e4f36d67c8315c /scripts/gdb | |
| parent | 0a8ad0ffa4d80a544f6cbff703bf6394339afcdf (diff) | |
| parent | 43e11fa2d1d3b6e35629fa556eb7d571edba2010 (diff) | |
Merge branch 'akpm' (patches from Andrew)
Merge more updates from Andrew Morton:
"VM:
- z3fold fixes and enhancements by Henry Burns and Vitaly Wool
- more accurate reclaimed slab caches calculations by Yafang Shao
- fix MAP_UNINITIALIZED UAPI symbol to not depend on config, by
Christoph Hellwig
- !CONFIG_MMU fixes by Christoph Hellwig
- new novmcoredd parameter to omit device dumps from vmcore, by
Kairui Song
- new test_meminit module for testing heap and pagealloc
initialization, by Alexander Potapenko
- ioremap improvements for huge mappings, by Anshuman Khandual
- generalize kprobe page fault handling, by Anshuman Khandual
- device-dax hotplug fixes and improvements, by Pavel Tatashin
- enable synchronous DAX fault on powerpc, by Aneesh Kumar K.V
- add pte_devmap() support for arm64, by Robin Murphy
- unify locked_vm accounting with a helper, by Daniel Jordan
- several misc fixes
core/lib:
- new typeof_member() macro including some users, by Alexey Dobriyan
- make BIT() and GENMASK() available in asm, by Masahiro Yamada
- changed LIST_POISON2 on x86_64 to 0xdead000000000122 for better
code generation, by Alexey Dobriyan
- rbtree code size optimizations, by Michel Lespinasse
- convert struct pid count to refcount_t, by Joel Fernandes
get_maintainer.pl:
- add --no-moderated switch to skip moderated ML's, by Joe Perches
misc:
- ptrace PTRACE_GET_SYSCALL_INFO interface
- coda updates
- gdb scripts, various"
[ Using merge message suggestion from Vlastimil Babka, with some editing - Linus ]
* emailed patches from Andrew Morton <akpm@linux-foundation.org>: (100 commits)
fs/select.c: use struct_size() in kmalloc()
mm: add account_locked_vm utility function
arm64: mm: implement pte_devmap support
mm: introduce ARCH_HAS_PTE_DEVMAP
mm: clean up is_device_*_page() definitions
mm/mmap: move common defines to mman-common.h
mm: move MAP_SYNC to asm-generic/mman-common.h
device-dax: "Hotremove" persistent memory that is used like normal RAM
mm/hotplug: make remove_memory() interface usable
device-dax: fix memory and resource leak if hotplug fails
include/linux/lz4.h: fix spelling and copy-paste errors in documentation
ipc/mqueue.c: only perform resource calculation if user valid
include/asm-generic/bug.h: fix "cut here" for WARN_ON for __WARN_TAINT architectures
scripts/gdb: add helpers to find and list devices
scripts/gdb: add lx-genpd-summary command
drivers/pps/pps.c: clear offset flags in PPS_SETPARAMS ioctl
kernel/pid.c: convert struct pid count to refcount_t
drivers/rapidio/devices/rio_mport_cdev.c: NUL terminate some strings
select: shift restore_saved_sigmask_unless() into poll_select_copy_remaining()
select: change do_poll() to return -ERESTARTNOHAND rather than -EINTR
...
Diffstat (limited to 'scripts/gdb')
| -rw-r--r-- | scripts/gdb/linux/device.py | 182 | ||||
| -rw-r--r-- | scripts/gdb/linux/genpd.py | 83 | ||||
| -rw-r--r-- | scripts/gdb/vmlinux-gdb.py | 2 |
3 files changed, 267 insertions, 0 deletions
diff --git a/scripts/gdb/linux/device.py b/scripts/gdb/linux/device.py new file mode 100644 index 000000000000..16376c5cfec6 --- /dev/null +++ b/scripts/gdb/linux/device.py | |||
| @@ -0,0 +1,182 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | # | ||
| 3 | # Copyright (c) NXP 2019 | ||
| 4 | |||
| 5 | import gdb | ||
| 6 | |||
| 7 | from linux.utils import CachedType | ||
| 8 | from linux.utils import container_of | ||
| 9 | from linux.lists import list_for_each_entry | ||
| 10 | |||
| 11 | |||
| 12 | device_private_type = CachedType('struct device_private') | ||
| 13 | device_type = CachedType('struct device') | ||
| 14 | |||
| 15 | subsys_private_type = CachedType('struct subsys_private') | ||
| 16 | kobject_type = CachedType('struct kobject') | ||
| 17 | kset_type = CachedType('struct kset') | ||
| 18 | |||
| 19 | bus_type = CachedType('struct bus_type') | ||
| 20 | class_type = CachedType('struct class') | ||
| 21 | |||
| 22 | |||
| 23 | def dev_name(dev): | ||
| 24 | dev_init_name = dev['init_name'] | ||
| 25 | if dev_init_name: | ||
| 26 | return dev_init_name.string() | ||
| 27 | return dev['kobj']['name'].string() | ||
| 28 | |||
| 29 | |||
| 30 | def kset_for_each_object(kset): | ||
| 31 | return list_for_each_entry(kset['list'], | ||
| 32 | kobject_type.get_type().pointer(), "entry") | ||
| 33 | |||
| 34 | |||
| 35 | def for_each_bus(): | ||
| 36 | for kobj in kset_for_each_object(gdb.parse_and_eval('bus_kset')): | ||
| 37 | subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj') | ||
| 38 | subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys') | ||
| 39 | yield subsys_priv['bus'] | ||
| 40 | |||
| 41 | |||
| 42 | def for_each_class(): | ||
| 43 | for kobj in kset_for_each_object(gdb.parse_and_eval('class_kset')): | ||
| 44 | subsys = container_of(kobj, kset_type.get_type().pointer(), 'kobj') | ||
| 45 | subsys_priv = container_of(subsys, subsys_private_type.get_type().pointer(), 'subsys') | ||
| 46 | yield subsys_priv['class'] | ||
| 47 | |||
| 48 | |||
| 49 | def get_bus_by_name(name): | ||
| 50 | for item in for_each_bus(): | ||
| 51 | if item['name'].string() == name: | ||
| 52 | return item | ||
| 53 | raise gdb.GdbError("Can't find bus type {!r}".format(name)) | ||
| 54 | |||
| 55 | |||
| 56 | def get_class_by_name(name): | ||
| 57 | for item in for_each_class(): | ||
| 58 | if item['name'].string() == name: | ||
| 59 | return item | ||
| 60 | raise gdb.GdbError("Can't find device class {!r}".format(name)) | ||
| 61 | |||
| 62 | |||
| 63 | klist_type = CachedType('struct klist') | ||
| 64 | klist_node_type = CachedType('struct klist_node') | ||
| 65 | |||
| 66 | |||
| 67 | def klist_for_each(klist): | ||
| 68 | return list_for_each_entry(klist['k_list'], | ||
| 69 | klist_node_type.get_type().pointer(), 'n_node') | ||
| 70 | |||
| 71 | |||
| 72 | def bus_for_each_device(bus): | ||
| 73 | for kn in klist_for_each(bus['p']['klist_devices']): | ||
| 74 | dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_bus') | ||
| 75 | yield dp['device'] | ||
| 76 | |||
| 77 | |||
| 78 | def class_for_each_device(cls): | ||
| 79 | for kn in klist_for_each(cls['p']['klist_devices']): | ||
| 80 | dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_class') | ||
| 81 | yield dp['device'] | ||
| 82 | |||
| 83 | |||
| 84 | def device_for_each_child(dev): | ||
| 85 | for kn in klist_for_each(dev['p']['klist_children']): | ||
| 86 | dp = container_of(kn, device_private_type.get_type().pointer(), 'knode_parent') | ||
| 87 | yield dp['device'] | ||
| 88 | |||
| 89 | |||
| 90 | def _show_device(dev, level=0, recursive=False): | ||
| 91 | gdb.write('{}dev {}:\t{}\n'.format('\t' * level, dev_name(dev), dev)) | ||
| 92 | if recursive: | ||
| 93 | for child in device_for_each_child(dev): | ||
| 94 | _show_device(child, level + 1, recursive) | ||
| 95 | |||
| 96 | |||
| 97 | class LxDeviceListBus(gdb.Command): | ||
| 98 | '''Print devices on a bus (or all buses if not specified)''' | ||
| 99 | |||
| 100 | def __init__(self): | ||
| 101 | super(LxDeviceListBus, self).__init__('lx-device-list-bus', gdb.COMMAND_DATA) | ||
| 102 | |||
| 103 | def invoke(self, arg, from_tty): | ||
| 104 | if not arg: | ||
| 105 | for bus in for_each_bus(): | ||
| 106 | gdb.write('bus {}:\t{}\n'.format(bus['name'].string(), bus)) | ||
| 107 | for dev in bus_for_each_device(bus): | ||
| 108 | _show_device(dev, level=1) | ||
| 109 | else: | ||
| 110 | bus = get_bus_by_name(arg) | ||
| 111 | if not bus: | ||
| 112 | raise gdb.GdbError("Can't find bus {!r}".format(arg)) | ||
| 113 | for dev in bus_for_each_device(bus): | ||
| 114 | _show_device(dev) | ||
| 115 | |||
| 116 | |||
| 117 | class LxDeviceListClass(gdb.Command): | ||
| 118 | '''Print devices in a class (or all classes if not specified)''' | ||
| 119 | |||
| 120 | def __init__(self): | ||
| 121 | super(LxDeviceListClass, self).__init__('lx-device-list-class', gdb.COMMAND_DATA) | ||
| 122 | |||
| 123 | def invoke(self, arg, from_tty): | ||
| 124 | if not arg: | ||
| 125 | for cls in for_each_class(): | ||
| 126 | gdb.write("class {}:\t{}\n".format(cls['name'].string(), cls)) | ||
| 127 | for dev in class_for_each_device(cls): | ||
| 128 | _show_device(dev, level=1) | ||
| 129 | else: | ||
| 130 | cls = get_class_by_name(arg) | ||
| 131 | for dev in class_for_each_device(cls): | ||
| 132 | _show_device(dev) | ||
| 133 | |||
| 134 | |||
| 135 | class LxDeviceListTree(gdb.Command): | ||
| 136 | '''Print a device and its children recursively''' | ||
| 137 | |||
| 138 | def __init__(self): | ||
| 139 | super(LxDeviceListTree, self).__init__('lx-device-list-tree', gdb.COMMAND_DATA) | ||
| 140 | |||
| 141 | def invoke(self, arg, from_tty): | ||
| 142 | if not arg: | ||
| 143 | raise gdb.GdbError('Please provide pointer to struct device') | ||
| 144 | dev = gdb.parse_and_eval(arg) | ||
| 145 | if dev.type != device_type.get_type().pointer(): | ||
| 146 | raise gdb.GdbError('Please provide pointer to struct device') | ||
| 147 | _show_device(dev, level=0, recursive=True) | ||
| 148 | |||
| 149 | |||
| 150 | class LxDeviceFindByBusName(gdb.Function): | ||
| 151 | '''Find struct device by bus and name (both strings)''' | ||
| 152 | |||
| 153 | def __init__(self): | ||
| 154 | super(LxDeviceFindByBusName, self).__init__('lx_device_find_by_bus_name') | ||
| 155 | |||
| 156 | def invoke(self, bus, name): | ||
| 157 | name = name.string() | ||
| 158 | bus = get_bus_by_name(bus.string()) | ||
| 159 | for dev in bus_for_each_device(bus): | ||
| 160 | if dev_name(dev) == name: | ||
| 161 | return dev | ||
| 162 | |||
| 163 | |||
| 164 | class LxDeviceFindByClassName(gdb.Function): | ||
| 165 | '''Find struct device by class and name (both strings)''' | ||
| 166 | |||
| 167 | def __init__(self): | ||
| 168 | super(LxDeviceFindByClassName, self).__init__('lx_device_find_by_class_name') | ||
| 169 | |||
| 170 | def invoke(self, cls, name): | ||
| 171 | name = name.string() | ||
| 172 | cls = get_class_by_name(cls.string()) | ||
| 173 | for dev in class_for_each_device(cls): | ||
| 174 | if dev_name(dev) == name: | ||
| 175 | return dev | ||
| 176 | |||
| 177 | |||
| 178 | LxDeviceListBus() | ||
| 179 | LxDeviceListClass() | ||
| 180 | LxDeviceListTree() | ||
| 181 | LxDeviceFindByBusName() | ||
| 182 | LxDeviceFindByClassName() | ||
diff --git a/scripts/gdb/linux/genpd.py b/scripts/gdb/linux/genpd.py new file mode 100644 index 000000000000..6ca93bd2949e --- /dev/null +++ b/scripts/gdb/linux/genpd.py | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | ||
| 2 | # | ||
| 3 | # Copyright (c) NXP 2019 | ||
| 4 | |||
| 5 | import gdb | ||
| 6 | import sys | ||
| 7 | |||
| 8 | from linux.utils import CachedType | ||
| 9 | from linux.lists import list_for_each_entry | ||
| 10 | |||
| 11 | generic_pm_domain_type = CachedType('struct generic_pm_domain') | ||
| 12 | pm_domain_data_type = CachedType('struct pm_domain_data') | ||
| 13 | device_link_type = CachedType('struct device_link') | ||
| 14 | |||
| 15 | |||
| 16 | def kobject_get_path(kobj): | ||
| 17 | path = kobj['name'].string() | ||
| 18 | parent = kobj['parent'] | ||
| 19 | if parent: | ||
| 20 | path = kobject_get_path(parent) + '/' + path | ||
| 21 | return path | ||
| 22 | |||
| 23 | |||
| 24 | def rtpm_status_str(dev): | ||
| 25 | if dev['power']['runtime_error']: | ||
| 26 | return 'error' | ||
| 27 | if dev['power']['disable_depth']: | ||
| 28 | return 'unsupported' | ||
| 29 | _RPM_STATUS_LOOKUP = [ | ||
| 30 | "active", | ||
| 31 | "resuming", | ||
| 32 | "suspended", | ||
| 33 | "suspending" | ||
| 34 | ] | ||
| 35 | return _RPM_STATUS_LOOKUP[dev['power']['runtime_status']] | ||
| 36 | |||
| 37 | |||
| 38 | class LxGenPDSummary(gdb.Command): | ||
| 39 | '''Print genpd summary | ||
| 40 | |||
| 41 | Output is similar to /sys/kernel/debug/pm_genpd/pm_genpd_summary''' | ||
| 42 | |||
| 43 | def __init__(self): | ||
| 44 | super(LxGenPDSummary, self).__init__('lx-genpd-summary', gdb.COMMAND_DATA) | ||
| 45 | |||
| 46 | def summary_one(self, genpd): | ||
| 47 | if genpd['status'] == 0: | ||
| 48 | status_string = 'on' | ||
| 49 | else: | ||
| 50 | status_string = 'off-{}'.format(genpd['state_idx']) | ||
| 51 | |||
| 52 | slave_names = [] | ||
| 53 | for link in list_for_each_entry( | ||
| 54 | genpd['master_links'], | ||
| 55 | device_link_type.get_type().pointer(), | ||
| 56 | 'master_node'): | ||
| 57 | slave_names.apend(link['slave']['name']) | ||
| 58 | |||
| 59 | gdb.write('%-30s %-15s %s\n' % ( | ||
| 60 | genpd['name'].string(), | ||
| 61 | status_string, | ||
| 62 | ', '.join(slave_names))) | ||
| 63 | |||
| 64 | # Print devices in domain | ||
| 65 | for pm_data in list_for_each_entry(genpd['dev_list'], | ||
| 66 | pm_domain_data_type.get_type().pointer(), | ||
| 67 | 'list_node'): | ||
| 68 | dev = pm_data['dev'] | ||
| 69 | kobj_path = kobject_get_path(dev['kobj']) | ||
| 70 | gdb.write(' %-50s %s\n' % (kobj_path, rtpm_status_str(dev))) | ||
| 71 | |||
| 72 | def invoke(self, arg, from_tty): | ||
| 73 | gdb.write('domain status slaves\n'); | ||
| 74 | gdb.write(' /device runtime status\n'); | ||
| 75 | gdb.write('----------------------------------------------------------------------\n'); | ||
| 76 | for genpd in list_for_each_entry( | ||
| 77 | gdb.parse_and_eval('&gpd_list'), | ||
| 78 | generic_pm_domain_type.get_type().pointer(), | ||
| 79 | 'gpd_list_node'): | ||
| 80 | self.summary_one(genpd) | ||
| 81 | |||
| 82 | |||
| 83 | LxGenPDSummary() | ||
diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index eff5a48ac026..4136dc2c59df 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py | |||
| @@ -35,3 +35,5 @@ else: | |||
| 35 | import linux.constants | 35 | import linux.constants |
| 36 | import linux.timerlist | 36 | import linux.timerlist |
| 37 | import linux.clk | 37 | import linux.clk |
| 38 | import linux.genpd | ||
| 39 | import linux.device | ||
