From d950fcd31c4092ce74f8219b8a1d9e17546bbc45 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Fri, 17 Aug 2012 14:44:09 +0800 Subject: [PATCH] --- yaml --- r: 331747 b: refs/heads/master c: 1033f9041d526dd694e2b2e12744e47c41040c4d h: refs/heads/master i: 331745: 3da8dcb5b3b1b2dec591ec5eb8e7cd8be9dcf6e4 331743: b7a6f8b5958292f83dce985499b0d3d6fa5afba4 v: v3 --- [refs] | 2 +- trunk/drivers/acpi/glue.c | 135 +++++++----- trunk/drivers/acpi/proc.c | 57 ++++-- trunk/drivers/acpi/scan.c | 2 + trunk/drivers/pnp/pnpacpi/core.c | 7 +- trunk/include/acpi/acpi_bus.h | 15 +- trunk/tools/power/x86/turbostat/turbostat.8 | 55 +---- trunk/tools/power/x86/turbostat/turbostat.c | 214 +++----------------- 8 files changed, 176 insertions(+), 311 deletions(-) diff --git a/[refs] b/[refs] index fb9128458bcb..6c2d76f099cc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f9240813e61cb3e5838c9ab0237af831c61df7cf +refs/heads/master: 1033f9041d526dd694e2b2e12744e47c41040c4d diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 243ee85e4d2e..d1a2d74033e9 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -25,6 +25,8 @@ static LIST_HEAD(bus_type_list); static DECLARE_RWSEM(bus_type_sem); +#define PHYSICAL_NODE_STRING "physical_node" + int register_acpi_bus_type(struct acpi_bus_type *type) { if (acpi_disabled) @@ -124,84 +126,119 @@ acpi_handle acpi_get_child(acpi_handle parent, u64 address) EXPORT_SYMBOL(acpi_get_child); -/* Link ACPI devices with physical devices */ -static void acpi_glue_data_handler(acpi_handle handle, - void *context) -{ - /* we provide an empty handler */ -} - -/* Note: a success call will increase reference count by one */ -struct device *acpi_get_physical_device(acpi_handle handle) -{ - acpi_status status; - struct device *dev; - - status = acpi_get_data(handle, acpi_glue_data_handler, (void **)&dev); - if (ACPI_SUCCESS(status)) - return get_device(dev); - return NULL; -} - -EXPORT_SYMBOL(acpi_get_physical_device); - static int acpi_bind_one(struct device *dev, acpi_handle handle) { struct acpi_device *acpi_dev; acpi_status status; + struct acpi_device_physical_node *physical_node; + char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; + int retval = -EINVAL; if (dev->archdata.acpi_handle) { dev_warn(dev, "Drivers changed 'acpi_handle'\n"); return -EINVAL; } + get_device(dev); - status = acpi_attach_data(handle, acpi_glue_data_handler, dev); - if (ACPI_FAILURE(status)) { - put_device(dev); - return -EINVAL; + status = acpi_bus_get_device(handle, &acpi_dev); + if (ACPI_FAILURE(status)) + goto err; + + physical_node = kzalloc(sizeof(struct acpi_device_physical_node), + GFP_KERNEL); + if (!physical_node) { + retval = -ENOMEM; + goto err; } - dev->archdata.acpi_handle = handle; - status = acpi_bus_get_device(handle, &acpi_dev); - if (!ACPI_FAILURE(status)) { - int ret; - - ret = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, - "firmware_node"); - ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, - "physical_node"); - if (acpi_dev->wakeup.flags.valid) - device_set_wakeup_capable(dev, true); + mutex_lock(&acpi_dev->physical_node_lock); + /* allocate physical node id according to physical_node_id_bitmap */ + physical_node->node_id = + find_first_zero_bit(acpi_dev->physical_node_id_bitmap, + ACPI_MAX_PHYSICAL_NODE); + if (physical_node->node_id >= ACPI_MAX_PHYSICAL_NODE) { + retval = -ENOSPC; + mutex_unlock(&acpi_dev->physical_node_lock); + goto err; } + set_bit(physical_node->node_id, acpi_dev->physical_node_id_bitmap); + physical_node->dev = dev; + list_add_tail(&physical_node->node, &acpi_dev->physical_node_list); + acpi_dev->physical_node_count++; + mutex_unlock(&acpi_dev->physical_node_lock); + + dev->archdata.acpi_handle = handle; + + if (!physical_node->node_id) + strcpy(physical_node_name, PHYSICAL_NODE_STRING); + else + sprintf(physical_node_name, + "physical_node%d", physical_node->node_id); + retval = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, + physical_node_name); + retval = sysfs_create_link(&dev->kobj, &acpi_dev->dev.kobj, + "firmware_node"); + + if (acpi_dev->wakeup.flags.valid) + device_set_wakeup_capable(dev, true); + return 0; + + err: + put_device(dev); + return retval; } static int acpi_unbind_one(struct device *dev) { + struct acpi_device_physical_node *entry; + struct acpi_device *acpi_dev; + acpi_status status; + struct list_head *node, *next; + if (!dev->archdata.acpi_handle) return 0; - if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { - struct acpi_device *acpi_dev; - /* acpi_get_physical_device increase refcnt by one */ - put_device(dev); + status = acpi_bus_get_device(dev->archdata.acpi_handle, + &acpi_dev); + if (ACPI_FAILURE(status)) + goto err; - if (!acpi_bus_get_device(dev->archdata.acpi_handle, - &acpi_dev)) { - sysfs_remove_link(&dev->kobj, "firmware_node"); - sysfs_remove_link(&acpi_dev->dev.kobj, "physical_node"); - } + mutex_lock(&acpi_dev->physical_node_lock); + list_for_each_safe(node, next, &acpi_dev->physical_node_list) { + char physical_node_name[sizeof(PHYSICAL_NODE_STRING) + 2]; + + entry = list_entry(node, struct acpi_device_physical_node, + node); + if (entry->dev != dev) + continue; + + list_del(node); + clear_bit(entry->node_id, acpi_dev->physical_node_id_bitmap); - acpi_detach_data(dev->archdata.acpi_handle, - acpi_glue_data_handler); + acpi_dev->physical_node_count--; + + if (!entry->node_id) + strcpy(physical_node_name, PHYSICAL_NODE_STRING); + else + sprintf(physical_node_name, + "physical_node%d", entry->node_id); + + sysfs_remove_link(&acpi_dev->dev.kobj, physical_node_name); + sysfs_remove_link(&dev->kobj, "firmware_node"); dev->archdata.acpi_handle = NULL; /* acpi_bind_one increase refcnt by one */ put_device(dev); - } else { - dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); + kfree(entry); } + mutex_unlock(&acpi_dev->physical_node_lock); + return 0; + +err: + dev_err(dev, "Oops, 'acpi_handle' corrupt\n"); + return -EINVAL; } static int acpi_platform_notify(struct device *dev) diff --git a/trunk/drivers/acpi/proc.c b/trunk/drivers/acpi/proc.c index 251c7b6273a9..27adb090bb30 100644 --- a/trunk/drivers/acpi/proc.c +++ b/trunk/drivers/acpi/proc.c @@ -302,26 +302,41 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) list_for_each_safe(node, next, &acpi_wakeup_device_list) { struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - struct device *ldev; + struct acpi_device_physical_node *entry; if (!dev->wakeup.flags.valid) continue; - ldev = acpi_get_physical_device(dev->handle); - seq_printf(seq, "%s\t S%d\t%c%-8s ", + seq_printf(seq, "%s\t S%d\t", dev->pnp.bus_id, - (u32) dev->wakeup.sleep_state, - dev->wakeup.flags.run_wake ? '*' : ' ', - (device_may_wakeup(&dev->dev) - || (ldev && device_may_wakeup(ldev))) ? - "enabled" : "disabled"); - if (ldev) - seq_printf(seq, "%s:%s", - ldev->bus ? ldev->bus->name : "no-bus", - dev_name(ldev)); - seq_printf(seq, "\n"); - put_device(ldev); - + (u32) dev->wakeup.sleep_state); + + if (!dev->physical_node_count) + seq_printf(seq, "%c%-8s\n", + dev->wakeup.flags.run_wake ? + '*' : ' ', "disabled"); + else { + struct device *ldev; + list_for_each_entry(entry, &dev->physical_node_list, + node) { + ldev = get_device(entry->dev); + if (!ldev) + continue; + + if (&entry->node != + dev->physical_node_list.next) + seq_printf(seq, "\t\t"); + + seq_printf(seq, "%c%-8s %s:%s\n", + dev->wakeup.flags.run_wake ? '*' : ' ', + (device_may_wakeup(&dev->dev) || + (ldev && device_may_wakeup(ldev))) ? + "enabled" : "disabled", + ldev->bus ? ldev->bus->name : + "no-bus", dev_name(ldev)); + put_device(ldev); + } + } } mutex_unlock(&acpi_device_lock); return 0; @@ -329,12 +344,14 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) static void physical_device_enable_wakeup(struct acpi_device *adev) { - struct device *dev = acpi_get_physical_device(adev->handle); + struct acpi_device_physical_node *entry; - if (dev && device_can_wakeup(dev)) { - bool enable = !device_may_wakeup(dev); - device_set_wakeup_enable(dev, enable); - } + list_for_each_entry(entry, + &adev->physical_node_list, node) + if (entry->dev && device_can_wakeup(entry->dev)) { + bool enable = !device_may_wakeup(entry->dev); + device_set_wakeup_enable(entry->dev, enable); + } } static ssize_t diff --git a/trunk/drivers/acpi/scan.c b/trunk/drivers/acpi/scan.c index d1ecca2b641a..d730a939ead1 100644 --- a/trunk/drivers/acpi/scan.c +++ b/trunk/drivers/acpi/scan.c @@ -481,6 +481,8 @@ static int acpi_device_register(struct acpi_device *device) INIT_LIST_HEAD(&device->children); INIT_LIST_HEAD(&device->node); INIT_LIST_HEAD(&device->wakeup_list); + INIT_LIST_HEAD(&device->physical_node_list); + mutex_init(&device->physical_node_lock); new_bus_id = kzalloc(sizeof(struct acpi_device_bus_id), GFP_KERNEL); if (!new_bus_id) { diff --git a/trunk/drivers/pnp/pnpacpi/core.c b/trunk/drivers/pnp/pnpacpi/core.c index 507a8e2b9a4c..26b5d4b18dd7 100644 --- a/trunk/drivers/pnp/pnpacpi/core.c +++ b/trunk/drivers/pnp/pnpacpi/core.c @@ -321,14 +321,9 @@ static int __init acpi_pnp_match(struct device *dev, void *_pnp) { struct acpi_device *acpi = to_acpi_device(dev); struct pnp_dev *pnp = _pnp; - struct device *physical_device; - - physical_device = acpi_get_physical_device(acpi->handle); - if (physical_device) - put_device(physical_device); /* true means it matched */ - return !physical_device + return !acpi->physical_node_count && compare_pnp_id(pnp->id, acpi_device_hid(acpi)); } diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index bde976ee068d..453596d4ce65 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -282,8 +282,16 @@ struct acpi_device_wakeup { int prepare_count; }; -/* Device */ +struct acpi_device_physical_node { + u8 node_id; + struct list_head node; + struct device *dev; +}; +/* set maximum of physical nodes to 32 for expansibility */ +#define ACPI_MAX_PHYSICAL_NODE 32 + +/* Device */ struct acpi_device { int device_type; acpi_handle handle; /* no handle for fixed hardware */ @@ -304,6 +312,10 @@ struct acpi_device { struct device dev; struct acpi_bus_ops bus_ops; /* workaround for different code path for hotplug */ enum acpi_bus_removal_type removal_type; /* indicate for different removal type */ + u8 physical_node_count; + struct list_head physical_node_list; + struct mutex physical_node_lock; + DECLARE_BITMAP(physical_node_id_bitmap, ACPI_MAX_PHYSICAL_NODE); }; static inline void *acpi_driver_data(struct acpi_device *d) @@ -394,7 +406,6 @@ struct acpi_bus_type { }; int register_acpi_bus_type(struct acpi_bus_type *); int unregister_acpi_bus_type(struct acpi_bus_type *); -struct device *acpi_get_physical_device(acpi_handle); struct acpi_pci_root { struct list_head node; diff --git a/trunk/tools/power/x86/turbostat/turbostat.8 b/trunk/tools/power/x86/turbostat/turbostat.8 index e4d0690cccf9..74e44507dfe9 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.8 +++ b/trunk/tools/power/x86/turbostat/turbostat.8 @@ -4,11 +4,15 @@ turbostat \- Report processor frequency and idle statistics .SH SYNOPSIS .ft B .B turbostat -.RB [ Options ] +.RB [ "\-s" ] +.RB [ "\-v" ] +.RB [ "\-M MSR#" ] .RB command .br .B turbostat -.RB [ Options ] +.RB [ "\-s" ] +.RB [ "\-v" ] +.RB [ "\-M MSR#" ] .RB [ "\-i interval_sec" ] .SH DESCRIPTION \fBturbostat \fP reports processor topology, frequency @@ -23,23 +27,16 @@ supports an "invariant" TSC, plus the APERF and MPERF MSRs. on processors that additionally support C-state residency counters. .SS Options -The \fB-p\fP option limits output to the 1st thread in 1st core of each package. +The \fB-s\fP option limits output to a 1-line system summary for each interval. .PP -The \fB-P\fP option limits output to the 1st thread in each Package. +The \fB-c\fP option limits output to the 1st thread in each core. .PP -The \fB-S\fP option limits output to a 1-line System Summary for each interval. +The \fB-p\fP option limits output to the 1st thread in each package. .PP The \fB-v\fP option increases verbosity. .PP -The \fB-s\fP option prints the SMI counter, equivalent to "-c 0x34" -.PP -The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter. -.PP -The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter. -.PP -The \fB-m MSR#\fP option includes the the specified 32-bit MSR value. -.PP -The \fB-M MSR#\fP option includes the the specified 64-bit MSR value. +The \fB-M MSR#\fP option dumps the specified MSR, +in addition to the usual frequency and idle statistics. .PP The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds. The default is 5 seconds. @@ -153,29 +150,6 @@ Note that turbostat reports average GHz of 3.63, while the arithmetic average of the GHz column above is lower. This is a weighted average, where the weight is %c0. ie. it is the total number of un-halted cycles elapsed per time divided by the number of CPUs. -.SH SMI COUNTING EXAMPLE -On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter. -Using the -m option, you can display how many SMIs have fired since reset, or if there -are SMIs during the measurement interval, you can display the delta using the -d option. -.nf -[root@x980 ~]# turbostat -m 0x34 -cor CPU %c0 GHz TSC MSR 0x034 %c1 %c3 %c6 %pc3 %pc6 - 1.41 1.82 3.38 0x00000000 8.92 37.82 51.85 17.37 0.55 - 0 0 3.73 2.03 3.38 0x00000055 1.72 48.25 46.31 17.38 0.55 - 0 6 0.14 1.63 3.38 0x00000056 5.30 - 1 2 2.51 1.80 3.38 0x00000056 15.65 29.33 52.52 - 1 8 0.10 1.65 3.38 0x00000056 18.05 - 2 4 1.16 1.68 3.38 0x00000056 5.87 24.47 68.50 - 2 10 0.10 1.63 3.38 0x00000056 6.93 - 8 1 3.84 1.91 3.38 0x00000056 1.36 50.65 44.16 - 8 7 0.08 1.64 3.38 0x00000056 5.12 - 9 3 1.82 1.73 3.38 0x00000056 7.59 24.21 66.38 - 9 9 0.09 1.68 3.38 0x00000056 9.32 - 10 5 1.66 1.65 3.38 0x00000056 15.10 50.00 33.23 - 10 11 1.72 1.65 3.38 0x00000056 15.05 -^C -[root@x980 ~]# -.fi .SH NOTES .B "turbostat " @@ -191,13 +165,6 @@ may work poorly on Linux-2.6.20 through 2.6.29, as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF in those kernels. -If the TSC column does not make sense, then -the other numbers will also make no sense. -Turbostat is lightweight, and its data collection is not atomic. -These issues are usually caused by an extremely short measurement -interval (much less than 1 second), or system activity that prevents -turbostat from being able to run on all CPUS to quickly collect data. - The APERF, MPERF MSRs are defined to count non-halted cycles. Although it is not guaranteed by the architecture, turbostat assumes that they count at TSC rate, which is true on all processors tested to date. diff --git a/trunk/tools/power/x86/turbostat/turbostat.c b/trunk/tools/power/x86/turbostat/turbostat.c index 2655ae9a3ad8..861d77190206 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.c +++ b/trunk/tools/power/x86/turbostat/turbostat.c @@ -35,9 +35,9 @@ #include #include +#define MSR_TSC 0x10 #define MSR_NEHALEM_PLATFORM_INFO 0xCE #define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1AD -#define MSR_IVT_TURBO_RATIO_LIMIT 0x1AE #define MSR_APERF 0xE8 #define MSR_MPERF 0xE7 #define MSR_PKG_C2_RESIDENCY 0x60D /* SNB only */ @@ -62,11 +62,7 @@ unsigned int genuine_intel; unsigned int has_invariant_tsc; unsigned int do_nehalem_platform_info; unsigned int do_nehalem_turbo_ratio_limit; -unsigned int do_ivt_turbo_ratio_limit; -unsigned int extra_msr_offset32; -unsigned int extra_msr_offset64; -unsigned int extra_delta_offset32; -unsigned int extra_delta_offset64; +unsigned int extra_msr_offset; double bclk; unsigned int show_pkg; unsigned int show_core; @@ -87,10 +83,7 @@ struct thread_data { unsigned long long aperf; unsigned long long mperf; unsigned long long c1; /* derived */ - unsigned long long extra_msr64; - unsigned long long extra_delta64; - unsigned long long extra_msr32; - unsigned long long extra_delta32; + unsigned long long extra_msr; unsigned int cpu_id; unsigned int flags; #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 @@ -229,14 +222,6 @@ void print_header(void) if (has_aperf) outp += sprintf(outp, " GHz"); outp += sprintf(outp, " TSC"); - if (extra_delta_offset32) - outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); - if (extra_delta_offset64) - outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64); - if (extra_msr_offset32) - outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32); - if (extra_msr_offset64) - outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); if (do_nhm_cstates) outp += sprintf(outp, " %%c1"); if (do_nhm_cstates) @@ -253,6 +238,8 @@ void print_header(void) outp += sprintf(outp, " %%pc6"); if (do_snb_cstates) outp += sprintf(outp, " %%pc7"); + if (extra_msr_offset) + outp += sprintf(outp, " MSR 0x%x ", extra_msr_offset); outp += sprintf(outp, "\n"); } @@ -268,14 +255,8 @@ int dump_counters(struct thread_data *t, struct core_data *c, fprintf(stderr, "aperf: %016llX\n", t->aperf); fprintf(stderr, "mperf: %016llX\n", t->mperf); fprintf(stderr, "c1: %016llX\n", t->c1); - fprintf(stderr, "msr0x%x: %08llX\n", - extra_delta_offset32, t->extra_delta32); fprintf(stderr, "msr0x%x: %016llX\n", - extra_delta_offset64, t->extra_delta64); - fprintf(stderr, "msr0x%x: %08llX\n", - extra_msr_offset32, t->extra_msr32); - fprintf(stderr, "msr0x%x: %016llX\n", - extra_msr_offset64, t->extra_msr64); + extra_msr_offset, t->extra_msr); } if (c) { @@ -379,21 +360,6 @@ int format_counters(struct thread_data *t, struct core_data *c, /* TSC */ outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); - /* delta */ - if (extra_delta_offset32) - outp += sprintf(outp, " %11llu", t->extra_delta32); - - /* DELTA */ - if (extra_delta_offset64) - outp += sprintf(outp, " %11llu", t->extra_delta64); - /* msr */ - if (extra_msr_offset32) - outp += sprintf(outp, " 0x%08llx", t->extra_msr32); - - /* MSR */ - if (extra_msr_offset64) - outp += sprintf(outp, " 0x%016llx", t->extra_msr64); - if (do_nhm_cstates) { if (!skip_c1) outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc); @@ -425,6 +391,8 @@ int format_counters(struct thread_data *t, struct core_data *c, if (do_snb_cstates) outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); done: + if (extra_msr_offset) + outp += sprintf(outp, " 0x%016llx", t->extra_msr); outp += sprintf(outp, "\n"); return 0; @@ -534,16 +502,10 @@ delta_thread(struct thread_data *new, struct thread_data *old, old->mperf = 1; /* divide by 0 protection */ } - old->extra_delta32 = new->extra_delta32 - old->extra_delta32; - old->extra_delta32 &= 0xFFFFFFFF; - - old->extra_delta64 = new->extra_delta64 - old->extra_delta64; - /* - * Extra MSR is just a snapshot, simply copy latest w/o subtracting + * for "extra msr", just copy the latest w/o subtracting */ - old->extra_msr32 = new->extra_msr32; - old->extra_msr64 = new->extra_msr64; + old->extra_msr = new->extra_msr; } int delta_cpu(struct thread_data *t, struct core_data *c, @@ -571,9 +533,6 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data t->mperf = 0; t->c1 = 0; - t->extra_delta32 = 0; - t->extra_delta64 = 0; - /* tells format_counters to dump all fields from this set */ t->flags = CPU_IS_FIRST_THREAD_IN_CORE | CPU_IS_FIRST_CORE_IN_PACKAGE; @@ -594,9 +553,6 @@ int sum_counters(struct thread_data *t, struct core_data *c, average.threads.mperf += t->mperf; average.threads.c1 += t->c1; - average.threads.extra_delta32 += t->extra_delta32; - average.threads.extra_delta64 += t->extra_delta64; - /* sum per-core values only for 1st thread in core */ if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) return 0; @@ -632,11 +588,6 @@ void compute_average(struct thread_data *t, struct core_data *c, average.threads.mperf /= topo.num_cpus; average.threads.c1 /= topo.num_cpus; - average.threads.extra_delta32 /= topo.num_cpus; - average.threads.extra_delta32 &= 0xFFFFFFFF; - - average.threads.extra_delta64 /= topo.num_cpus; - average.cores.c3 /= topo.num_cores; average.cores.c6 /= topo.num_cores; average.cores.c7 /= topo.num_cores; @@ -678,24 +629,8 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) return -4; } - if (extra_delta_offset32) { - if (get_msr(cpu, extra_delta_offset32, &t->extra_delta32)) - return -5; - t->extra_delta32 &= 0xFFFFFFFF; - } - - if (extra_delta_offset64) - if (get_msr(cpu, extra_delta_offset64, &t->extra_delta64)) - return -5; - - if (extra_msr_offset32) { - if (get_msr(cpu, extra_msr_offset32, &t->extra_msr32)) - return -5; - t->extra_msr32 &= 0xFFFFFFFF; - } - - if (extra_msr_offset64) - if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) + if (extra_msr_offset) + if (get_msr(cpu, extra_msr_offset, &t->extra_msr)) return -5; /* collect core counters only for 1st thread in core */ @@ -742,9 +677,6 @@ void print_verbose_header(void) get_msr(0, MSR_NEHALEM_PLATFORM_INFO, &msr); - if (verbose > 1) - fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr); - ratio = (msr >> 40) & 0xFF; fprintf(stderr, "%d * %.0f = %.0f MHz max efficiency\n", ratio, bclk, ratio * bclk); @@ -753,84 +685,14 @@ void print_verbose_header(void) fprintf(stderr, "%d * %.0f = %.0f MHz TSC frequency\n", ratio, bclk, ratio * bclk); - if (!do_ivt_turbo_ratio_limit) - goto print_nhm_turbo_ratio_limits; - - get_msr(0, MSR_IVT_TURBO_RATIO_LIMIT, &msr); - if (verbose > 1) - fprintf(stderr, "MSR_IVT_TURBO_RATIO_LIMIT: 0x%llx\n", msr); - - ratio = (msr >> 56) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 16 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 48) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 15 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 40) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 14 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 32) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 13 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 24) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 12 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 16) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 11 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 8) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 10 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 0) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 9 active cores\n", - ratio, bclk, ratio * bclk); - -print_nhm_turbo_ratio_limits: + fprintf(stderr, "MSR_NEHALEM_PLATFORM_INFO: 0x%llx\n", msr); if (!do_nehalem_turbo_ratio_limit) return; get_msr(0, MSR_NEHALEM_TURBO_RATIO_LIMIT, &msr); - if (verbose > 1) - fprintf(stderr, "MSR_NEHALEM_TURBO_RATIO_LIMIT: 0x%llx\n", msr); - - ratio = (msr >> 56) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 8 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 48) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 7 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 40) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 6 active cores\n", - ratio, bclk, ratio * bclk); - - ratio = (msr >> 32) & 0xFF; - if (ratio) - fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 5 active cores\n", - ratio, bclk, ratio * bclk); - ratio = (msr >> 24) & 0xFF; if (ratio) fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 4 active cores\n", @@ -850,6 +712,7 @@ void print_verbose_header(void) if (ratio) fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n", ratio, bclk, ratio * bclk); + } void free_all_buffers(void) @@ -1175,7 +1038,7 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) case 0x2A: /* SNB */ case 0x2D: /* SNB Xeon */ case 0x3A: /* IVB */ - case 0x3E: /* IVB Xeon */ + case 0x3D: /* IVB Xeon */ return 1; case 0x2E: /* Nehalem-EX Xeon - Beckton */ case 0x2F: /* Westmere-EX Xeon - Eagleton */ @@ -1183,22 +1046,6 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) return 0; } } -int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model) -{ - if (!genuine_intel) - return 0; - - if (family != 6) - return 0; - - switch (model) { - case 0x3E: /* IVB Xeon */ - return 1; - default: - return 0; - } -} - int is_snb(unsigned int family, unsigned int model) { @@ -1209,7 +1056,7 @@ int is_snb(unsigned int family, unsigned int model) case 0x2A: case 0x2D: case 0x3A: /* IVB */ - case 0x3E: /* IVB Xeon */ + case 0x3D: /* IVB Xeon */ return 1; } return 0; @@ -1298,13 +1145,12 @@ void check_cpuid() bclk = discover_bclk(family, model); do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); - do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model); } void usage() { - fprintf(stderr, "%s: [-v][-p|-P|-S][-c MSR# | -s]][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n", + fprintf(stderr, "%s: [-v] [-M MSR#] [-i interval_sec | command ...]\n", progname); exit(1); } @@ -1594,15 +1440,15 @@ void cmdline(int argc, char **argv) progname = argv[0]; - while ((opt = getopt(argc, argv, "+pPSvisc:sC:m:M:")) != -1) { + while ((opt = getopt(argc, argv, "+cpsvi:M:")) != -1) { switch (opt) { - case 'p': + case 'c': show_core_only++; break; - case 'P': + case 'p': show_pkg_only++; break; - case 'S': + case 's': summary_only++; break; case 'v': @@ -1611,20 +1457,10 @@ void cmdline(int argc, char **argv) case 'i': interval_sec = atoi(optarg); break; - case 'c': - sscanf(optarg, "%x", &extra_delta_offset32); - break; - case 's': - extra_delta_offset32 = 0x34; /* SMI counter */ - break; - case 'C': - sscanf(optarg, "%x", &extra_delta_offset64); - break; - case 'm': - sscanf(optarg, "%x", &extra_msr_offset32); - break; case 'M': - sscanf(optarg, "%x", &extra_msr_offset64); + sscanf(optarg, "%x", &extra_msr_offset); + if (verbose > 1) + fprintf(stderr, "MSR 0x%X\n", extra_msr_offset); break; default: usage(); @@ -1637,7 +1473,7 @@ int main(int argc, char **argv) cmdline(argc, argv); if (verbose > 1) - fprintf(stderr, "turbostat v2.1 October 6, 2012" + fprintf(stderr, "turbostat v2.0 May 16, 2012" " - Len Brown \n"); turbostat_init();