Skip to content

Add CPU frequency detection from CPUID vendor string#121

Merged
MegaMaddin merged 4 commits into
KernelTestFramework:mainlinefrom
MegaMaddin:cpufreq
Oct 23, 2020
Merged

Add CPU frequency detection from CPUID vendor string#121
MegaMaddin merged 4 commits into
KernelTestFramework:mainlinefrom
MegaMaddin:cpufreq

Conversation

@MegaMaddin
Copy link
Copy Markdown
Contributor

Issue #, if available: #80

Description of changes:

This commit series is adding a cpu frequency detection by parsing the specific bits out of the CPUID vendor string.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Testing done:

  • running UNITTEST=1 make clean boot on the branch results in executing unit tests
Got CPU string 'Intel(R) Xeon(R) CPU E3-1270 V2 @ 3.50GHz' and frequency '3500000000'
Got CPU string 'Intel(R) Celeron(R) CPU J1900 @ 1.99GHz' and frequency '1990000000'
Got CPU string 'AMD G-T48L Processor' and frequency '0'
Got CPU string 'Intel(R) Atom(TM) CPU E3815 @ 1.46GHz' and frequency '1460000000'
Got CPU string 'Intel(R) Atom(TM) CPU E620 @ 600MHz' and frequency '600000000'
Got CPU string 'VIA C7 Processor 1000MHz' and frequency '1000000000'
Got CPU string 'Intel(R) Core(TM) i7 CPU 950 @ 3.07GHz' and frequency '3070000000'
Got CPU string 'AMD Ryzen Threadripper 1950X 16-Core Processor' and frequency '0'
Got CPU string 'Prototyp Amazing Foo One @ 1GHz' and frequency '1000000000'
Got CPU string 'Prototyp Amazing Foo Two @ 1.00GHz' and frequency '1000000000'

@MegaMaddin MegaMaddin requested a review from wipawel October 22, 2020 08:33
@MegaMaddin MegaMaddin linked an issue Oct 22, 2020 that may be closed by this pull request
Comment thread include/cpuid.h Outdated
#define MHZ_MULTIPLIER 1000000
#define GHZ_MULTIPLIER 1000000000

static inline uint64_t get_cpu_freq(const char *cpu_str) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make it regular function (no inline).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did that, had to use it somewhere afterwards :)

Comment thread include/cpuid.h Outdated
Comment on lines +35 to +36
#define MHZ_MULTIPLIER 1000000
#define GHZ_MULTIPLIER 1000000000
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might make sense to add common defines for HZ() KHZ() MHZ() and GHZ(), similar to the ones for KB(), MB(), and GB()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Comment thread include/cpuid.h Outdated

/* we need to reverse the vendor string for parsing the freq */
while (len--) {
if (isspace(*(cpu_str + len))) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: cpu_str[len]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment thread include/cpuid.h Outdated
*(reverse) = '\0';
break;
}
*(reverse++) = *(cpu_str + len);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: *reverse++ = cpu_str[len]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment thread include/cpuid.h
uint64_t frequency = 0;
char buf[16];
char buf2[16];
char *reverse = &buf[0];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: reverse can be declared in the while() {} loop scope using it

Comment thread include/cpuid.h Outdated
}

if (!strstr(buf, "zHM") && !strstr(buf, "zHG")) {
// if we have nothing to calculate, just return
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no C++ comments pls

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also this if seems redundant. We call the same strstr() in the below if-else if-else. We can make return 0 the statement of the final else

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment thread include/cpuid.h
size_t len = strlen(cpu_str);
uint64_t multiplier = 0;
uint64_t frequency = 0;
char buf[16];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I would call it reverse and the buf2 result

Comment thread include/cpuid.h Outdated
Comment on lines +93 to +89
if (strlen(buf2) == 2)
frequency += strtoul(buf2, NULL, 0) * 10 * multiplier;
else if (strlen(buf2) == 1)
frequency += strtoul(buf2, NULL, 0) * 100 * multiplier;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be: frequency += strtoul(buf2, NULL, 0) * (1000 / (10 * strlen(buf2))) * multiplier

@wipawel wipawel added the Priority: 3 Regular feature label Oct 22, 2020
@wipawel wipawel added this to the v0.3 milestone Oct 22, 2020
@MegaMaddin MegaMaddin force-pushed the cpufreq branch 5 times, most recently from 65b6dd4 to 695e61d Compare October 22, 2020 16:38
Comment thread common/setup.c Outdated
if (cpu_vendor_string(&cpu_identifier[0]))
if (cpu_vendor_string(&cpu_identifier[0])) {
printk("CPU: %.48s\n", cpu_identifier);
printk("Frequency: %llu Hz\n", get_cpu_freq(&cpu_identifier[0]));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I would prefer MHz and %lu formatter should be ok

Comment thread include/cpuid.h Outdated
#define CPUID_BRAND_INFO_MIN 0x80000002U
#define CPUID_BRAND_INFO_MAX 0x80000004U

#define KHZ(x) (_U64(x) * ipow(10, 3))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this and below I would move to compiler.h

Comment thread include/cpuid.h Outdated
}
}
}
else {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since frequency is set to 0 by default, this is redundant

Comment thread include/lib.h Outdated
}

static inline unsigned int ipow(int base, int exp) {
int result = 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be unsigned long

Comment thread include/lib.h Outdated
return n;
}

static inline unsigned int ipow(int base, int exp) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function should return unsigned long

Comment thread include/lib.h

static inline unsigned int ipow(int base, int exp) {
int result = 1;
for (;;) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pow(nit, 10): while(true)

Signed-off-by: Martin Mazein <amazein@amazon.de>
Comment thread common/setup.c Outdated

/* Print cpu vendor info */
if (cpu_vendor_string(&cpu_identifier[0]))
if (cpu_vendor_string(&cpu_identifier[0])) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: here and below: s/&cpu_identifier[0]/cpu_identifier/

Comment thread include/compiler.h Outdated
#define GB(x) (_U64(x) << 30)

#define KHZ(x) (_U64(x) * 1000)
#define MHZ(x) (_U64(x) * 1000000)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: MHZ(x) (KHZ(x) * 1000)

Comment thread include/lib.h Outdated
return n;
}

static inline unsigned long ipow(int base, int exp) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/int exp/unsigned int exp/

Signed-off-by: Martin Mazein <amazein@amazon.de>
… string

Signed-off-by: Martin Mazein <amazein@amazon.de>
Signed-off-by: Martin Mazein <amazein@amazon.de>
@MegaMaddin MegaMaddin merged commit 6cf4ea8 into KernelTestFramework:mainline Oct 23, 2020
@MegaMaddin MegaMaddin deleted the cpufreq branch December 1, 2020 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Priority: 3 Regular feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] add CPUID processor brand string handling and parsing

2 participants