Message ID | 20200717060849.12469-1-liwei.song@windriver.com (mailing list archive) |
---|---|
State | Superseded, archived |
Delegated to: | Len Brown |
Headers | show |
Series | tools/power turbostat: call pread64 in kernel directly | expand |
Huh? On Fri, Jul 17, 2020 at 2:09 AM Liwei Song <liwei.song@windriver.com> wrote: > > with 32-bit rootfs, the offset may out of range when set it > to 0xc0010299, define it as "unsigned long long" type and > call pread64 directly in kernel. > > Signed-off-by: Liwei Song <liwei.song@windriver.com> > --- > tools/power/x86/turbostat/turbostat.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c > index 33b370865d16..4c5cdfcb5721 100644 > --- a/tools/power/x86/turbostat/turbostat.c > +++ b/tools/power/x86/turbostat/turbostat.c > @@ -33,6 +33,7 @@ > #include <sys/capability.h> > #include <errno.h> > #include <math.h> > +#include <sys/syscall.h> > > char *proc_stat = "/proc/stat"; > FILE *outf; > @@ -381,11 +382,11 @@ int get_msr_fd(int cpu) > return fd; > } > > -int get_msr(int cpu, off_t offset, unsigned long long *msr) > +int get_msr(int cpu, unsigned long long offset, unsigned long long *msr) > { > ssize_t retval; > > - retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset); > + retval = syscall(SYS_pread64, get_msr_fd(cpu), msr, sizeof(*msr), offset); > > if (retval != sizeof *msr) > err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset); > -- > 2.17.1 >
with multilib lib32 support, the rootfs will be 32-bit, the kernel is still 64-bit, in this case run turbostat will failed with "out of range" error. Thanks, Liwei. On 8/14/20 05:43, Len Brown wrote: > Huh? > > On Fri, Jul 17, 2020 at 2:09 AM Liwei Song <liwei.song@windriver.com> wrote: >> >> with 32-bit rootfs, the offset may out of range when set it >> to 0xc0010299, define it as "unsigned long long" type and >> call pread64 directly in kernel. >> >> Signed-off-by: Liwei Song <liwei.song@windriver.com> >> --- >> tools/power/x86/turbostat/turbostat.c | 5 +++-- >> 1 file changed, 3 insertions(+), 2 deletions(-) >> >> diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c >> index 33b370865d16..4c5cdfcb5721 100644 >> --- a/tools/power/x86/turbostat/turbostat.c >> +++ b/tools/power/x86/turbostat/turbostat.c >> @@ -33,6 +33,7 @@ >> #include <sys/capability.h> >> #include <errno.h> >> #include <math.h> >> +#include <sys/syscall.h> >> >> char *proc_stat = "/proc/stat"; >> FILE *outf; >> @@ -381,11 +382,11 @@ int get_msr_fd(int cpu) >> return fd; >> } >> >> -int get_msr(int cpu, off_t offset, unsigned long long *msr) >> +int get_msr(int cpu, unsigned long long offset, unsigned long long *msr) >> { >> ssize_t retval; >> >> - retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset); >> + retval = syscall(SYS_pread64, get_msr_fd(cpu), msr, sizeof(*msr), offset); >> >> if (retval != sizeof *msr) >> err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset); >> -- >> 2.17.1 >> > >
Re: offset size The offsets on this file are the MSR offsets. What MSR are you trying to access at offset 0xc0010299? Re: pread vs pread64 If I take on faith that you have some kind of 32-bit execution environment that makes pread into pread32 instead of pread64, and that truncates an off_t to 32-bits from 64-bits, and it actually makes sense to request a read at this large offset... would we really have to invoke syscall() directly -- couldn't we invoke pread64() directly? (eg. below) thanks, -Len @@ -490,11 +491,12 @@ int get_msr_fd(int cpu) return fd; } -int get_msr(int cpu, off_t offset, unsigned long long *msr) +int get_msr(int cpu, unsigned long long offset, unsigned long long *msr) { ssize_t retval; - retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset); + retval = pread64(get_msr_fd(cpu), msr, sizeof(*msr), offset); if (retval != sizeof *msr) err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset); On Thu, Aug 13, 2020 at 10:17 PM Liwei Song <liwei.song@windriver.com> wrote: > > with multilib lib32 support, the rootfs will be 32-bit, > the kernel is still 64-bit, in this case run turbostat > will failed with "out of range" error. > > Thanks, > Liwei. > > On 8/14/20 05:43, Len Brown wrote: > > Huh? > > > > On Fri, Jul 17, 2020 at 2:09 AM Liwei Song <liwei.song@windriver.com> wrote: > >> > >> with 32-bit rootfs, the offset may out of range when set it > >> to 0xc0010299, define it as "unsigned long long" type and > >> call pread64 directly in kernel. > >> > >> Signed-off-by: Liwei Song <liwei.song@windriver.com> > >> --- > >> tools/power/x86/turbostat/turbostat.c | 5 +++-- > >> 1 file changed, 3 insertions(+), 2 deletions(-) > >> > >> diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c > >> index 33b370865d16..4c5cdfcb5721 100644 > >> --- a/tools/power/x86/turbostat/turbostat.c > >> +++ b/tools/power/x86/turbostat/turbostat.c > >> @@ -33,6 +33,7 @@ > >> #include <sys/capability.h> > >> #include <errno.h> > >> #include <math.h> > >> +#include <sys/syscall.h> > >> > >> char *proc_stat = "/proc/stat"; > >> FILE *outf; > >> @@ -381,11 +382,11 @@ int get_msr_fd(int cpu) > >> return fd; > >> } > >> > >> -int get_msr(int cpu, off_t offset, unsigned long long *msr) > >> +int get_msr(int cpu, unsigned long long offset, unsigned long long *msr) > >> { > >> ssize_t retval; > >> > >> - retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset); > >> + retval = syscall(SYS_pread64, get_msr_fd(cpu), msr, sizeof(*msr), offset); > >> > >> if (retval != sizeof *msr) > >> err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset); > >> -- > >> 2.17.1 > >> > > > >
Hi, I am not the original submitter, but I have answers and a proper patch :) On Fri, 21 Aug 2020, Len Brown wrote: > Re: offset size > > The offsets on this file are the MSR offsets. > What MSR are you trying to access at offset 0xc0010299? This MSR is particular is part of AMD RAPL (energy measurements) interface. > Re: pread vs pread64 > > If I take on faith that you have some kind of 32-bit execution > environment that makes pread into pread32 instead of pread64, and that > truncates an off_t to 32-bits from 64-bits, and it actually makes > sense to request a read at this large offset... The problem here stems from the backward compatibility in Glibc: off_t is 32-bit on 32-bit x86, unless compiled with -D_FILE_OFFSET_BITS=64. This macro should be used for all new code. Distros should enable it for all builds, but when one builds turbostat 'by hand', they hit the issue. > would we really have to invoke syscall() directly -- couldn't we > invoke pread64() directly? (eg. below) No, the proper fix is to pass -D_FILE_OFFSET_BITS=64 to the compiler. Here's the patch: ---8<--- From: Alexander Monakov <amonakov@ispras.ru> Date: Sun, 23 Aug 2020 23:27:02 +0300 Subject: [PATCH] turbostat: build with _FILE_OFFSET_BITS=64 For compatibility reasons, Glibc off_t is a 32-bit type on 32-bit x86 unless _FILE_OFFSET_BITS=64 is defined. Add this define, as otherwise reading MSRs with index 0x80000000 and above attempts a pread with a negative offset, which fails. Signed-off-by: Alexander Monakov <amonakov@ispras.ru> --- tools/power/x86/turbostat/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile index 2b6551269e43..40ae44402eec 100644 --- a/tools/power/x86/turbostat/Makefile +++ b/tools/power/x86/turbostat/Makefile @@ -12,6 +12,7 @@ turbostat : turbostat.c override CFLAGS += -O2 -Wall -I../../../include override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' override CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"' +override CFLAGS += -D_FILE_OFFSET_BITS=64 override CFLAGS += -D_FORTIFY_SOURCE=2 %: %.c
On 8/24/20 04:54, Alexander Monakov wrote: > Hi, > > I am not the original submitter, but I have answers and a proper patch :) > > On Fri, 21 Aug 2020, Len Brown wrote: > >> Re: offset size >> >> The offsets on this file are the MSR offsets. >> What MSR are you trying to access at offset 0xc0010299? > > This MSR is particular is part of AMD RAPL (energy measurements) interface. > >> Re: pread vs pread64 >> >> If I take on faith that you have some kind of 32-bit execution >> environment that makes pread into pread32 instead of pread64, and that >> truncates an off_t to 32-bits from 64-bits, and it actually makes >> sense to request a read at this large offset... > > The problem here stems from the backward compatibility in Glibc: off_t is > 32-bit on 32-bit x86, unless compiled with -D_FILE_OFFSET_BITS=64. This > macro should be used for all new code. Distros should enable it for all > builds, but when one builds turbostat 'by hand', they hit the issue. > >> would we really have to invoke syscall() directly -- couldn't we >> invoke pread64() directly? (eg. below) > > No, the proper fix is to pass -D_FILE_OFFSET_BITS=64 to the compiler. > > Here's the patch: This path works with my case. Thanks, Liwei. > > ---8<--- > > From: Alexander Monakov <amonakov@ispras.ru> > Date: Sun, 23 Aug 2020 23:27:02 +0300 > Subject: [PATCH] turbostat: build with _FILE_OFFSET_BITS=64 > > For compatibility reasons, Glibc off_t is a 32-bit type on 32-bit x86 > unless _FILE_OFFSET_BITS=64 is defined. Add this define, as otherwise > reading MSRs with index 0x80000000 and above attempts a pread with a > negative offset, which fails. > > Signed-off-by: Alexander Monakov <amonakov@ispras.ru> > --- > tools/power/x86/turbostat/Makefile | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile > index 2b6551269e43..40ae44402eec 100644 > --- a/tools/power/x86/turbostat/Makefile > +++ b/tools/power/x86/turbostat/Makefile > @@ -12,6 +12,7 @@ turbostat : turbostat.c > override CFLAGS += -O2 -Wall -I../../../include > override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' > override CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"' > +override CFLAGS += -D_FILE_OFFSET_BITS=64 > override CFLAGS += -D_FORTIFY_SOURCE=2 > > %: %.c >
> -D_FILE_OFFSET_BITS=64 Applied. thanks! -Len On Mon, Aug 24, 2020 at 12:09 AM Liwei Song <liwei.song@windriver.com> wrote: > > > > On 8/24/20 04:54, Alexander Monakov wrote: > > Hi, > > > > I am not the original submitter, but I have answers and a proper patch :) > > > > On Fri, 21 Aug 2020, Len Brown wrote: > > > >> Re: offset size > >> > >> The offsets on this file are the MSR offsets. > >> What MSR are you trying to access at offset 0xc0010299? > > > > This MSR is particular is part of AMD RAPL (energy measurements) interface. > > > >> Re: pread vs pread64 > >> > >> If I take on faith that you have some kind of 32-bit execution > >> environment that makes pread into pread32 instead of pread64, and that > >> truncates an off_t to 32-bits from 64-bits, and it actually makes > >> sense to request a read at this large offset... > > > > The problem here stems from the backward compatibility in Glibc: off_t is > > 32-bit on 32-bit x86, unless compiled with -D_FILE_OFFSET_BITS=64. This > > macro should be used for all new code. Distros should enable it for all > > builds, but when one builds turbostat 'by hand', they hit the issue. > > > >> would we really have to invoke syscall() directly -- couldn't we > >> invoke pread64() directly? (eg. below) > > > > No, the proper fix is to pass -D_FILE_OFFSET_BITS=64 to the compiler. > > > > Here's the patch: > > This path works with my case. > > Thanks, > Liwei. > > > > > > ---8<--- > > > > From: Alexander Monakov <amonakov@ispras.ru> > > Date: Sun, 23 Aug 2020 23:27:02 +0300 > > Subject: [PATCH] turbostat: build with _FILE_OFFSET_BITS=64 > > > > For compatibility reasons, Glibc off_t is a 32-bit type on 32-bit x86 > > unless _FILE_OFFSET_BITS=64 is defined. Add this define, as otherwise > > reading MSRs with index 0x80000000 and above attempts a pread with a > > negative offset, which fails. > > > > Signed-off-by: Alexander Monakov <amonakov@ispras.ru> > > --- > > tools/power/x86/turbostat/Makefile | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile > > index 2b6551269e43..40ae44402eec 100644 > > --- a/tools/power/x86/turbostat/Makefile > > +++ b/tools/power/x86/turbostat/Makefile > > @@ -12,6 +12,7 @@ turbostat : turbostat.c > > override CFLAGS += -O2 -Wall -I../../../include > > override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' > > override CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"' > > +override CFLAGS += -D_FILE_OFFSET_BITS=64 > > override CFLAGS += -D_FORTIFY_SOURCE=2 > > > > %: %.c > >
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 33b370865d16..4c5cdfcb5721 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -33,6 +33,7 @@ #include <sys/capability.h> #include <errno.h> #include <math.h> +#include <sys/syscall.h> char *proc_stat = "/proc/stat"; FILE *outf; @@ -381,11 +382,11 @@ int get_msr_fd(int cpu) return fd; } -int get_msr(int cpu, off_t offset, unsigned long long *msr) +int get_msr(int cpu, unsigned long long offset, unsigned long long *msr) { ssize_t retval; - retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset); + retval = syscall(SYS_pread64, get_msr_fd(cpu), msr, sizeof(*msr), offset); if (retval != sizeof *msr) err(-1, "cpu%d: msr offset 0x%llx read failed", cpu, (unsigned long long)offset);
with 32-bit rootfs, the offset may out of range when set it to 0xc0010299, define it as "unsigned long long" type and call pread64 directly in kernel. Signed-off-by: Liwei Song <liwei.song@windriver.com> --- tools/power/x86/turbostat/turbostat.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)