[PATCH] staging: greybus: fix spelling mistake "entires" -> "entries"
From: Colin Ian King Trivial fix to spelling mistake Signed-off-by: Colin Ian King --- drivers/staging/greybus/tools/README.loopback | 2 +- drivers/staging/greybus/tools/loopback_test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/greybus/tools/README.loopback b/drivers/staging/greybus/tools/README.loopback index 845b08dc4696..070a510cbe7c 100644 --- a/drivers/staging/greybus/tools/README.loopback +++ b/drivers/staging/greybus/tools/README.loopback @@ -79,7 +79,7 @@ Here is the summary of the available options: -t must be one of the test names - sink, transfer or ping -i iteration count - the number of iterations to run the test over Optional arguments - -S sysfs location - location for greybus 'endo' entires default /sys/bus/greybus/devices/ + -S sysfs location - location for greybus 'endo' entries default /sys/bus/greybus/devices/ -D debugfs location - location for loopback debugfs entries default /sys/kernel/debug/gb_loopback/ -s size of data packet to send during test - defaults to zero -m mask - a bit mask of connections to include example: -m 8 = 4th connection -m 9 = 1st and 4th connection etc diff --git a/drivers/staging/greybus/tools/loopback_test.c b/drivers/staging/greybus/tools/loopback_test.c index b82e2befe935..2fa88092514d 100644 --- a/drivers/staging/greybus/tools/loopback_test.c +++ b/drivers/staging/greybus/tools/loopback_test.c @@ -192,7 +192,7 @@ void usage(void) " -t must be one of the test names - sink, transfer or ping\n" " -i iteration count - the number of iterations to run the test over\n" " Optional arguments\n" - " -S sysfs location - location for greybus 'endo' entires default /sys/bus/greybus/devices/\n" + " -S sysfs location - location for greybus 'endo' entries default /sys/bus/greybus/devices/\n" " -D debugfs location - location for loopback debugfs entries default /sys/kernel/debug/gb_loopback/\n" " -s size of data packet to send during test - defaults to zero\n" " -m mask - a bit mask of connections to include example: -m 8 = 4th connection -m 9 = 1st and 4th connection etc\n" -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[GIT PULL] Staging/IIO driver fixes for 4.19-rc4
The following changes since commit 5b394b2ddf0347bef56e50c69a58773c94343ff3: Linux 4.19-rc1 (2018-08-26 14:11:59 -0700) are available in the Git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git tags/staging-4.19-rc4 for you to fetch changes up to 65aac17423284634169489f298169c3e3f099cc7: staging: vboxvideo: Change address of scanout buffer on page-flip (2018-09-11 18:39:54 +0200) Staging/IIO fixes for 4.19-rc4 Here are a few small staging and iio driver fixes for -rc4. Nothing major, just a few small bugfixes for some reported issues, and a MAINTAINERS file update for the fbtft drivers. We also re-enable the building of the erofs filesystem as the patcheset that was causing it to break never got merged in the -rc1 cycle, so there's no reason it can't be turned back on for now. The problem that was previously there is now being handled in that other tree at the moment, so it will not hit us again in the future. All of these patches have been in linux-next with no reported issues. Signed-off-by: Greg Kroah-Hartman Ahmed S. Darwish (1): staging: gasket: TODO: re-implement using UIO Arnd Bergmann (1): staging: wilc1000: revert "fix TODO to compile spi and sdio components in single module" Daniel Vetter (1): staging/fbtft: Update TODO and mailing lists Gao Xiang (2): Revert "staging: erofs: disable compiling temporarile" staging: erofs: rename superblock flags (MS_xyz -> SB_xyz) Greg Kroah-Hartman (1): Merge tag 'iio-fixes-4.19a' of git://git.kernel.org/.../jic23/iio into staging-linus Hans de Goede (2): staging: vboxvideo: Fix IRQs no longer working staging: vboxvideo: Change address of scanout buffer on page-flip Lorenzo Bianconi (1): iio: imu: st_lsm6dsx: take into account ts samples in wm configuration Matt Ranostay (1): Revert "iio: temperature: maxim_thermocouple: add MAX31856 part" Todd Poynor (1): MAINTAINERS: Switch a maintainer for drivers/staging/gasket MAINTAINERS| 4 +++- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 13 ++--- drivers/iio/temperature/maxim_thermocouple.c | 1 - drivers/staging/erofs/Kconfig | 2 +- drivers/staging/erofs/super.c | 4 ++-- drivers/staging/fbtft/TODO | 4 drivers/staging/gasket/TODO| 13 + drivers/staging/vboxvideo/vbox_drv.c | 7 +++ drivers/staging/vboxvideo/vbox_mode.c | 5 + drivers/staging/wilc1000/Makefile | 3 +-- drivers/staging/wilc1000/linux_wlan.c | 6 -- drivers/staging/wilc1000/wilc_debugfs.c| 7 +-- drivers/staging/wilc1000/wilc_wlan.c | 6 ++ drivers/staging/wilc1000/wilc_wlan_if.h| 2 -- 14 files changed, 57 insertions(+), 20 deletions(-) ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [greybus-dev] [PATCH] staging: greybus: fix spelling mistake "entires" -> "entries"
On 09/14/2018 06:24 AM, Colin King wrote: > From: Colin Ian King > > Trivial fix to spelling mistake I hate to have two-character fixes to documentation like this. I.e., as long as you're touching the README file it might have been nice to review it and look for other things. I suspect you found this in the program output though, and also noticed it in the README file. So... Looks good to me. Reviewed-by: Alex Elder > > Signed-off-by: Colin Ian King > --- > drivers/staging/greybus/tools/README.loopback | 2 +- > drivers/staging/greybus/tools/loopback_test.c | 2 +- > 2 files changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/staging/greybus/tools/README.loopback > b/drivers/staging/greybus/tools/README.loopback > index 845b08dc4696..070a510cbe7c 100644 > --- a/drivers/staging/greybus/tools/README.loopback > +++ b/drivers/staging/greybus/tools/README.loopback > @@ -79,7 +79,7 @@ Here is the summary of the available options: > -t must be one of the test names - sink, transfer or ping > -i iteration count - the number of iterations to run the test over > Optional arguments > - -S sysfs location - location for greybus 'endo' entires default > /sys/bus/greybus/devices/ > + -S sysfs location - location for greybus 'endo' entries default > /sys/bus/greybus/devices/ > -D debugfs location - location for loopback debugfs entries default > /sys/kernel/debug/gb_loopback/ > -s size of data packet to send during test - defaults to zero > -m mask - a bit mask of connections to include example: -m 8 = 4th > connection -m 9 = 1st and 4th connection etc > diff --git a/drivers/staging/greybus/tools/loopback_test.c > b/drivers/staging/greybus/tools/loopback_test.c > index b82e2befe935..2fa88092514d 100644 > --- a/drivers/staging/greybus/tools/loopback_test.c > +++ b/drivers/staging/greybus/tools/loopback_test.c > @@ -192,7 +192,7 @@ void usage(void) > " -t must be one of the test names - sink, transfer or ping\n" > " -i iteration count - the number of iterations to run the test > over\n" > " Optional arguments\n" > - " -S sysfs location - location for greybus 'endo' entires default > /sys/bus/greybus/devices/\n" > + " -S sysfs location - location for greybus 'endo' entries default > /sys/bus/greybus/devices/\n" > " -D debugfs location - location for loopback debugfs entries > default /sys/kernel/debug/gb_loopback/\n" > " -s size of data packet to send during test - defaults to zero\n" > " -m mask - a bit mask of connections to include example: -m 8 = > 4th connection -m 9 = 1st and 4th connection etc\n" > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [greybus-dev] [PATCH] staging: greybus: fix spelling mistake "entires" -> "entries"
On 14/09/18 12:43, Alex Elder wrote: > On 09/14/2018 06:24 AM, Colin King wrote: >> From: Colin Ian King >> >> Trivial fix to spelling mistake > > I hate to have two-character fixes to documentation like this. I.e., > as long as you're touching the README file it might have been nice to > review it and look for other things. I suspect you found this in the > program output though, and also noticed it in the README file. Indeed, it was the program output where the mistake was first spotted. > > So... Looks good to me. > > Reviewed-by: Alex Elder > >> >> Signed-off-by: Colin Ian King >> --- >> drivers/staging/greybus/tools/README.loopback | 2 +- >> drivers/staging/greybus/tools/loopback_test.c | 2 +- >> 2 files changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/staging/greybus/tools/README.loopback >> b/drivers/staging/greybus/tools/README.loopback >> index 845b08dc4696..070a510cbe7c 100644 >> --- a/drivers/staging/greybus/tools/README.loopback >> +++ b/drivers/staging/greybus/tools/README.loopback >> @@ -79,7 +79,7 @@ Here is the summary of the available options: >> -t must be one of the test names - sink, transfer or ping >> -i iteration count - the number of iterations to run the test over >> Optional arguments >> - -S sysfs location - location for greybus 'endo' entires default >> /sys/bus/greybus/devices/ >> + -S sysfs location - location for greybus 'endo' entries default >> /sys/bus/greybus/devices/ >> -D debugfs location - location for loopback debugfs entries default >> /sys/kernel/debug/gb_loopback/ >> -s size of data packet to send during test - defaults to zero >> -m mask - a bit mask of connections to include example: -m 8 = 4th >> connection -m 9 = 1st and 4th connection etc >> diff --git a/drivers/staging/greybus/tools/loopback_test.c >> b/drivers/staging/greybus/tools/loopback_test.c >> index b82e2befe935..2fa88092514d 100644 >> --- a/drivers/staging/greybus/tools/loopback_test.c >> +++ b/drivers/staging/greybus/tools/loopback_test.c >> @@ -192,7 +192,7 @@ void usage(void) >> " -t must be one of the test names - sink, transfer or ping\n" >> " -i iteration count - the number of iterations to run the test >> over\n" >> " Optional arguments\n" >> -" -S sysfs location - location for greybus 'endo' entires default >> /sys/bus/greybus/devices/\n" >> +" -S sysfs location - location for greybus 'endo' entries default >> /sys/bus/greybus/devices/\n" >> " -D debugfs location - location for loopback debugfs entries >> default /sys/kernel/debug/gb_loopback/\n" >> " -s size of data packet to send during test - defaults to zero\n" >> " -m mask - a bit mask of connections to include example: -m 8 = >> 4th connection -m 9 = 1st and 4th connection etc\n" >> > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 01/11] clocksource: Provide clocksource_arch_init()
Architectures have extra archdata in the clocksource, e.g. for VDSO support. There are no sanity checks or general initializations for this available. Add support for that. Signed-off-by: Thomas Gleixner --- include/linux/clocksource.h |5 + kernel/time/Kconfig |4 kernel/time/clocksource.c |2 ++ 3 files changed, 11 insertions(+) --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -241,6 +241,11 @@ static inline void __clocksource_update_ __clocksource_update_freq_scale(cs, 1000, khz); } +#ifdef CONFIG_ARCH_CLOCKSOURCE_INIT +extern void clocksource_arch_init(struct clocksource *cs); +#else +static inline void clocksource_arch_init(struct clocksource *cs) { } +#endif extern int timekeeping_notify(struct clocksource *clock); --- a/kernel/time/Kconfig +++ b/kernel/time/Kconfig @@ -12,6 +12,10 @@ config CLOCKSOURCE_WATCHDOG config ARCH_CLOCKSOURCE_DATA bool +# Architecture has extra clocksource init called from registration +config ARCH_CLOCKSOURCE_INIT + bool + # Clocksources require validation of the clocksource against the last # cycle update - x86/TSC misfeature config CLOCKSOURCE_VALIDATE_LAST_CYCLE --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -937,6 +937,8 @@ int __clocksource_register_scale(struct { unsigned long flags; + clocksource_arch_init(cs); + /* Initialize mult/shift and max_idle_ns */ __clocksource_update_freq_scale(cs, scale, freq); ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 03/11] x86/vdso: Enforce 64bit clocksource
All VDSO clock sources are TSC based and use CLOCKSOURCE_MASK(64). There is no point in masking with all FF. Get rid of it and enforce the mask in the sanity checker. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c |2 +- arch/x86/kernel/time.c |6 ++ 2 files changed, 7 insertions(+), 1 deletion(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -199,7 +199,7 @@ notrace static inline u64 vgetsns(int *m #endif else return 0; - v = (cycles - gtod->cycle_last) & gtod->mask; + v = cycles - gtod->cycle_last; return v * gtod->mult; } --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c @@ -120,4 +120,10 @@ void clocksource_arch_init(struct clocks cs->name, cs->archdata.vclock_mode); cs->archdata.vclock_mode = VCLOCK_NONE; } + + if (cs->mask != CLOCKSOURCE_MASK(64)) { + pr_warn("clocksource %s registered with invalid mask %016llx. Disabling vclock.\n", + cs->name, cs->mask); + cs->archdata.vclock_mode = VCLOCK_NONE; + } } ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 05/11] x86/vdso: Introduce and use vgtod_ts
It's desired to support more clocks in the VDSO, e.g. CLOCK_TAI. This results either in indirect calls due to the larger switch case, which then requires retpolines or when the compiler is forced to avoid jump tables it results in even more conditionals. To avoid both variants which are bad for performance the high resolution functions and the coarse grained functions will be collapsed into one for each. That requires to store the clock specific base time in an array. Introcude struct vgtod_ts for storage and convert the data store, the update function and the individual clock functions over to use it. The new storage does not longer use gtod_long_t for seconds depending on 32 or 64 bit compile because this needs to be the full 64bit value even for 32bit when a Y2038 function is added. No point in keeping the distinction alive in the internal representation. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c| 24 +-- arch/x86/entry/vsyscall/vsyscall_gtod.c | 51 arch/x86/include/asm/vgtod.h| 36 -- 3 files changed, 61 insertions(+), 50 deletions(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -206,6 +206,7 @@ notrace static inline u64 vgetsns(int *m /* Code size doesn't matter (vdso is 4k anyway) and this is faster. */ notrace static int __always_inline do_realtime(struct timespec *ts) { + struct vgtod_ts *base = >od->basetime[CLOCK_REALTIME]; unsigned int seq; u64 ns; int mode; @@ -213,8 +214,8 @@ notrace static int __always_inline do_re do { seq = gtod_read_begin(gtod); mode = gtod->vclock_mode; - ts->tv_sec = gtod->wall_time_sec; - ns = gtod->wall_time_snsec; + ts->tv_sec = base->sec; + ns = base->nsec; ns += vgetsns(&mode); ns >>= gtod->shift; } while (unlikely(gtod_read_retry(gtod, seq))); @@ -227,6 +228,7 @@ notrace static int __always_inline do_re notrace static int __always_inline do_monotonic(struct timespec *ts) { + struct vgtod_ts *base = >od->basetime[CLOCK_MONOTONIC]; unsigned int seq; u64 ns; int mode; @@ -234,8 +236,8 @@ notrace static int __always_inline do_mo do { seq = gtod_read_begin(gtod); mode = gtod->vclock_mode; - ts->tv_sec = gtod->monotonic_time_sec; - ns = gtod->monotonic_time_snsec; + ts->tv_sec = base->sec; + ns = base->nsec; ns += vgetsns(&mode); ns >>= gtod->shift; } while (unlikely(gtod_read_retry(gtod, seq))); @@ -248,21 +250,25 @@ notrace static int __always_inline do_mo notrace static void do_realtime_coarse(struct timespec *ts) { + struct vgtod_ts *base = >od->basetime[CLOCK_REALTIME_COARSE]; unsigned int seq; + do { seq = gtod_read_begin(gtod); - ts->tv_sec = gtod->wall_time_coarse_sec; - ts->tv_nsec = gtod->wall_time_coarse_nsec; + ts->tv_sec = base->sec; + ts->tv_nsec = base->nsec; } while (unlikely(gtod_read_retry(gtod, seq))); } notrace static void do_monotonic_coarse(struct timespec *ts) { + struct vgtod_ts *base = >od->basetime[CLOCK_MONOTONIC_COARSE]; unsigned int seq; + do { seq = gtod_read_begin(gtod); - ts->tv_sec = gtod->monotonic_time_coarse_sec; - ts->tv_nsec = gtod->monotonic_time_coarse_nsec; + ts->tv_sec = base->sec; + ts->tv_nsec = base->nsec; } while (unlikely(gtod_read_retry(gtod, seq))); } @@ -318,7 +324,7 @@ int gettimeofday(struct timeval *, struc notrace time_t __vdso_time(time_t *t) { /* This is atomic on x86 so we don't need any locks. */ - time_t result = READ_ONCE(gtod->wall_time_sec); + time_t result = READ_ONCE(gtod->basetime[CLOCK_REALTIME].sec); if (t) *t = result; --- a/arch/x86/entry/vsyscall/vsyscall_gtod.c +++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c @@ -31,6 +31,8 @@ void update_vsyscall(struct timekeeper * { int vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; struct vsyscall_gtod_data *vdata = &vsyscall_gtod_data; + struct vgtod_ts *base; + u64 nsec; /* Mark the new vclock used. */ BUILD_BUG_ON(VCLOCK_MAX >= 32); @@ -45,34 +47,33 @@ void update_vsyscall(struct timekeeper * vdata->mult = tk->tkr_mono.mult; vdata->shift= tk->tkr_mono.shift; - vdata->wall_time_sec= tk->xtime_sec; - vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec; - - vdata->monotonic_time_sec = tk->xtime_sec - + tk->wall_to_monotonic.tv_sec; -
[patch 09/11] x86/vdso: Simplify the invalid vclock case
The code flow for the vclocks is convoluted as it requires the vclocks which can be invalidated separately from the vsyscall_gtod_data sequence to store the fact in a separate variable. That's inefficient. Restructure the code so the vclock readout returns cycles and the conversion to nanoseconds is handled at the call site. If the clock gets invalidated or vclock is already VCLOCK_NONE, return U64_MAX as the cycle value, which is invalid for all clocks and leave the sequence loop immediately in that case by calling the fallback function directly. This allows to remove the gettimeofday fallback as it now uses the clock_gettime() fallback and does the nanoseconds to microseconds conversion in the same way as it does when the vclock is functional. It does not make a difference whether the division by 1000 happens in the kernel fallback or in userspace. Generates way better code and gains a few cycles back. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c | 81 +-- 1 file changed, 21 insertions(+), 60 deletions(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -48,16 +48,6 @@ notrace static long vdso_fallback_gettim return ret; } -notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) -{ - long ret; - - asm("syscall" : "=a" (ret) : - "0" (__NR_gettimeofday), "D" (tv), "S" (tz) : "memory"); - return ret; -} - - #else notrace static long vdso_fallback_gettime(long clock, struct timespec *ts) @@ -75,21 +65,6 @@ notrace static long vdso_fallback_gettim return ret; } -notrace static long vdso_fallback_gtod(struct timeval *tv, struct timezone *tz) -{ - long ret; - - asm( - "mov %%ebx, %%edx \n" - "mov %2, %%ebx \n" - "call __kernel_vsyscall \n" - "mov %%edx, %%ebx \n" - : "=a" (ret) - : "0" (__NR_gettimeofday), "g" (tv), "c" (tz) - : "memory", "edx"); - return ret; -} - #endif #ifdef CONFIG_PARAVIRT_CLOCK @@ -98,7 +73,7 @@ static notrace const struct pvclock_vsys return (const struct pvclock_vsyscall_time_info *)&pvclock_page; } -static notrace u64 vread_pvclock(int *mode) +static notrace u64 vread_pvclock(void) { const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti; u64 ret; @@ -130,10 +105,8 @@ static notrace u64 vread_pvclock(int *mo do { version = pvclock_read_begin(pvti); - if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) { - *mode = VCLOCK_NONE; - return 0; - } + if (unlikely(!(pvti->flags & PVCLOCK_TSC_STABLE_BIT))) + return U64_MAX; ret = __pvclock_read_cycles(pvti, rdtsc_ordered()); } while (pvclock_read_retry(pvti, version)); @@ -148,17 +121,12 @@ static notrace u64 vread_pvclock(int *mo } #endif #ifdef CONFIG_HYPERV_TSCPAGE -static notrace u64 vread_hvclock(int *mode) +static notrace u64 vread_hvclock(void) { const struct ms_hyperv_tsc_page *tsc_pg = (const struct ms_hyperv_tsc_page *)&hvclock_page; - u64 current_tick = hv_read_tsc_page(tsc_pg); - - if (current_tick != U64_MAX) - return current_tick; - *mode = VCLOCK_NONE; - return 0; + return hv_read_tsc_page(tsc_pg); } #endif @@ -182,47 +150,42 @@ notrace static u64 vread_tsc(void) return last; } -notrace static inline u64 vgetsns(int *mode) +notrace static inline u64 vgetcyc(int mode) { - u64 v; - cycles_t cycles; - - if (gtod->vclock_mode == VCLOCK_TSC) - cycles = vread_tsc(); + if (mode == VCLOCK_TSC) + return vread_tsc(); #ifdef CONFIG_PARAVIRT_CLOCK - else if (gtod->vclock_mode == VCLOCK_PVCLOCK) - cycles = vread_pvclock(mode); + else if (mode == VCLOCK_PVCLOCK) + return vread_pvclock(); #endif #ifdef CONFIG_HYPERV_TSCPAGE - else if (gtod->vclock_mode == VCLOCK_HVCLOCK) - cycles = vread_hvclock(mode); + else if (mode == VCLOCK_HVCLOCK) + return vread_hvclock(); #endif - else - return 0; - v = cycles - gtod->cycle_last; - return v * gtod->mult; + return U64_MAX; } notrace static int do_hres(clockid_t clk, struct timespec *ts) { struct vgtod_ts *base = >od->basetime[clk]; unsigned int seq; - int mode; - u64 ns; + u64 cycles, ns; do { seq = gtod_read_begin(gtod); - mode = gtod->vclock_mode; ts->tv_sec = base->sec; ns = base->nsec; - ns += vgetsns(&mode); + cycles = vgetcyc(gtod->vclock_mode); + if (unlikely((s64)cycles < 0)) +
[patch 10/11] x86/vdso: Move cycle_last handling into the caller
Dereferencing gtod->cycle_last all over the place and foing the cycles < last comparison in the vclock read functions generates horrible code. Doing it at the call site is much better and gains a few cycles both for TSC and pvclock. Caveat: This adds the comparison to the hyperv vclock as well, but I have no way to test that. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c | 39 ++- 1 file changed, 7 insertions(+), 32 deletions(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -76,9 +76,8 @@ static notrace const struct pvclock_vsys static notrace u64 vread_pvclock(void) { const struct pvclock_vcpu_time_info *pvti = &get_pvti0()->pvti; - u64 ret; - u64 last; u32 version; + u64 ret; /* * Note: The kernel and hypervisor must guarantee that cpu ID @@ -111,13 +110,7 @@ static notrace u64 vread_pvclock(void) ret = __pvclock_read_cycles(pvti, rdtsc_ordered()); } while (pvclock_read_retry(pvti, version)); - /* refer to vread_tsc() comment for rationale */ - last = gtod->cycle_last; - - if (likely(ret >= last)) - return ret; - - return last; + return ret; } #endif #ifdef CONFIG_HYPERV_TSCPAGE @@ -130,30 +123,10 @@ static notrace u64 vread_hvclock(void) } #endif -notrace static u64 vread_tsc(void) -{ - u64 ret = (u64)rdtsc_ordered(); - u64 last = gtod->cycle_last; - - if (likely(ret >= last)) - return ret; - - /* -* GCC likes to generate cmov here, but this branch is extremely -* predictable (it's just a function of time and the likely is -* very likely) and there's a data dependence, so force GCC -* to generate a branch instead. I don't barrier() because -* we don't actually need a barrier, and if this function -* ever gets inlined it will generate worse code. -*/ - asm volatile (""); - return last; -} - notrace static inline u64 vgetcyc(int mode) { if (mode == VCLOCK_TSC) - return vread_tsc(); + return (u64)rdtsc_ordered(); #ifdef CONFIG_PARAVIRT_CLOCK else if (mode == VCLOCK_PVCLOCK) return vread_pvclock(); @@ -168,17 +141,19 @@ notrace static inline u64 vgetcyc(int mo notrace static int do_hres(clockid_t clk, struct timespec *ts) { struct vgtod_ts *base = >od->basetime[clk]; + u64 cycles, last, ns; unsigned int seq; - u64 cycles, ns; do { seq = gtod_read_begin(gtod); ts->tv_sec = base->sec; ns = base->nsec; + last = gtod->cycle_last; cycles = vgetcyc(gtod->vclock_mode); if (unlikely((s64)cycles < 0)) return vdso_fallback_gettime(clk, ts); - ns += (cycles - gtod->cycle_last) * gtod->mult; + if (cycles > last) + ns += (cycles - last) * gtod->mult; ns >>= gtod->shift; } while (unlikely(gtod_read_retry(gtod, seq))); ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 02/11] x86/time: Implement clocksource_arch_init()
Runtime validate the VCLOCK_MODE in clocksource::archdata and disable VCLOCK if invalid, which disables the VDSO but keeps the system running. Signed-off-by: Thomas Gleixner --- arch/x86/Kconfig |1 + arch/x86/kernel/time.c | 16 2 files changed, 17 insertions(+) --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -48,6 +48,7 @@ config X86 select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI select ANON_INODES select ARCH_CLOCKSOURCE_DATA + select ARCH_CLOCKSOURCE_INIT select ARCH_DISCARD_MEMBLOCK select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI select ARCH_HAS_DEBUG_VIRTUAL --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c @@ -10,6 +10,7 @@ * */ +#include #include #include #include @@ -105,3 +106,18 @@ void __init time_init(void) { late_time_init = x86_late_time_init; } + +/* + * Sanity check the vdso related archdata content. + */ +void clocksource_arch_init(struct clocksource *cs) +{ + if (cs->archdata.vclock_mode == VCLOCK_NONE) + return; + + if (cs->archdata.vclock_mode >= VCLOCK_MAX) { + pr_warn("clocksource %s registered with invalid vclock_mode %d. Disabling vclock.\n", + cs->name, cs->archdata.vclock_mode); + cs->archdata.vclock_mode = VCLOCK_NONE; + } +} ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 07/11] x86/vdso: Collapse coarse functions
do_realtime_coarse() and do_monotonic_coarse() are now the same except for the storage array index. Hand the index in as an argument and collapse the functions. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c | 20 1 file changed, 4 insertions(+), 16 deletions(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -225,21 +225,9 @@ notrace static int do_hres(clockid_t clk return mode; } -notrace static void do_realtime_coarse(struct timespec *ts) +notrace static void do_coarse(clockid_t clk, struct timespec *ts) { - struct vgtod_ts *base = >od->basetime[CLOCK_REALTIME_COARSE]; - unsigned int seq; - - do { - seq = gtod_read_begin(gtod); - ts->tv_sec = base->sec; - ts->tv_nsec = base->nsec; - } while (unlikely(gtod_read_retry(gtod, seq))); -} - -notrace static void do_monotonic_coarse(struct timespec *ts) -{ - struct vgtod_ts *base = >od->basetime[CLOCK_MONOTONIC_COARSE]; + struct vgtod_ts *base = >od->basetime[clk]; unsigned int seq; do { @@ -261,10 +249,10 @@ notrace int __vdso_clock_gettime(clockid goto fallback; break; case CLOCK_REALTIME_COARSE: - do_realtime_coarse(ts); + do_coarse(CLOCK_REALTIME_COARSE, ts); break; case CLOCK_MONOTONIC_COARSE: - do_monotonic_coarse(ts); + do_coarse(CLOCK_MONOTONIC_COARSE, ts); break; default: goto fallback; ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 04/11] x86/vdso: Use unsigned int consistently for vsyscall_gtod_data::seq
The sequence count in vgtod_data is unsigned int, but the call sites use unsigned long, which is a pointless exercise. Fix the call sites and replace 'unsigned' with unsinged 'int' while at it. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c |8 arch/x86/include/asm/vgtod.h | 10 +- 2 files changed, 9 insertions(+), 9 deletions(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -206,7 +206,7 @@ notrace static inline u64 vgetsns(int *m /* Code size doesn't matter (vdso is 4k anyway) and this is faster. */ notrace static int __always_inline do_realtime(struct timespec *ts) { - unsigned long seq; + unsigned int seq; u64 ns; int mode; @@ -227,7 +227,7 @@ notrace static int __always_inline do_re notrace static int __always_inline do_monotonic(struct timespec *ts) { - unsigned long seq; + unsigned int seq; u64 ns; int mode; @@ -248,7 +248,7 @@ notrace static int __always_inline do_mo notrace static void do_realtime_coarse(struct timespec *ts) { - unsigned long seq; + unsigned int seq; do { seq = gtod_read_begin(gtod); ts->tv_sec = gtod->wall_time_coarse_sec; @@ -258,7 +258,7 @@ notrace static void do_realtime_coarse(s notrace static void do_monotonic_coarse(struct timespec *ts) { - unsigned long seq; + unsigned int seq; do { seq = gtod_read_begin(gtod); ts->tv_sec = gtod->monotonic_time_coarse_sec; --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h @@ -15,9 +15,9 @@ typedef unsigned long gtod_long_t; * so be carefull by modifying this structure. */ struct vsyscall_gtod_data { - unsigned seq; + unsigned int seq; - int vclock_mode; + int vclock_mode; u64 cycle_last; u64 mask; u32 mult; @@ -44,9 +44,9 @@ static inline bool vclock_was_used(int v return READ_ONCE(vclocks_used) & (1 << vclock); } -static inline unsigned gtod_read_begin(const struct vsyscall_gtod_data *s) +static inline unsigned int gtod_read_begin(const struct vsyscall_gtod_data *s) { - unsigned ret; + unsigned int ret; repeat: ret = READ_ONCE(s->seq); @@ -59,7 +59,7 @@ static inline unsigned gtod_read_begin(c } static inline int gtod_read_retry(const struct vsyscall_gtod_data *s, - unsigned start) + unsigned int start) { smp_rmb(); return unlikely(s->seq != start); ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 08/11] x86/vdso: Replace the clockid switch case
Now that the time getter functions use the clockid as index into the storage array for the base time access, the switch case can be replaced. - Check for clockid >= MAX_CLOCKS and for negative clockid (CPU/FD) first and call the fallback function right away. - After establishing that clockid is < MAX_CLOCKS, convert the clockid to a bitmask - Check for the supported high resolution and coarse functions by anding the bitmask of supported clocks and check whether a bit is set. This completely avoids jump tables, reduces the number of conditionals and makes the VDSO extensible for other clock ids. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c | 38 --- 1 file changed, 18 insertions(+), 20 deletions(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -239,29 +239,27 @@ notrace static void do_coarse(clockid_t notrace int __vdso_clock_gettime(clockid_t clock, struct timespec *ts) { - switch (clock) { - case CLOCK_REALTIME: - if (do_hres(CLOCK_REALTIME, ts) == VCLOCK_NONE) - goto fallback; - break; - case CLOCK_MONOTONIC: - if (do_hres(CLOCK_MONOTONIC, ts) == VCLOCK_NONE) - goto fallback; - break; - case CLOCK_REALTIME_COARSE: - do_coarse(CLOCK_REALTIME_COARSE, ts); - break; - case CLOCK_MONOTONIC_COARSE: - do_coarse(CLOCK_MONOTONIC_COARSE, ts); - break; - default: - goto fallback; - } + unsigned int msk; + + /* Sort out negative (CPU/FD) and invalid clocks */ + if (unlikely((unsigned int) clock >= MAX_CLOCKS)) + return vdso_fallback_gettime(clock, ts); - return 0; -fallback: + /* +* Convert the clockid to a bitmask and use it to check which +* clocks are handled in the VDSO directly. +*/ + msk = 1U << clock; + if (likely(msk & VGTOD_HRES)) { + if (do_hres(clock, ts) != VCLOCK_NONE) + return 0; + } else if (msk & VGTOD_COARSE) { + do_coarse(clock, ts); + return 0; + } return vdso_fallback_gettime(clock, ts); } + int clock_gettime(clockid_t, struct timespec *) __attribute__((weak, alias("__vdso_clock_gettime"))); ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 11/11] x66/vdso: Add CLOCK_TAI support
With the storage array in place it's now trivial to support CLOCK_TAI in the vdso. Instead of extending the array to accomodate CLOCK_TAI, make use of the fact that: - CLOCK ids are set in stone - CLOCK_THREAD_CPUTIME is never going to be supported in the VDSO so the array slot 3 is unused - CLOCK_TAI is id 11 which results in 3 when masked with 0x3 Add the mask to the basetime array lookup and set up the CLOCK_TAI base time in update_vsyscall(). The performance impact of the mask operation is within the noise. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c|2 +- arch/x86/entry/vsyscall/vsyscall_gtod.c |4 arch/x86/include/asm/vgtod.h|6 +- 3 files changed, 10 insertions(+), 2 deletions(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -140,7 +140,7 @@ notrace static inline u64 vgetcyc(int mo notrace static int do_hres(clockid_t clk, struct timespec *ts) { - struct vgtod_ts *base = >od->basetime[clk]; + struct vgtod_ts *base = >od->basetime[clk & VGTOD_HRES_MASK]; u64 cycles, last, ns; unsigned int seq; --- a/arch/x86/entry/vsyscall/vsyscall_gtod.c +++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c @@ -51,6 +51,10 @@ void update_vsyscall(struct timekeeper * base->sec = tk->xtime_sec; base->nsec = tk->tkr_mono.xtime_nsec; + base = &vdata->basetime[VGTOD_TAI]; + base->sec = tk->xtime_sec + (s64)tk->tai_offset; + base->nsec = tk->tkr_mono.xtime_nsec; + base = &vdata->basetime[CLOCK_MONOTONIC]; base->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; nsec = tk->tkr_mono.xtime_nsec; --- a/arch/x86/include/asm/vgtod.h +++ b/arch/x86/include/asm/vgtod.h @@ -19,9 +19,13 @@ struct vgtod_ts { }; #define VGTOD_BASES(CLOCK_MONOTONIC_COARSE + 1) -#define VGTOD_HRES (BIT(CLOCK_REALTIME) | BIT(CLOCK_MONOTONIC)) +#define VGTOD_HRES (BIT(CLOCK_REALTIME) | BIT(CLOCK_MONOTONIC) | BIT(CLOCK_TAI)) #define VGTOD_COARSE (BIT(CLOCK_REALTIME_COARSE) | BIT(CLOCK_MONOTONIC_COARSE)) +/* Abuse CLOCK_THREAD_CPUTIME_ID for VGTOD CLOCK TAI */ +#define VGTOD_HRES_MASK0x3 +#define VGTOD_TAI (CLOCK_TAI & VGTOD_HRES_MASK) + /* * vsyscall_gtod_data will be accessed by 32 and 64 bit code at the same time * so be carefull by modifying this structure. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 06/11] x86/vdso: Collapse high resolution functions
do_realtime() and do_monotonic() are now the same except for the storage array index. Hand the index in as an argument and collapse the functions. Signed-off-by: Thomas Gleixner --- arch/x86/entry/vdso/vclock_gettime.c | 35 +++ 1 file changed, 7 insertions(+), 28 deletions(-) --- a/arch/x86/entry/vdso/vclock_gettime.c +++ b/arch/x86/entry/vdso/vclock_gettime.c @@ -203,35 +203,12 @@ notrace static inline u64 vgetsns(int *m return v * gtod->mult; } -/* Code size doesn't matter (vdso is 4k anyway) and this is faster. */ -notrace static int __always_inline do_realtime(struct timespec *ts) +notrace static int do_hres(clockid_t clk, struct timespec *ts) { - struct vgtod_ts *base = >od->basetime[CLOCK_REALTIME]; + struct vgtod_ts *base = >od->basetime[clk]; unsigned int seq; - u64 ns; int mode; - - do { - seq = gtod_read_begin(gtod); - mode = gtod->vclock_mode; - ts->tv_sec = base->sec; - ns = base->nsec; - ns += vgetsns(&mode); - ns >>= gtod->shift; - } while (unlikely(gtod_read_retry(gtod, seq))); - - ts->tv_sec += __iter_div_u64_rem(ns, NSEC_PER_SEC, &ns); - ts->tv_nsec = ns; - - return mode; -} - -notrace static int __always_inline do_monotonic(struct timespec *ts) -{ - struct vgtod_ts *base = >od->basetime[CLOCK_MONOTONIC]; - unsigned int seq; u64 ns; - int mode; do { seq = gtod_read_begin(gtod); @@ -276,11 +253,11 @@ notrace int __vdso_clock_gettime(clockid { switch (clock) { case CLOCK_REALTIME: - if (do_realtime(ts) == VCLOCK_NONE) + if (do_hres(CLOCK_REALTIME, ts) == VCLOCK_NONE) goto fallback; break; case CLOCK_MONOTONIC: - if (do_monotonic(ts) == VCLOCK_NONE) + if (do_hres(CLOCK_MONOTONIC, ts) == VCLOCK_NONE) goto fallback; break; case CLOCK_REALTIME_COARSE: @@ -303,7 +280,9 @@ int clock_gettime(clockid_t, struct time notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz) { if (likely(tv != NULL)) { - if (unlikely(do_realtime((struct timespec *)tv) == VCLOCK_NONE)) + struct timespec *ts = (struct timespec *) tv; + + if (unlikely(do_hres(CLOCK_REALTIME, ts) == VCLOCK_NONE)) return vdso_fallback_gtod(tv, tz); tv->tv_usec /= 1000; } ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch 00/11] x86/vdso: Cleanups, simmplifications and CLOCK_TAI support
Matt attempted to add CLOCK_TAI support to the VDSO clock_gettime() implementation, which extended the clockid switch case and added yet another slightly different copy of the same code. Especially the extended switch case is problematic as the compiler tends to generate a jump table which then requires to use retpolines. If jump tables are disabled it adds yet another conditional to the existing maze. This series takes a different approach by consolidating the almost identical functions into one implementation for high resolution clocks and one for the coarse grained clock ids by storing the base data for each clock id in an array which is indexed by the clock id. This completely eliminates the switch case and allows further simplifications of the code base, which at the end all together gain a few cycles performance or at least stay on par with todays code. The resulting performance depends heavily on the micro architecture and the compiler. Thanks, tglx 8<--- arch/x86/Kconfig|1 arch/x86/entry/vdso/vclock_gettime.c| 199 arch/x86/entry/vsyscall/vsyscall_gtod.c | 55 arch/x86/include/asm/vgtod.h| 46 --- arch/x86/kernel/time.c | 22 +++ include/linux/clocksource.h |5 kernel/time/Kconfig |4 kernel/time/clocksource.c |2 8 files changed, 144 insertions(+), 190 deletions(-) ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 00/11] x86/vdso: Cleanups, simmplifications and CLOCK_TAI support
On 09/14/2018 02:50 PM, Thomas Gleixner wrote: Matt attempted to add CLOCK_TAI support to the VDSO clock_gettime() implementation, which extended the clockid switch case and added yet another slightly different copy of the same code. Especially the extended switch case is problematic as the compiler tends to generate a jump table which then requires to use retpolines. Does vDSO code really have to use retpolines? It's in userspace, after all. Thanks, Florian ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 00/11] x86/vdso: Cleanups, simmplifications and CLOCK_TAI support
On Fri, 14 Sep 2018, Florian Weimer wrote: > On 09/14/2018 02:50 PM, Thomas Gleixner wrote: > > Matt attempted to add CLOCK_TAI support to the VDSO clock_gettime() > > implementation, which extended the clockid switch case and added yet > > another slightly different copy of the same code. > > > > Especially the extended switch case is problematic as the compiler tends to > > generate a jump table which then requires to use retpolines. > > Does vDSO code really have to use retpolines? It's in userspace, after all. Unless you have IBRS/STIPB enabled, you need user space ratpoutine as well. Thanks, tglx ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 00/11] x86/vdso: Cleanups, simmplifications and CLOCK_TAI support
On 09/14/2018 03:05 PM, Thomas Gleixner wrote: On Fri, 14 Sep 2018, Florian Weimer wrote: On 09/14/2018 02:50 PM, Thomas Gleixner wrote: Matt attempted to add CLOCK_TAI support to the VDSO clock_gettime() implementation, which extended the clockid switch case and added yet another slightly different copy of the same code. Especially the extended switch case is problematic as the compiler tends to generate a jump table which then requires to use retpolines. Does vDSO code really have to use retpolines? It's in userspace, after all. Unless you have IBRS/STIPB enabled, you need user space ratpoutine as well. I don't think this is a consensus position, and it obviously depends on the (sub)architecture. Thanks, Florian ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 00/11] x86/vdso: Cleanups, simmplifications and CLOCK_TAI support
On Fri, Sep 14, 2018 at 02:56:46PM +0200, Florian Weimer wrote: > On 09/14/2018 02:50 PM, Thomas Gleixner wrote: > > Matt attempted to add CLOCK_TAI support to the VDSO clock_gettime() > > implementation, which extended the clockid switch case and added yet > > another slightly different copy of the same code. > > > > Especially the extended switch case is problematic as the compiler tends to > > generate a jump table which then requires to use retpolines. > > Does vDSO code really have to use retpolines? It's in userspace, after all. Userspace is equally susceptible to spectre-v2. Ideally we'd recompile world with retpoline, but given the amount of inline asm in say things like openssl and similar projects, validating that there are indeed no indirect calls/jumps left is nontrivial. There are currently pending patches to otherwise address user-user spectre-v2 attacks. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 00/11] x86/vdso: Cleanups, simmplifications and CLOCK_TAI support
On Fri, 14 Sep 2018, Florian Weimer wrote: > On 09/14/2018 03:05 PM, Thomas Gleixner wrote: > > On Fri, 14 Sep 2018, Florian Weimer wrote: > > > > > On 09/14/2018 02:50 PM, Thomas Gleixner wrote: > > > > Matt attempted to add CLOCK_TAI support to the VDSO clock_gettime() > > > > implementation, which extended the clockid switch case and added yet > > > > another slightly different copy of the same code. > > > > > > > > Especially the extended switch case is problematic as the compiler tends > > > > to > > > > generate a jump table which then requires to use retpolines. > > > > > > Does vDSO code really have to use retpolines? It's in userspace, after > > > all. > > > > Unless you have IBRS/STIPB enabled, you need user space ratpoutine as well. > > I don't think this is a consensus position, and it obviously depends on the > (sub)architecture. It does, but we are not building kernels for specific micro architectures nor do distros AFAIK. But that aside, even with jump tables the generated code (ratpoutine disabled) is not any better than with the current approach. It's even worse and needs the same optimizations at the end and then the main difference is that you have 3 copies of one function and 2 of the other. Not a win at all. Thanks, tglx ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 2/4] dt-bindings: soc: Document "brcm,bcm2836-vchiq"
"brcm,bcm2836-vchiq" should be used on BCM2836 and BCM2837 to ensure correct operation. Signed-off-by: Phil Elwell --- Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt index 8dd7b3a..f331316 100644 --- a/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt +++ b/Documentation/devicetree/bindings/soc/bcm/brcm,bcm2835-vchiq.txt @@ -2,7 +2,8 @@ Broadcom VCHIQ firmware services Required properties: -- compatible: Should be "brcm,bcm2835-vchiq" +- compatible: Should be "brcm,bcm2835-vchiq" on BCM2835, otherwise + "brcm,bcm2836-vchiq". - reg: Physical base address and length of the doorbell register pair - interrupts: The interrupt number See bindings/interrupt-controller/brcm,bcm2835-armctrl-ic.txt -- 2.7.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 3/4] ARM: dts: bcm283x: Correct vchiq compatible string
To allow VCHIQ to determine the correct cache line size, use the new "brcm,bcm2836-vchiq" compatible string on BCM2836 and BCM2837. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +- arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 2 +- arch/arm/boot/dts/bcm2836-rpi.dtsi | 6 ++ arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +- arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 2 +- arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 2 +- 6 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index cb2d6d7..215d8cc 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -30,7 +30,7 @@ #power-domain-cells = <1>; }; - mailbox@7e00b840 { + vchiq: mailbox@7e00b840 { compatible = "brcm,bcm2835-vchiq"; reg = <0x7e00b840 0xf>; interrupts = <0 2>; diff --git a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts index 2fef70a..ac4408b 100644 --- a/arch/arm/boot/dts/bcm2836-rpi-2-b.dts +++ b/arch/arm/boot/dts/bcm2836-rpi-2-b.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2836.dtsi" -#include "bcm2835-rpi.dtsi" +#include "bcm2836-rpi.dtsi" #include "bcm283x-rpi-smsc9514.dtsi" #include "bcm283x-rpi-usb-host.dtsi" diff --git a/arch/arm/boot/dts/bcm2836-rpi.dtsi b/arch/arm/boot/dts/bcm2836-rpi.dtsi new file mode 100644 index 000..c4c858b --- /dev/null +++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "bcm2835-rpi.dtsi" + +&vchiq { + compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; +}; diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts index 4adb85e..eca36e3 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2837.dtsi" -#include "bcm2835-rpi.dtsi" +#include "bcm2836-rpi.dtsi" #include "bcm283x-rpi-lan7515.dtsi" #include "bcm283x-rpi-usb-host.dtsi" diff --git a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts index c318bcb..a0ba0f6 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-3-b.dts +++ b/arch/arm/boot/dts/bcm2837-rpi-3-b.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2837.dtsi" -#include "bcm2835-rpi.dtsi" +#include "bcm2836-rpi.dtsi" #include "bcm283x-rpi-smsc9514.dtsi" #include "bcm283x-rpi-usb-host.dtsi" diff --git a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi index 7b7ab6a..4a89a18 100644 --- a/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi +++ b/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /dts-v1/; #include "bcm2837.dtsi" -#include "bcm2835-rpi.dtsi" +#include "bcm2836-rpi.dtsi" / { memory { -- 2.7.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 1/4] staging/vc04_services: Use correct cache line size
Use the compatible string in the DTB to select the correct cache line size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. Signed-off-by: Phil Elwell --- .../interface/vchiq_arm/vchiq_2835_arm.c | 4 ++- .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 36 -- .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 5 +++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index e767209..83d740f 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo, int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) { struct device *dev = &pdev->dev; - struct rpi_firmware *fw = platform_get_drvdata(pdev); + struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev); + struct rpi_firmware *fw = drvdata->fw; VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; struct resource *res; void *slot_mem; @@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) if (err < 0) return err; + g_cache_line_size = drvdata->cache_line_size; g_fragments_size = 2 * g_cache_line_size; /* Allocate space for the channels in coherent memory */ diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index bc05c69..b2ae9259 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -170,6 +170,14 @@ static struct device *vchiq_dev; static DEFINE_SPINLOCK(msg_queue_spinlock); static struct platform_device *bcm2835_camera; +static struct vchiq_drvdata bcm2835_drvdata = { + .cache_line_size = 32, +}; + +static struct vchiq_drvdata bcm2836_drvdata = { + .cache_line_size = 64, +}; + static const char *const ioctl_names[] = { "CONNECT", "SHUTDOWN", @@ -3573,12 +3581,26 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, } } +static const struct of_device_id vchiq_of_match[] = { + { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, + { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, + {}, +}; +MODULE_DEVICE_TABLE(of, vchiq_of_match); + static int vchiq_probe(struct platform_device *pdev) { struct device_node *fw_node; - struct rpi_firmware *fw; + const struct of_device_id *of_id; + struct vchiq_drvdata *drvdata; int err; + snd_rpi_simple.dev = &pdev->dev; + of_id = of_match_node(vchiq_of_match, pdev->dev.of_node); + drvdata = of_id->data; + if (!drvdata) + return -EINVAL; + fw_node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware"); if (!fw_node) { @@ -3586,12 +3608,12 @@ static int vchiq_probe(struct platform_device *pdev) return -ENOENT; } - fw = rpi_firmware_get(fw_node); + drvdata->fw = rpi_firmware_get(fw_node); of_node_put(fw_node); - if (!fw) + if (!drvdata->fw) return -EPROBE_DEFER; - platform_set_drvdata(pdev, fw); + platform_set_drvdata(pdev, drvdata); err = vchiq_platform_init(pdev, &g_state); if (err != 0) @@ -3661,12 +3683,6 @@ static int vchiq_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id vchiq_of_match[] = { - { .compatible = "brcm,bcm2835-vchiq", }, - {}, -}; -MODULE_DEVICE_TABLE(of, vchiq_of_match); - static struct platform_driver vchiq_driver = { .driver = { .name = "bcm2835_vchiq", diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h index 40bb0c6..2f3ebc9 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h @@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct { } VCHIQ_ARM_STATE_T; +struct vchiq_drvdata { + const unsigned int cache_line_size; + struct rpi_firmware *fw; +}; + extern int vchiq_arm_log_level; extern int vchiq_susp_log_level; -- 2.7.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 0/4] Improve VCHIQ cache line size handling
Both sides of the VCHIQ communications mechanism need to agree on the cache line size. Using an incorrect value can lead to data corruption, but having the two sides using different values is usually worse. In the absence of an obvious convenient run-time method to determine the correct value in the ARCH=arm world, the downstream Raspberry Pi trees used a Device Tree property, written by the firmware, to configure the kernel driver. This method was vetoed during the upstreaming process, so a fixed value of 32 was used instead, and some corruptions ensued. This is take 2 at arriving at the correct value. Add a new compatible string - "brcm,bcm2836-vchiq" - to indicate an SoC with a 64-byte cache line. Document the new string in the binding, and use it on the appropriate platforms. The final patch is a (seemingly cosmetic) correction of the Device Tree "reg" declaration for the device node, but it doubles as an indication to the Raspberry Pi firmware that the kernel driver is running a recent kernel driver that chooses the correct value. As such it would help if the DT patches are not merged before the driver patch. v2: Replaced ARM-specific logic used to determine cache line size with a new compatible string for BCM2836 and BCM2837. Phil Elwell (4): staging/vc04_services: Use correct cache line size dt-bindings: soc: Document "brcm,bcm2836-vchiq" ARM: dts: bcm283x: Correct vchiq compatible string ARM: dts: bcm283x: Correct mailbox register sizes .../bindings/soc/bcm/brcm,bcm2835-vchiq.txt| 3 +- arch/arm/boot/dts/bcm2835-rpi.dtsi | 4 +-- arch/arm/boot/dts/bcm2836-rpi-2-b.dts | 2 +- arch/arm/boot/dts/bcm2836-rpi.dtsi | 6 arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts | 2 +- arch/arm/boot/dts/bcm2837-rpi-3-b.dts | 2 +- arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 2 +- .../interface/vchiq_arm/vchiq_2835_arm.c | 4 ++- .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 36 -- .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 5 +++ 10 files changed, 48 insertions(+), 18 deletions(-) create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi -- 2.7.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 4/4] ARM: dts: bcm283x: Correct mailbox register sizes
The size field in a Device Tree "reg" property is encoded in bytes, not words. Signed-off-by: Phil Elwell --- arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index 215d8cc..29f970f 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -32,7 +32,7 @@ vchiq: mailbox@7e00b840 { compatible = "brcm,bcm2835-vchiq"; - reg = <0x7e00b840 0xf>; + reg = <0x7e00b840 0x3c>; interrupts = <0 2>; }; }; -- 2.7.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 11/11] x66/vdso: Add CLOCK_TAI support
> On Sep 14, 2018, at 5:50 AM, Thomas Gleixner wrote: > > With the storage array in place it's now trivial to support CLOCK_TAI in > the vdso. Instead of extending the array to accomodate CLOCK_TAI, make use > of the fact that: > > - CLOCK ids are set in stone > - CLOCK_THREAD_CPUTIME is never going to be supported in the VDSO so > the array slot 3 is unused > - CLOCK_TAI is id 11 which results in 3 when masked with 0x3 > > Add the mask to the basetime array lookup and set up the CLOCK_TAI base > time in update_vsyscall(). That’s... horrible. In an amazing way. Can you add BUILD_BUG_ON somewhere to assert that this actually works? > > The performance impact of the mask operation is within the noise. > > Signed-off-by: Thomas Gleixner > --- > arch/x86/entry/vdso/vclock_gettime.c|2 +- > arch/x86/entry/vsyscall/vsyscall_gtod.c |4 > arch/x86/include/asm/vgtod.h|6 +- > 3 files changed, 10 insertions(+), 2 deletions(-) > > --- a/arch/x86/entry/vdso/vclock_gettime.c > +++ b/arch/x86/entry/vdso/vclock_gettime.c > @@ -140,7 +140,7 @@ notrace static inline u64 vgetcyc(int mo > > notrace static int do_hres(clockid_t clk, struct timespec *ts) > { > -struct vgtod_ts *base = >od->basetime[clk]; > +struct vgtod_ts *base = >od->basetime[clk & VGTOD_HRES_MASK]; >u64 cycles, last, ns; >unsigned int seq; > > --- a/arch/x86/entry/vsyscall/vsyscall_gtod.c > +++ b/arch/x86/entry/vsyscall/vsyscall_gtod.c > @@ -51,6 +51,10 @@ void update_vsyscall(struct timekeeper * >base->sec = tk->xtime_sec; >base->nsec = tk->tkr_mono.xtime_nsec; > > +base = &vdata->basetime[VGTOD_TAI]; > +base->sec = tk->xtime_sec + (s64)tk->tai_offset; > +base->nsec = tk->tkr_mono.xtime_nsec; > + >base = &vdata->basetime[CLOCK_MONOTONIC]; >base->sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; >nsec = tk->tkr_mono.xtime_nsec; > --- a/arch/x86/include/asm/vgtod.h > +++ b/arch/x86/include/asm/vgtod.h > @@ -19,9 +19,13 @@ struct vgtod_ts { > }; > > #define VGTOD_BASES(CLOCK_MONOTONIC_COARSE + 1) > -#define VGTOD_HRES(BIT(CLOCK_REALTIME) | BIT(CLOCK_MONOTONIC)) > +#define VGTOD_HRES(BIT(CLOCK_REALTIME) | BIT(CLOCK_MONOTONIC) | > BIT(CLOCK_TAI)) > #define VGTOD_COARSE(BIT(CLOCK_REALTIME_COARSE) | > BIT(CLOCK_MONOTONIC_COARSE)) > > +/* Abuse CLOCK_THREAD_CPUTIME_ID for VGTOD CLOCK TAI */ > +#define VGTOD_HRES_MASK0x3 > +#define VGTOD_TAI(CLOCK_TAI & VGTOD_HRES_MASK) > + > /* > * vsyscall_gtod_data will be accessed by 32 and 64 bit code at the same time > * so be carefull by modifying this structure. > > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 00/11] x86/vdso: Cleanups, simmplifications and CLOCK_TAI support
On Fri, Sep 14, 2018 at 2:52 PM Thomas Gleixner wrote: > > Matt attempted to add CLOCK_TAI support to the VDSO clock_gettime() > implementation, which extended the clockid switch case and added yet > another slightly different copy of the same code. > > Especially the extended switch case is problematic as the compiler tends to > generate a jump table which then requires to use retpolines. If jump tables > are disabled it adds yet another conditional to the existing maze. > > This series takes a different approach by consolidating the almost > identical functions into one implementation for high resolution clocks and > one for the coarse grained clock ids by storing the base data for each > clock id in an array which is indexed by the clock id. > > This completely eliminates the switch case and allows further > simplifications of the code base, which at the end all together gain a few > cycles performance or at least stay on par with todays code. The resulting > performance depends heavily on the micro architecture and the compiler. No objections from my side, just a few general remarks: Deepa and I have discussed the vdso in the past for 2038. I have started a patch that I'll have to redo on top of yours, but that is fine, your cleanup is only going to help here. More generally speaking, Deepa said that she would like to see some generalization on the vdso before adding the time64_t based variants. Your series probably makes x86 diverge more from the others, which makes it harder to consolidate them again, but we might just as well use your new implementation to base the generic one on, and just move the other ones over to that. A couple of architectures (s390, ia64, riscv, powerpc, arm64) implement the vdso as assembler code at the moment, so they won't be as easy to consolidate (other than outright replacing all the code). The other five: arch/x86/entry/vdso/vclock_gettime.c arch/sparc/vdso/vclock_gettime.c arch/nds32/kernel/vdso/gettimeofday.c arch/mips/vdso/gettimeofday.c arch/arm/vdso/vgettimeofday.c are basically all minor variations of the same code base and could be consolidated to some degree. Any suggestions here? Should we plan to do that consolitdation based on your new version, or just add clock_gettime64 in arm32 and x86-32, and then be done with it? The other ones will obviously still be fast for 32-bit time_t and will have a working non-vdso sys_clock_getttime64(). I also wonder about clock_getres(): half the architectures seem to implement it in vdso, but notably arm32 and x86 don't, and I had not expected it to be performance critical given that the result is easily cached in user space. Arnd ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 11/11] x66/vdso: Add CLOCK_TAI support
On Fri, 14 Sep 2018, Andy Lutomirski wrote: > > On Sep 14, 2018, at 5:50 AM, Thomas Gleixner wrote: > > > > With the storage array in place it's now trivial to support CLOCK_TAI in > > the vdso. Instead of extending the array to accomodate CLOCK_TAI, make use > > of the fact that: > > > > - CLOCK ids are set in stone > > - CLOCK_THREAD_CPUTIME is never going to be supported in the VDSO so > > the array slot 3 is unused > > - CLOCK_TAI is id 11 which results in 3 when masked with 0x3 > > > > Add the mask to the basetime array lookup and set up the CLOCK_TAI base > > time in update_vsyscall(). > > That’s... horrible. In an amazing way. Can you add BUILD_BUG_ON somewhere > to assert that this actually works? Sure, but changing any of the clock ids will cause more wreckage than that. Thanks, tglx___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/8] staging: erofs: error handing and more tracepoints
In order to avoid conflicts with cleanup patches, Chao and I think it is better to send reviewed preview patches in the erofs mailing list to the community in time. So here is reviewed & tested patches right now, which clean up and enhance the error handing and add some tracepoints for decompression. Note that in this patchset, bare use of 'unsigned' and NULL comparison are also fixed compared with the preview patches according to the previous discussion in the staging mailing list. Thanks, Gao Xiang Chen Gong (2): staging: erofs: add trace points for reading zipped data staging: erofs: replace BUG_ON with DBG_BUGON in data.c Gao Xiang (6): staging: erofs: fix a missing endian conversion staging: erofs: clean up z_erofs_map_blocks_iter staging: erofs: complete error handing of z_erofs_map_blocks_iter staging: erofs: fix a bug when appling cache strategy staging: erofs: complete error handing of z_erofs_do_read_page staging: erofs: avoid magic constants when initializing clusterbits drivers/staging/erofs/data.c | 31 ++-- drivers/staging/erofs/include/trace/events/erofs.h | 20 ++- drivers/staging/erofs/super.c | 5 +- drivers/staging/erofs/unzip_vle.c | 195 + 4 files changed, 162 insertions(+), 89 deletions(-) -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/8] staging: erofs: fix a missing endian conversion
This patch fixes a missing endian conversion in vle_get_logical_extent_head. Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- drivers/staging/erofs/unzip_vle.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index 21874b7..d16e3dc 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c @@ -1488,6 +1488,7 @@ static erofs_off_t vle_get_logical_extent_head( struct super_block *const sb = inode->i_sb; const unsigned int clusterbits = EROFS_SB(sb)->clusterbits; const unsigned int clustersize = 1 << clusterbits; + unsigned int delta0; if (page->index != blkaddr) { kunmap_atomic(*kaddr_iter); @@ -1502,12 +1503,13 @@ static erofs_off_t vle_get_logical_extent_head( di = *kaddr_iter + vle_extent_blkoff(inode, lcn); switch (vle_cluster_type(di)) { case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: - BUG_ON(!di->di_u.delta[0]); - BUG_ON(lcn < di->di_u.delta[0]); + delta0 = le16_to_cpu(di->di_u.delta[0]); + DBG_BUGON(!delta0); + DBG_BUGON(lcn < delta0); ofs = vle_get_logical_extent_head(inode, page_iter, kaddr_iter, - lcn - di->di_u.delta[0], pcn, flags); + lcn - delta0, pcn, flags); break; case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: *flags ^= EROFS_MAP_ZIPPED; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/8] staging: erofs: clean up z_erofs_map_blocks_iter
This patch mainly introduces `vle_map_blocks_iter_ctx' to clean up z_erofs_map_blocks_iter and vle_get_logical_extent_head. It changes the return value of `vle_get_logical_extent_head' to int for the later error handing. In addition, it also renames `pcn' to `pblk' since only `pblk' exists in erofs compression ondisk format. Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- drivers/staging/erofs/unzip_vle.c | 139 +- 1 file changed, 77 insertions(+), 62 deletions(-) diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index d16e3dc..d6e5956 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c @@ -1410,6 +1410,13 @@ static int z_erofs_vle_normalaccess_readpages( .readpages = z_erofs_vle_normalaccess_readpages, }; +/* + * Variable-sized Logical Extent (Fixed Physical Cluster) Compression Mode + * --- + * VLE compression mode attempts to compress a number of logical data into + * a physical cluster with a fixed size. + * VLE compression mode uses "struct z_erofs_vle_decompressed_index". + */ #define __vle_cluster_advise(x, bit, bits) \ ((le16_to_cpu(x) >> (bit)) & ((1 << (bits)) - 1)) @@ -1465,90 +1472,95 @@ static int z_erofs_vle_normalaccess_readpages( return erofs_blkoff(iloc(sbi, vi->nid) + ofs); } -/* - * Variable-sized Logical Extent (Fixed Physical Cluster) Compression Mode - * --- - * VLE compression mode attempts to compress a number of logical data into - * a physical cluster with a fixed size. - * VLE compression mode uses "struct z_erofs_vle_decompressed_index". - */ -static erofs_off_t vle_get_logical_extent_head( - struct inode *inode, - struct page **page_iter, - void **kaddr_iter, - unsigned int lcn, /* logical cluster number */ - erofs_blk_t *pcn, - unsigned int *flags) +struct vle_map_blocks_iter_ctx { + struct inode *inode; + struct super_block *sb; + unsigned int clusterbits; + + struct page **mpage_ret; + void **kaddr_ret; +}; + +static int +vle_get_logical_extent_head(const struct vle_map_blocks_iter_ctx *ctx, + unsigned int lcn, /* logical cluster number */ + unsigned long long *ofs, + erofs_blk_t *pblk, + unsigned int *flags) { - /* for extent meta */ - struct page *page = *page_iter; - erofs_blk_t blkaddr = vle_extent_blkaddr(inode, lcn); + const unsigned int clustersize = 1 << ctx->clusterbits; + const erofs_blk_t mblk = vle_extent_blkaddr(ctx->inode, lcn); + struct page *mpage = *ctx->mpage_ret; /* extent metapage */ + struct z_erofs_vle_decompressed_index *di; - unsigned long long ofs; - struct super_block *const sb = inode->i_sb; - const unsigned int clusterbits = EROFS_SB(sb)->clusterbits; - const unsigned int clustersize = 1 << clusterbits; - unsigned int delta0; - - if (page->index != blkaddr) { - kunmap_atomic(*kaddr_iter); - unlock_page(page); - put_page(page); + unsigned int cluster_type, delta0; - page = erofs_get_meta_page_nofail(sb, blkaddr, false); - *page_iter = page; - *kaddr_iter = kmap_atomic(page); + if (mpage->index != mblk) { + kunmap_atomic(*ctx->kaddr_ret); + unlock_page(mpage); + put_page(mpage); + + mpage = erofs_get_meta_page_nofail(ctx->sb, mblk, false); + *ctx->mpage_ret = mpage; + *ctx->kaddr_ret = kmap_atomic(mpage); } - di = *kaddr_iter + vle_extent_blkoff(inode, lcn); - switch (vle_cluster_type(di)) { + di = *ctx->kaddr_ret + vle_extent_blkoff(ctx->inode, lcn); + + cluster_type = vle_cluster_type(di); + switch (cluster_type) { case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: delta0 = le16_to_cpu(di->di_u.delta[0]); DBG_BUGON(!delta0); DBG_BUGON(lcn < delta0); - ofs = vle_get_logical_extent_head(inode, - page_iter, kaddr_iter, - lcn - delta0, pcn, flags); - break; + return vle_get_logical_extent_head(ctx, + lcn - delta0, ofs, pblk, flags); case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: *flags ^= EROFS_MAP_ZIPPED; + /* fallthrough */ case Z_EROFS_VLE_CLUSTER_TYPE_HEAD: /* clustersize should be a power of two */ - ofs = ((u64)lcn << clusterbits) + + *ofs = ((u64)lcn << ctx->clusterbits) + (le16_to_cpu(di->di_clusterofs) & (clustersize - 1)); - *pcn = le32_to_cpu(di->di_u.blkaddr); + *pblk = le32_to_cpu(di->di_u.blkaddr); break; default:
[PATCH 3/8] staging: erofs: complete error handing of z_erofs_map_blocks_iter
This patch completes error handing of z_erofs_map_blocks_iter and vle_get_logical_extent_head, including no memory and io error cases. Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- drivers/staging/erofs/unzip_vle.c | 35 ++- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index d6e5956..d4998fe 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c @@ -1500,7 +1500,11 @@ struct vle_map_blocks_iter_ctx { unlock_page(mpage); put_page(mpage); - mpage = erofs_get_meta_page_nofail(ctx->sb, mblk, false); + mpage = erofs_get_meta_page(ctx->sb, mblk, false); + if (IS_ERR(mpage)) { + *ctx->mpage_ret = NULL; + return PTR_ERR(mpage); + } *ctx->mpage_ret = mpage; *ctx->kaddr_ret = kmap_atomic(mpage); } @@ -1511,9 +1515,12 @@ struct vle_map_blocks_iter_ctx { switch (cluster_type) { case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: delta0 = le16_to_cpu(di->di_u.delta[0]); - DBG_BUGON(!delta0); - DBG_BUGON(lcn < delta0); - + if (unlikely(!delta0 || delta0 > lcn)) { + errln("invalid NONHEAD dl0 %u at lcn %u of nid %llu", + delta0, lcn, EROFS_V(ctx->inode)->nid); + DBG_BUGON(1); + return -EIO; + } return vle_get_logical_extent_head(ctx, lcn - delta0, ofs, pblk, flags); case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN: @@ -1526,7 +1533,10 @@ struct vle_map_blocks_iter_ctx { *pblk = le32_to_cpu(di->di_u.blkaddr); break; default: - BUG_ON(1); + errln("unknown cluster type %u at lcn %u of nid %llu", + cluster_type, lcn, EROFS_V(ctx->inode)->nid); + DBG_BUGON(1); + return -EIO; } return 0; } @@ -1582,7 +1592,11 @@ int z_erofs_map_blocks_iter(struct inode *inode, if (mpage != NULL) put_page(mpage); - mpage = erofs_get_meta_page_nofail(ctx.sb, mblk, false); + mpage = erofs_get_meta_page(ctx.sb, mblk, false); + if (IS_ERR(mpage)) { + err = PTR_ERR(mpage); + goto out; + } *mpage_ret = mpage; } else { lock_page(mpage); @@ -1645,8 +1659,11 @@ int z_erofs_map_blocks_iter(struct inode *inode, &pblk, &map->m_flags); mpage = *mpage_ret; - if (unlikely(err)) - goto unmap_out; + if (unlikely(err)) { + if (mpage) + goto unmap_out; + goto out; + } break; default: errln("unknown cluster type %u at offset %llu of nid %llu", @@ -1670,7 +1687,7 @@ int z_erofs_map_blocks_iter(struct inode *inode, map->m_llen, map->m_plen, map->m_flags); /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */ - DBG_BUGON(err < 0); + DBG_BUGON(err < 0 && err != -ENOMEM); return err; } -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 4/8] staging: erofs: fix a bug when appling cache strategy
As described in Kconfig, the last compressed pack should be cached for further reading for either `EROFS_FS_ZIP_CACHE_UNIPOLAR' or `EROFS_FS_ZIP_CACHE_BIPOLAR' by design. However, there is a bug in z_erofs_do_read_page, it will switch `initial' to `false' at the very beginning before it decides to cache the last compressed pack. caching strategy should work properly after appling this patch. Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- drivers/staging/erofs/unzip_vle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index d4998fe..0f2e180 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c @@ -629,7 +629,7 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, /* go ahead the next map_blocks */ debugln("%s: [out-of-range] pos %llu", __func__, offset + cur); - if (!z_erofs_vle_work_iter_end(builder)) + if (z_erofs_vle_work_iter_end(builder)) fe->initial = false; map->m_la = offset + cur; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 5/8] staging: erofs: complete error handing of z_erofs_do_read_page
This patch completes error handing code of z_erofs_do_read_page. PG_error will be set when some read error happens, therefore z_erofs_onlinepage_endio will unlock this page without setting PG_uptodate. Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- drivers/staging/erofs/unzip_vle.c | 20 +++- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index 0f2e180..15c2015 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c @@ -611,7 +611,7 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, enum z_erofs_page_type page_type; unsigned int cur, end, spiltted, index; - int err; + int err = 0; /* register locked file pages as online pages in pack */ z_erofs_onlinepage_init(page); @@ -638,12 +638,11 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, if (unlikely(err)) goto err_out; - /* deal with hole (FIXME! broken now) */ if (unlikely(!(map->m_flags & EROFS_MAP_MAPPED))) goto hitted; DBG_BUGON(map->m_plen != 1 << sbi->clusterbits); - BUG_ON(erofs_blkoff(map->m_pa)); + DBG_BUGON(erofs_blkoff(map->m_pa)); err = z_erofs_vle_work_iter_begin(builder, sb, map, &fe->owned_head); if (unlikely(err)) @@ -688,7 +687,7 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, err = z_erofs_vle_work_add_page(builder, newpage, Z_EROFS_PAGE_TYPE_EXCLUSIVE); - if (!err) + if (likely(!err)) goto retry; } @@ -699,9 +698,10 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, /* FIXME! avoid the last relundant fixup & endio */ z_erofs_onlinepage_fixup(page, index, true); - ++spiltted; - /* also update nr_pages and increase queued_pages */ + /* bump up the number of spiltted parts of a page */ + ++spiltted; + /* also update nr_pages */ work->nr_pages = max_t(pgoff_t, work->nr_pages, index + 1); next_part: /* can be used for verification */ @@ -711,16 +711,18 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, if (end > 0) goto repeat; +out: /* FIXME! avoid the last relundant fixup & endio */ z_erofs_onlinepage_endio(page); debugln("%s, finish page: %pK spiltted: %u map->m_llen %llu", __func__, page, spiltted, map->m_llen); - return 0; + return err; + /* if some error occurred while processing this page */ err_out: - /* TODO: the missing error handing cases */ - return err; + SetPageError(page); + goto out; } static void z_erofs_vle_unzip_kickoff(void *ptr, int bios) -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 6/8] staging: erofs: avoid magic constants when initializing clusterbits
Currently erofs only supports clustersize == blocksize. and clustersize == 2^n * blocksize will be supported in the future. Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- drivers/staging/erofs/super.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c index 2109b03..9e42153 100644 --- a/drivers/staging/erofs/super.c +++ b/drivers/staging/erofs/super.c @@ -116,9 +116,10 @@ static int superblock_read(struct super_block *sb) #endif sbi->islotbits = ffs(sizeof(struct erofs_inode_v1)) - 1; #ifdef CONFIG_EROFS_FS_ZIP - sbi->clusterbits = 12; + /* TODO: clusterbits should be related to inode */ + sbi->clusterbits = blkszbits; - if (1 << (sbi->clusterbits - 12) > Z_EROFS_CLUSTER_MAX_PAGES) + if (1 << (sbi->clusterbits - PAGE_SHIFT) > Z_EROFS_CLUSTER_MAX_PAGES) errln("clusterbits %u is not supported on this kernel", sbi->clusterbits); #endif -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 05/17] compat_ioctl: move more drivers to generic_compat_ioctl_ptrarg
On Wed, Sep 12, 2018 at 05:08:52PM +0200, Arnd Bergmann wrote: > The .ioctl and .compat_ioctl file operations have the same prototype so > they can both point to the same function, which works great almost all > the time when all the commands are compatible. > > One exception is the s390 architecture, where a compat pointer is only > 31 bit wide, and converting it into a 64-bit pointer requires calling > compat_ptr(). Most drivers here will ever run in s390, but since we now > have a generic helper for it, it's easy enough to use it consistently. > > I double-checked all these drivers to ensure that all ioctl arguments > are used as pointers or are ignored, but are not interpreted as integer > values. > > Signed-off-by: Arnd Bergmann > --- > fs/btrfs/super.c| 2 +- Acked-by: David Sterba ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 7/8] staging: erofs: add trace points for reading zipped data
From: Chen Gong This patch adds trace points for reading zipped data. Signed-off-by: Chen Gong Reviewed-by: Chao Yu Reviewed-by: Gao Xiang Signed-off-by: Gao Xiang --- drivers/staging/erofs/include/trace/events/erofs.h | 20 ++-- drivers/staging/erofs/unzip_vle.c | 11 +++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/drivers/staging/erofs/include/trace/events/erofs.h b/drivers/staging/erofs/include/trace/events/erofs.h index 5aead93..660c92f 100644 --- a/drivers/staging/erofs/include/trace/events/erofs.h +++ b/drivers/staging/erofs/include/trace/events/erofs.h @@ -162,7 +162,8 @@ TP_printk("dev = (%d,%d), nid = %llu, la %llu llen %llu flags %s", show_dev_nid(__entry), - __entry->la, __entry->llen, show_map_flags(__entry->flags)) + __entry->la, __entry->llen, + __entry->flags ? show_map_flags(__entry->flags) : "NULL") ); DEFINE_EVENT(erofs__map_blocks_enter, erofs_map_blocks_flatmode_enter, @@ -172,6 +173,13 @@ TP_ARGS(inode, map, flags) ); +DEFINE_EVENT(erofs__map_blocks_enter, z_erofs_map_blocks_iter_enter, + TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, +unsigned int flags), + + TP_ARGS(inode, map, flags) +); + DECLARE_EVENT_CLASS(erofs__map_blocks_exit, TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, unsigned int flags, int ret), @@ -204,7 +212,8 @@ TP_printk("dev = (%d,%d), nid = %llu, flags %s " "la %llu pa %llu llen %llu plen %llu mflags %s ret %d", - show_dev_nid(__entry), show_map_flags(__entry->flags), + show_dev_nid(__entry), + __entry->flags ? show_map_flags(__entry->flags) : "NULL", __entry->la, __entry->pa, __entry->llen, __entry->plen, show_mflags(__entry->mflags), __entry->ret) ); @@ -216,6 +225,13 @@ TP_ARGS(inode, map, flags, ret) ); +DEFINE_EVENT(erofs__map_blocks_exit, z_erofs_map_blocks_iter_exit, + TP_PROTO(struct inode *inode, struct erofs_map_blocks *map, +unsigned int flags, int ret), + + TP_ARGS(inode, map, flags, ret) +); + TRACE_EVENT(erofs_destroy_inode, TP_PROTO(struct inode *inode), diff --git a/drivers/staging/erofs/unzip_vle.c b/drivers/staging/erofs/unzip_vle.c index 15c2015..ad3b7bb 100644 --- a/drivers/staging/erofs/unzip_vle.c +++ b/drivers/staging/erofs/unzip_vle.c @@ -13,6 +13,8 @@ #include "unzip_vle.h" #include +#include + static struct workqueue_struct *z_erofs_workqueue __read_mostly; static struct kmem_cache *z_erofs_workgroup_cachep __read_mostly; @@ -613,6 +615,8 @@ static int z_erofs_do_read_page(struct z_erofs_vle_frontend *fe, unsigned int cur, end, spiltted, index; int err = 0; + trace_erofs_readpage(page, false); + /* register locked file pages as online pages in pack */ z_erofs_onlinepage_init(page); @@ -1348,6 +1352,9 @@ static inline int __z_erofs_vle_normalaccess_readpages( struct page *head = NULL; LIST_HEAD(pagepool); + trace_erofs_readpages(mapping->host, lru_to_page(pages), + nr_pages, false); + #if (EROFS_FS_ZIP_CACHE_LVL >= 2) f.cachedzone_la = (erofs_off_t)lru_to_page(pages)->index << PAGE_SHIFT; #endif @@ -1570,6 +1577,8 @@ int z_erofs_map_blocks_iter(struct inode *inode, unsigned int cluster_type, logical_cluster_ofs; int err = 0; + trace_z_erofs_map_blocks_iter_enter(inode, map, flags); + /* when trying to read beyond EOF, leave it unmapped */ if (unlikely(map->m_la >= inode->i_size)) { DBG_BUGON(!initial); @@ -1688,6 +1697,8 @@ int z_erofs_map_blocks_iter(struct inode *inode, __func__, map->m_la, map->m_pa, map->m_llen, map->m_plen, map->m_flags); + trace_z_erofs_map_blocks_iter_exit(inode, map, flags, err); + /* aggressively BUG_ON iff CONFIG_EROFS_FS_DEBUG is on */ DBG_BUGON(err < 0 && err != -ENOMEM); return err; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 8/8] staging: erofs: replace BUG_ON with DBG_BUGON in data.c
From: Chen Gong This patch replace BUG_ON with DBG_BUGON in data.c, and add necessary error handler. Signed-off-by: Chen Gong Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Signed-off-by: Gao Xiang --- drivers/staging/erofs/data.c | 31 --- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/staging/erofs/data.c b/drivers/staging/erofs/data.c index e191610..6384f73 100644 --- a/drivers/staging/erofs/data.c +++ b/drivers/staging/erofs/data.c @@ -25,7 +25,7 @@ static inline void read_endio(struct bio *bio) struct page *page = bvec->bv_page; /* page is already locked */ - BUG_ON(PageUptodate(page)); + DBG_BUGON(PageUptodate(page)); if (unlikely(err)) SetPageError(page); @@ -110,12 +110,12 @@ static int erofs_map_blocks_flatmode(struct inode *inode, struct erofs_map_blocks *map, int flags) { + int err = 0; erofs_blk_t nblocks, lastblk; u64 offset = map->m_la; struct erofs_vnode *vi = EROFS_V(inode); trace_erofs_map_blocks_flatmode_enter(inode, map, flags); - BUG_ON(is_inode_layout_compression(inode)); nblocks = DIV_ROUND_UP(inode->i_size, PAGE_SIZE); lastblk = nblocks - is_inode_layout_inline(inode); @@ -142,18 +142,27 @@ static int erofs_map_blocks_flatmode(struct inode *inode, map->m_plen = inode->i_size - offset; /* inline data should locate in one meta block */ - BUG_ON(erofs_blkoff(map->m_pa) + map->m_plen > PAGE_SIZE); + if (erofs_blkoff(map->m_pa) + map->m_plen > PAGE_SIZE) { + DBG_BUGON(1); + err = -EIO; + goto err_out; + } + map->m_flags |= EROFS_MAP_META; } else { errln("internal error @ nid: %llu (size %llu), m_la 0x%llx", vi->nid, inode->i_size, map->m_la); - BUG(); + DBG_BUGON(1); + err = -EIO; + goto err_out; } out: map->m_llen = map->m_plen; + +err_out: trace_erofs_map_blocks_flatmode_exit(inode, map, flags, 0); - return 0; + return err; } #ifdef CONFIG_EROFS_FS_ZIP @@ -209,7 +218,7 @@ static inline struct bio *erofs_read_raw_page( erofs_off_t current_block = (erofs_off_t)page->index; int err; - BUG_ON(!nblocks); + DBG_BUGON(!nblocks); if (PageUptodate(page)) { err = 0; @@ -252,7 +261,7 @@ static inline struct bio *erofs_read_raw_page( } /* for RAW access mode, m_plen must be equal to m_llen */ - BUG_ON(map.m_plen != map.m_llen); + DBG_BUGON(map.m_plen != map.m_llen); blknr = erofs_blknr(map.m_pa); blkoff = erofs_blkoff(map.m_pa); @@ -262,7 +271,7 @@ static inline struct bio *erofs_read_raw_page( void *vsrc, *vto; struct page *ipage; - BUG_ON(map.m_plen > PAGE_SIZE); + DBG_BUGON(map.m_plen > PAGE_SIZE); ipage = erofs_get_meta_page(inode->i_sb, blknr, 0); @@ -289,7 +298,7 @@ static inline struct bio *erofs_read_raw_page( } /* pa must be block-aligned for raw reading */ - BUG_ON(erofs_blkoff(map.m_pa) != 0); + DBG_BUGON(erofs_blkoff(map.m_pa)); /* max # of continuous pages */ if (nblocks > DIV_ROUND_UP(map.m_plen, PAGE_SIZE)) @@ -357,7 +366,7 @@ static int erofs_raw_access_readpage(struct file *file, struct page *page) if (IS_ERR(bio)) return PTR_ERR(bio); - BUG_ON(bio != NULL);/* since we have only one bio -- must be NULL */ + DBG_BUGON(bio); /* since we have only one bio -- must be NULL */ return 0; } @@ -395,7 +404,7 @@ static int erofs_raw_access_readpages(struct file *filp, /* pages could still be locked */ put_page(page); } - BUG_ON(!list_empty(pages)); + DBG_BUGON(!list_empty(pages)); /* the rare case (end in gaps) */ if (unlikely(bio != NULL)) -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 11/11] x66/vdso: Add CLOCK_TAI support
> On Sep 14, 2018, at 7:27 AM, Thomas Gleixner wrote: > > On Fri, 14 Sep 2018, Andy Lutomirski wrote: >>> On Sep 14, 2018, at 5:50 AM, Thomas Gleixner wrote: >>> >>> With the storage array in place it's now trivial to support CLOCK_TAI in >>> the vdso. Instead of extending the array to accomodate CLOCK_TAI, make use >>> of the fact that: >>> >>> - CLOCK ids are set in stone >>> - CLOCK_THREAD_CPUTIME is never going to be supported in the VDSO so >>> the array slot 3 is unused >>> - CLOCK_TAI is id 11 which results in 3 when masked with 0x3 >>> >>> Add the mask to the basetime array lookup and set up the CLOCK_TAI base >>> time in update_vsyscall(). >> >> That’s... horrible. In an amazing way. Can you add BUILD_BUG_ON somewhere >> to assert that this actually works? > > Sure, but changing any of the clock ids will cause more wreckage than that. > I’m more concerned that we add a new one and break the magic masking. Maybe two start sharing the same slot. > Thanks, > >tglx ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/8] staging: rtl8188eu: remove unnecessary parentheses
Remove unnecessary parentheses as reported by checkpatch and from conditionals. Signed-off-by: Michael Straube --- .../staging/rtl8188eu/core/rtw_ioctl_set.c| 50 +-- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index 0880f18520a0..9b67f33cb568 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -17,11 +17,11 @@ u8 rtw_do_join(struct adapter *padapter) { struct list_head *plist, *phead; u8 *pibss = NULL; - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); - struct __queue *queue = &(pmlmepriv->scanned_queue); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct __queue *queue = &pmlmepriv->scanned_queue; u8 ret = _SUCCESS; - spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_lock_bh(&pmlmepriv->scanned_queue.lock); phead = get_list_head(queue); plist = phead->next; @@ -36,7 +36,7 @@ u8 rtw_do_join(struct adapter *padapter) pmlmepriv->to_join = true; if (list_empty(&queue->queue)) { - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); /* when set_ssid/set_bssid for rtw_do_join(), but scanning queue is empty */ @@ -60,7 +60,7 @@ u8 rtw_do_join(struct adapter *padapter) } else { int select_ret; - spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); + spin_unlock_bh(&pmlmepriv->scanned_queue.lock); select_ret = rtw_select_and_join_from_scanned_queue(pmlmepriv); if (select_ret == _SUCCESS) { pmlmepriv->to_join = false; @@ -71,7 +71,7 @@ u8 rtw_do_join(struct adapter *padapter) /* submit createbss_cmd to change to a ADHOC_MASTER */ /* pmlmepriv->lock has been acquired by caller... */ - struct wlan_bssid_ex*pdev_network = &(padapter->registrypriv.dev_network); + struct wlan_bssid_ex*pdev_network = &padapter->registrypriv.dev_network; pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE; @@ -172,7 +172,7 @@ u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid) if (padapter->securitypriv.btkip_countermeasure) { cur_time = jiffies; - if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) { + if (cur_time - padapter->securitypriv.btkip_countermeasure_time > 60 * HZ) { padapter->securitypriv.btkip_countermeasure = false; padapter->securitypriv.btkip_countermeasure_time = 0; } else { @@ -229,8 +229,8 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); - if ((pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength) && - (!memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength))) { + if (pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength && + !memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength)) { if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state = 0x%08x\n", @@ -279,7 +279,7 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) if (padapter->securitypriv.btkip_countermeasure) { cur_time = jiffies; - if ((cur_time - padapter->securitypriv.btkip_countermeasure_time) > 60 * HZ) { + if (cur_time - padapter->securitypriv.btkip_countermeasure_time > 60 * HZ) { padapter->securitypriv.btkip_countermeasure = false; padapter->securitypriv.btkip_countermeasure_time = 0; } else { @@ -310,7 +310,7 @@ u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network*cur_network = &pmlmepriv->cur_network; - enum ndis_802_11_network_infra *pold_state = &(cur_network->network.InfrastructureMode); + enum ndis_802_11_network_infra *pold_state = &cur_network->network.InfrastructureMode; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, ("+rtw_set_802_11_infrastructure_mode: old =%d new =%d
[PATCH 5/8] staging: rtl8188eu: fix comparsions to false
Use if(!x) instead of if(x == false). Signed-off-by: Michael Straube --- drivers/staging/rtl8188eu/core/rtw_ioctl_set.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index bd82de044bba..db983f15ddd6 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -145,7 +145,7 @@ u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid) RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) { - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false) + if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) goto release_mlme_lock;/* it means driver is in WIFI_ADHOC_MASTER_STATE, we needn't create bss again. */ } else { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("Set BSSID not the same bssid\n")); @@ -231,7 +231,7 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) if (pmlmepriv->assoc_ssid.SsidLength == ssid->SsidLength && !memcmp(&pmlmepriv->assoc_ssid.Ssid, ssid->Ssid, ssid->SsidLength)) { - if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == false)) { + if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("Set SSID is the same ssid, fw_state = 0x%08x\n", get_fwstate(pmlmepriv))); -- 2.19.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 8/8] staging: rtl8188eu: simplify function comments
Simplify function comments to a single line. Signed-off-by: Michael Straube --- drivers/staging/rtl8188eu/core/rtw_ioctl_set.c | 15 ++- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index c291d3a0fdcc..0b3eb0b40975 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -530,12 +530,7 @@ u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep) return ret; } -/* -* rtw_get_cur_max_rate - -* @adapter: pointer to struct adapter structure -* -* Return 0 or 100Kbps -*/ +/* Return 0 or 100Kbps */ u16 rtw_get_cur_max_rate(struct adapter *adapter) { int i = 0; @@ -586,13 +581,7 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter) return max_rate; } -/* -* rtw_set_country - -* @adapter: pointer to struct adapter structure -* @country_code: string of country code -* -* Return _SUCCESS or _FAIL -*/ +/* Return _SUCCESS or _FAIL */ int rtw_set_country(struct adapter *adapter, const char *country_code) { int i; -- 2.19.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 6/8] staging: rtl8188eu: add missing spaces around operators
Add missing spaces around '|', '-', and '&' to follow kernel coding style. Reported by checkpatch. Signed-off-by: Michael Straube --- drivers/staging/rtl8188eu/core/rtw_ioctl_set.c | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index db983f15ddd6..d6d6a232c4ec 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -141,7 +141,7 @@ u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid) else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) goto release_mlme_lock; - if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) { + if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_bssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); if (!memcmp(&pmlmepriv->cur_network.network.MacAddress, bssid, ETH_ALEN)) { @@ -225,7 +225,7 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) goto release_mlme_lock; - if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) { + if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE)) { RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n")); @@ -409,14 +409,14 @@ u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_s goto exit; } - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) || + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) || pmlmepriv->LinkDetectInfo.bBusyTraffic) { /* Scan or linking is in progress, do nothing. */ RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("%s fail since fw_state = %x\n", __func__, get_fwstate(pmlmepriv))); res = true; if (check_fwstate(pmlmepriv, - _FW_UNDER_SURVEY|_FW_UNDER_LINKING)) + _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###_FW_UNDER_SURVEY|_FW_UNDER_LINKING\n\n")); else RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("\n###pmlmepriv->sitesurveyctrl.traffic_busy == true\n\n")); @@ -550,8 +550,8 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter) !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) return 0; - if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N|WIRELESS_11_5N)) { - p = rtw_get_ie(&pcur_bss->ies[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->ie_length-12); + if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11_5N)) { + p = rtw_get_ie(&pcur_bss->ies[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->ie_length - 12); if (p && ht_ielen > 0) { /* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */ bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0; @@ -569,7 +569,7 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter) } } else { while (pcur_bss->SupportedRates[i] != 0 && pcur_bss->SupportedRates[i] != 0xFF) { - rate = pcur_bss->SupportedRates[i]&0x7F; + rate = pcur_bss->SupportedRates[i] & 0x7F; if (rate > max_rate) max_rate = rate; i++; -- 2.19.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 7/8] staging: rtl8188eu: fix lines over 80 characters
Wrap lines over 80 characters where appropriate to clear checkpatch warnings. Signed-off-by: Michael Straube --- drivers/staging/rtl8188eu/core/rtw_ioctl_set.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index d6d6a232c4ec..c291d3a0fdcc 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -339,7 +339,8 @@ u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) rtw_free_assoc_resources(padapter); - if (*pold_state == Ndis802_11Infrastructure || *pold_state == Ndis802_11IBSS) { + if (*pold_state == Ndis802_11Infrastructure || + *pold_state == Ndis802_11IBSS) { if (check_fwstate(pmlmepriv, _FW_LINKED)) rtw_indicate_disconnect(padapter); /* will clr Linked_state; before this function, we must have checked whether issue dis-assoc_cmd or not */ } @@ -444,7 +445,8 @@ u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11 int res; u8 ret; - RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, ("set_802_11_auth.mode(): mode =%x\n", authmode)); + RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_, +("set_802_11_auth.mode(): mode =%x\n", authmode)); psecuritypriv->ndisauthtype = authmode; @@ -497,7 +499,8 @@ u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep) ("rtw_set_802_11_add_wep:before memcpy, wep->KeyLength = 0x%x wep->KeyIndex = 0x%x keyid =%x\n", wep->KeyLength, wep->KeyIndex, keyid)); - memcpy(&psecuritypriv->dot11DefKey[keyid].skey[0], &wep->KeyMaterial, wep->KeyLength); + memcpy(&psecuritypriv->dot11DefKey[keyid].skey[0], + &wep->KeyMaterial, wep->KeyLength); psecuritypriv->dot11DefKeylen[keyid] = wep->KeyLength; @@ -551,7 +554,8 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter) return 0; if (pmlmeext->cur_wireless_mode & (WIRELESS_11_24N | WIRELESS_11_5N)) { - p = rtw_get_ie(&pcur_bss->ies[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->ie_length - 12); + p = rtw_get_ie(&pcur_bss->ies[12], _HT_CAPABILITY_IE_, + &ht_ielen, pcur_bss->ie_length - 12); if (p && ht_ielen > 0) { /* cur_bwmod is updated by beacon, pmlmeinfo is updated by association response */ bw_40MHz = (pmlmeext->cur_bwmode && (HT_INFO_HT_PARAM_REC_TRANS_CHNL_WIDTH & pmlmeinfo->HT_info.infos[0])) ? 1 : 0; @@ -568,7 +572,8 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter) ); } } else { - while (pcur_bss->SupportedRates[i] != 0 && pcur_bss->SupportedRates[i] != 0xFF) { + while (pcur_bss->SupportedRates[i] != 0 && + pcur_bss->SupportedRates[i] != 0xFF) { rate = pcur_bss->SupportedRates[i] & 0x7F; if (rate > max_rate) max_rate = rate; -- 2.19.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/8] staging: rtl8188eu: simplify calculation
Simpliy calcualation: * 10 / 2 can be reduced to * 5 Also cleans missing spaces checkpatch issues. Signed-off-by: Michael Straube --- drivers/staging/rtl8188eu/core/rtw_ioctl_set.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index c040f185074b..0880f18520a0 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -575,7 +575,7 @@ u16 rtw_get_cur_max_rate(struct adapter *adapter) i++; } - max_rate = max_rate*10/2; + max_rate *= 5; } return max_rate; -- 2.19.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 3/8] staging: rtl8188eu: remove whitespace
Replace tabs with spaces or just remove spaces in declarations. Signed-off-by: Michael Straube --- .../staging/rtl8188eu/core/rtw_ioctl_set.c| 34 +-- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index 9b67f33cb568..a00272540846 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -17,8 +17,8 @@ u8 rtw_do_join(struct adapter *padapter) { struct list_head *plist, *phead; u8 *pibss = NULL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct __queue *queue = &pmlmepriv->scanned_queue; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct __queue *queue = &pmlmepriv->scanned_queue; u8 ret = _SUCCESS; spin_lock_bh(&pmlmepriv->scanned_queue.lock); @@ -308,8 +308,8 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) u8 rtw_set_802_11_infrastructure_mode(struct adapter *padapter, enum ndis_802_11_network_infra networktype) { - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_network*cur_network = &pmlmepriv->cur_network; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct wlan_network *cur_network = &pmlmepriv->cur_network; enum ndis_802_11_network_infra *pold_state = &cur_network->network.InfrastructureMode; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_, @@ -394,8 +394,8 @@ u8 rtw_set_802_11_disassociate(struct adapter *padapter) u8 rtw_set_802_11_bssid_list_scan(struct adapter *padapter, struct ndis_802_11_ssid *pssid, int ssid_max_num) { - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - u8 res = true; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + u8 res = true; RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_, ("+%s(), fw_state =%x\n", __func__, get_fwstate(pmlmepriv))); @@ -467,9 +467,9 @@ u8 rtw_set_802_11_authentication_mode(struct adapter *padapter, enum ndis_802_11 u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep) { - int keyid, res; + int keyid, res; struct security_priv *psecuritypriv = &padapter->securitypriv; - u8 ret = _SUCCESS; + u8 ret = _SUCCESS; keyid = wep->KeyIndex & 0x3fff; @@ -535,16 +535,16 @@ u8 rtw_set_802_11_add_wep(struct adapter *padapter, struct ndis_802_11_wep *wep) */ u16 rtw_get_cur_max_rate(struct adapter *adapter) { - int i = 0; - u8 *p; - u16 rate = 0, max_rate = 0; - struct mlme_ext_priv*pmlmeext = &adapter->mlmeextpriv; - struct mlme_ext_info*pmlmeinfo = &pmlmeext->mlmext_info; + int i = 0; + u8 *p; + u16 rate = 0, max_rate = 0; + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct registry_priv *pregistrypriv = &adapter->registrypriv; - struct mlme_priv*pmlmepriv = &adapter->mlmepriv; - struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; - u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0; - u32 ht_ielen = 0; + struct mlme_priv *pmlmepriv = &adapter->mlmepriv; + struct wlan_bssid_ex *pcur_bss = &pmlmepriv->cur_network.network; + u8 bw_40MHz = 0, short_GI_20 = 0, short_GI_40 = 0; + u32 ht_ielen = 0; if (!check_fwstate(pmlmepriv, _FW_LINKED) && !check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) -- 2.19.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 4/8] staging: rtl8188eu: fix comparsions to true
Use if(x) instead of if(x == true). Signed-off-by: Michael Straube --- .../staging/rtl8188eu/core/rtw_ioctl_set.c| 26 +-- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c index a00272540846..bd82de044bba 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c +++ b/drivers/staging/rtl8188eu/core/rtw_ioctl_set.c @@ -67,7 +67,7 @@ u8 rtw_do_join(struct adapter *padapter) mod_timer(&pmlmepriv->assoc_timer, jiffies + msecs_to_jiffies(MAX_JOIN_TIMEOUT)); } else { - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* submit createbss_cmd to change to a ADHOC_MASTER */ /* pmlmepriv->lock has been acquired by caller... */ @@ -136,7 +136,7 @@ u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid) spin_lock_bh(&pmlmepriv->lock); DBG_88E("Set BSSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv)); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) goto handle_tkip_countermeasure; else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) goto release_mlme_lock; @@ -154,12 +154,12 @@ u8 rtw_set_802_11_bssid(struct adapter *padapter, u8 *bssid) rtw_disassoc_cmd(padapter, 0, true); - if (check_fwstate(pmlmepriv, _FW_LINKED) == true) + if (check_fwstate(pmlmepriv, _FW_LINKED)) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter); - if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } @@ -220,9 +220,9 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) spin_lock_bh(&pmlmepriv->lock); DBG_88E("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv)); - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) goto handle_tkip_countermeasure; - else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) + else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) goto release_mlme_lock; if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) { @@ -240,12 +240,12 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) /* if in WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE, create bss or rejoin again */ rtw_disassoc_cmd(padapter, 0, true); - if (check_fwstate(pmlmepriv, _FW_LINKED) == true) + if (check_fwstate(pmlmepriv, _FW_LINKED)) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter); - if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } @@ -262,12 +262,12 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) rtw_disassoc_cmd(padapter, 0, true); - if (check_fwstate(pmlmepriv, _FW_LINKED) == true) + if (check_fwstate(pmlmepriv, _FW_LINKED)) rtw_indicate_disconnect(padapter); rtw_free_assoc_resources(padapter); - if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE); set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); } @@ -291,7 +291,7 @@ u8 rtw_set_802_11_ssid(struct adapter *padapter, struct ndis_802_11_ssid *ssid) memcpy(&pmlmepriv->assoc_ssid, ssid, sizeof(struct ndis_802_11_ssid)); pmlmepriv->assoc_by_bssid = false
Re: [PATCH v2] staging: Convert to using %pOFn instead of device_node.name
On Thu, 2018-09-13 at 16:26 -0500, Rob Herring wrote: > On Thu, Sep 13, 2018 at 3:45 PM Joe Perches wrote: > > > > On Wed, 2018-09-12 at 15:26 -0500, Rob Herring wrote: > > > A problem with MAINTAINERS is there is no way to tell who applies > > > patches for a given path vs. anyone else listed. > > > > try the --scm option > > That kind of helps if the maintainer has listed a tree, but gives > wrong results if not. If there isn't a tree listed, it's not really maintained. > And you still have to figure out who owns which > tree. That's not hard, but it's not scriptable. a get_maintainer scripted loop using --maxdepth= --scm --m --nor --nol until a result could work. > IMO, we should reserve 'M:' for maintainers with trees and use 'R:' > driver maintainers. That's redefining M as "maintainer" rather than > "mail patches to". You could still have both for a entry so you can > know who to go bug when your patch hasn't been applied. IMO, most M: entries in MAINTAINERS are either reviewers or used-once when created and longer active or just vanity. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/4] staging/vc04_services: Use correct cache line size
On 14/09/2018 14:22, Phil Elwell wrote: Use the compatible string in the DTB to select the correct cache line size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. Signed-off-by: Phil Elwell --- .../interface/vchiq_arm/vchiq_2835_arm.c | 4 ++- .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 36 -- .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 5 +++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c index e767209..83d740f 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c @@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo, int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) { struct device *dev = &pdev->dev; - struct rpi_firmware *fw = platform_get_drvdata(pdev); + struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev); + struct rpi_firmware *fw = drvdata->fw; VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; struct resource *res; void *slot_mem; @@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) if (err < 0) return err; + g_cache_line_size = drvdata->cache_line_size; g_fragments_size = 2 * g_cache_line_size; /* Allocate space for the channels in coherent memory */ diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index bc05c69..b2ae9259 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -170,6 +170,14 @@ static struct device *vchiq_dev; static DEFINE_SPINLOCK(msg_queue_spinlock); static struct platform_device *bcm2835_camera; +static struct vchiq_drvdata bcm2835_drvdata = { + .cache_line_size = 32, +}; + +static struct vchiq_drvdata bcm2836_drvdata = { + .cache_line_size = 64, +}; + static const char *const ioctl_names[] = { "CONNECT", "SHUTDOWN", @@ -3573,12 +3581,26 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, } } +static const struct of_device_id vchiq_of_match[] = { + { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, + { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, + {}, +}; +MODULE_DEVICE_TABLE(of, vchiq_of_match); + static int vchiq_probe(struct platform_device *pdev) { struct device_node *fw_node; - struct rpi_firmware *fw; + const struct of_device_id *of_id; + struct vchiq_drvdata *drvdata; int err; + snd_rpi_simple.dev = &pdev->dev; + of_id = of_match_node(vchiq_of_match, pdev->dev.of_node); + drvdata = of_id->data; + if (!drvdata) + return -EINVAL; + fw_node = of_find_compatible_node(NULL, NULL, "raspberrypi,bcm2835-firmware"); if (!fw_node) { @@ -3586,12 +3608,12 @@ static int vchiq_probe(struct platform_device *pdev) return -ENOENT; } - fw = rpi_firmware_get(fw_node); + drvdata->fw = rpi_firmware_get(fw_node); of_node_put(fw_node); - if (!fw) + if (!drvdata->fw) return -EPROBE_DEFER; - platform_set_drvdata(pdev, fw); + platform_set_drvdata(pdev, drvdata); err = vchiq_platform_init(pdev, &g_state); if (err != 0) @@ -3661,12 +3683,6 @@ static int vchiq_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id vchiq_of_match[] = { - { .compatible = "brcm,bcm2835-vchiq", }, - {}, -}; -MODULE_DEVICE_TABLE(of, vchiq_of_match); - static struct platform_driver vchiq_driver = { .driver = { .name = "bcm2835_vchiq", diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h index 40bb0c6..2f3ebc9 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h @@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct { } VCHIQ_ARM_STATE_T; +struct vchiq_drvdata { + const unsigned int cache_line_size; + struct rpi_firmware *fw; +}; + extern int vchiq_arm_log_level; extern int vchiq_susp_log_level; This version doesn't compile (wrong defconfig used when building), but any criticism of the approach before v3 is welcome. Phil ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 2/7] staging: erofs: code cleanup for option parsing of fault_injection
On 2018/9/13 13:46, cgxu519 wrote: > On 09/13/2018 10:15 AM, Chao Yu wrote: >> On 2018/9/12 13:10, Chengguang Xu wrote: >>> Define a dummpy function of erofs_build_fault_attr() when macro >>> CONFIG_EROFS_FAULT_INJECTION is disabled, so that we don't have to >>> check the macro in calling place. Based on above adjustment, >>> do proper code cleanup for option parsing of fault_injection. >>> >>> Signed-off-by: Chengguang Xu >>> --- >>> drivers/staging/erofs/super.c | 33 ++--- >>> 1 file changed, 22 insertions(+), 11 deletions(-) >>> >>> diff --git a/drivers/staging/erofs/super.c b/drivers/staging/erofs/super.c >>> index 1aec509c805f..14dbb6517b8d 100644 >>> --- a/drivers/staging/erofs/super.c >>> +++ b/drivers/staging/erofs/super.c >>> @@ -144,18 +144,33 @@ char *erofs_fault_name[FAULT_MAX] = { >>> [FAULT_KMALLOC] = "kmalloc", >>> }; >>> -static void erofs_build_fault_attr(struct erofs_sb_info *sbi, >>> - unsigned int rate) >>> +static int erofs_build_fault_attr(struct erofs_sb_info *sbi, >>> + substring_t *args) >>> { >>> struct erofs_fault_info *ffi = &sbi->fault_info; >>> + int rate = 0; >>> + >>> + if (args->from && match_int(args, &rate)) >>> + return -EINVAL; >>> if (rate) { >>> atomic_set(&ffi->inject_ops, 0); >>> ffi->inject_rate = rate; >>> ffi->inject_type = (1 << FAULT_MAX) - 1; >>> + set_opt(sbi, FAULT_INJECTION); >>> } else { >>> memset(ffi, 0, sizeof(struct erofs_fault_info)); >>> + clear_opt(sbi, FAULT_INJECTION); >> Hmmm, if user mounts/remounts image with -o fault_injection=0, user can not >> check such info in anywhere, as we skip showing this option due to lack of >> EROFS_MOUNT_FAULT_INJECTION bit. How about keeping this bit? >> > > IIUC, the purpose of fault_injection=0 is for disabling fault injection > function, > so isn't it the same as default? Should we distinguish explicit setting value > 0 IMO, if user set fault_injection=0 during mount, it means user want to enable this feature but currently user want to set the rate to zero, later user may change it to non-zero. And with EROFS_MOUNT_FAULT_INJECTION being set, user can check current rate value via ->show_options. Thanks, > and default value 0? > > Thanks, > Chengguang > > > > > > ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 10/11] x86/vdso: Move cycle_last handling into the caller
Thomas Gleixner writes: > Dereferencing gtod->cycle_last all over the place and foing the cycles < > last comparison in the vclock read functions generates horrible code. Doing > it at the call site is much better and gains a few cycles both for TSC and > pvclock. > > Caveat: This adds the comparison to the hyperv vclock as well, but I have > no way to test that. While the change looks obviously correct for Hyper-V vclock too, by saying that you encouraged me to give the whole series a shot. I did and turns out Hyper-V vclock is broken: simple clock_gettime(CLOCK_REALTIME, ) test goes from 70 cpu cycles to 1000 (meaning that we're falling back to syscall I guess). Bisecting now, stay tuned! -- Vitaly ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 02/11] x86/time: Implement clocksource_arch_init()
Thomas Gleixner writes: > Runtime validate the VCLOCK_MODE in clocksource::archdata and disable > VCLOCK if invalid, which disables the VDSO but keeps the system running. > > Signed-off-by: Thomas Gleixner > --- > arch/x86/Kconfig |1 + > arch/x86/kernel/time.c | 16 > 2 files changed, 17 insertions(+) > > --- a/arch/x86/Kconfig > +++ b/arch/x86/Kconfig > @@ -48,6 +48,7 @@ config X86 > select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI > select ANON_INODES > select ARCH_CLOCKSOURCE_DATA > + select ARCH_CLOCKSOURCE_INIT > select ARCH_DISCARD_MEMBLOCK > select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI > select ARCH_HAS_DEBUG_VIRTUAL > --- a/arch/x86/kernel/time.c > +++ b/arch/x86/kernel/time.c > @@ -10,6 +10,7 @@ > * > */ > > +#include > #include > #include > #include > @@ -105,3 +106,18 @@ void __init time_init(void) > { > late_time_init = x86_late_time_init; > } > + > +/* > + * Sanity check the vdso related archdata content. > + */ > +void clocksource_arch_init(struct clocksource *cs) > +{ > + if (cs->archdata.vclock_mode == VCLOCK_NONE) > + return; > + > + if (cs->archdata.vclock_mode >= VCLOCK_MAX) { It should be '>' as VCLOCK_MAX == VCLOCK_HVCLOCK == 3 > + pr_warn("clocksource %s registered with invalid vclock_mode %d. > Disabling vclock.\n", > + cs->name, cs->archdata.vclock_mode); > + cs->archdata.vclock_mode = VCLOCK_NONE; > + } > +} -- Vitaly ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/6] fix Hyper-V uio restart
This set of patches fixes the problem where DPDK applications using hv_uio_generic driver can not be successfully restarted. In order to get this working it required small change to uio to allow for mapping without no-cache. And refactoring of how ring buffer is setup in vmbus code. It could be backported as a fix, to 4.19 but that is not an LTS so probably not worth it. v2 - add refcount unwind in hv_uio_generic open in case of error Stephen Hemminger (6): vmbus: pass channel to hv_process_channel_removal vmbus: keep pointer to ring buffer page vmbus: split ring buffer allocation from open uio: introduce UIO_MEM_IOVA hv_uio_generic: map ringbuffer phys addr uio_hv_generic: defer opening vmbus until first use drivers/hv/channel.c | 276 --- drivers/hv/channel_mgmt.c| 17 +-- drivers/hv/ring_buffer.c | 1 + drivers/hv/vmbus_drv.c | 3 +- drivers/uio/uio.c| 24 +-- drivers/uio/uio_hv_generic.c | 109 ++ include/linux/hyperv.h | 13 +- include/linux/uio_driver.h | 1 + 8 files changed, 264 insertions(+), 180 deletions(-) -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 3/6] vmbus: split ring buffer allocation from open
The UIO driver needs the ring buffer to be persistent(reused) across open/close. Split the allocation and setup of ring buffer out of vmbus_open. For normal usage vmbus_open/vmbus_close there are no changes; only impacts uio_hv_generic which needs to keep ring buffer memory and reuse when application restarts. Signed-off-by: Stephen Hemminger --- drivers/hv/channel.c | 267 ++- drivers/hv/ring_buffer.c | 1 + include/linux/hyperv.h | 9 ++ 3 files changed, 162 insertions(+), 115 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 56ec0d96d876..ddadb7efd1cc 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -79,84 +79,96 @@ void vmbus_setevent(struct vmbus_channel *channel) } EXPORT_SYMBOL_GPL(vmbus_setevent); -/* - * vmbus_open - Open the specified channel. - */ -int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, -u32 recv_ringbuffer_size, void *userdata, u32 userdatalen, -void (*onchannelcallback)(void *context), void *context) +/* vmbus_free_ring - drop mapping of ring buffer */ +void vmbus_free_ring(struct vmbus_channel *channel) { - struct vmbus_channel_open_channel *open_msg; - struct vmbus_channel_msginfo *open_info = NULL; - unsigned long flags; - int ret, err = 0; - struct page *page; - unsigned int order; + hv_ringbuffer_cleanup(&channel->outbound); + hv_ringbuffer_cleanup(&channel->inbound); - if (send_ringbuffer_size % PAGE_SIZE || - recv_ringbuffer_size % PAGE_SIZE) - return -EINVAL; + if (channel->ringbuffer_page) { + __free_pages(channel->ringbuffer_page, +get_order(channel->ringbuffer_pagecount + << PAGE_SHIFT)); + channel->ringbuffer_page = NULL; + } +} +EXPORT_SYMBOL_GPL(vmbus_free_ring); - order = get_order(send_ringbuffer_size + recv_ringbuffer_size); +/* vmbus_alloc_ring - allocate and map pages for ring buffer */ +int vmbus_alloc_ring(struct vmbus_channel *newchannel, +u32 send_size, u32 recv_size) +{ + struct page *page; + int order; - spin_lock_irqsave(&newchannel->lock, flags); - if (newchannel->state == CHANNEL_OPEN_STATE) { - newchannel->state = CHANNEL_OPENING_STATE; - } else { - spin_unlock_irqrestore(&newchannel->lock, flags); + if (send_size % PAGE_SIZE || recv_size % PAGE_SIZE) return -EINVAL; - } - spin_unlock_irqrestore(&newchannel->lock, flags); - - newchannel->onchannel_callback = onchannelcallback; - newchannel->channel_callback_context = context; /* Allocate the ring buffer */ + order = get_order(send_size + recv_size); page = alloc_pages_node(cpu_to_node(newchannel->target_cpu), GFP_KERNEL|__GFP_ZERO, order); if (!page) page = alloc_pages(GFP_KERNEL|__GFP_ZERO, order); - if (!page) { - err = -ENOMEM; - goto error_set_chnstate; - } + if (!page) + return -ENOMEM; newchannel->ringbuffer_page = page; - newchannel->ringbuffer_pagecount = (send_ringbuffer_size + - recv_ringbuffer_size) >> PAGE_SHIFT; + newchannel->ringbuffer_pagecount = (send_size + recv_size) >> PAGE_SHIFT; + newchannel->ringbuffer_send_offset = send_size >> PAGE_SHIFT; - ret = hv_ringbuffer_init(&newchannel->outbound, page, -send_ringbuffer_size >> PAGE_SHIFT); + return 0; +} +EXPORT_SYMBOL_GPL(vmbus_alloc_ring); - if (ret != 0) { - err = ret; - goto error_free_pages; - } +static int __vmbus_open(struct vmbus_channel *newchannel, + void *userdata, u32 userdatalen, + void (*onchannelcallback)(void *context), void *context) +{ + struct vmbus_channel_open_channel *open_msg; + struct vmbus_channel_msginfo *open_info = NULL; + struct page *page = newchannel->ringbuffer_page; + u32 send_pages, recv_pages; + unsigned long flags; + int err; - ret = hv_ringbuffer_init(&newchannel->inbound, -&page[send_ringbuffer_size >> PAGE_SHIFT], -recv_ringbuffer_size >> PAGE_SHIFT); - if (ret != 0) { - err = ret; - goto error_free_pages; + if (userdatalen > MAX_USER_DEFINED_BYTES) + return -EINVAL; + + send_pages = newchannel->ringbuffer_send_offset; + recv_pages = newchannel->ringbuffer_pagecount - send_pages; + + spin_lock_irqsave(&newchannel->lock, flags); + if (newchannel->state != CHANNEL_OPEN_STATE) { + spin_unlock_irqrest
[PATCH 5/6] hv_uio_generic: map ringbuffer phys addr
The ring buffer is contiguous IOVA and is mapped via phys addr for sysfs file. Use same method for the UIO mapping. Signed-off-by: Stephen Hemminger --- drivers/uio/uio_hv_generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index ba67a5267557..53f5610c6065 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -224,10 +224,10 @@ hv_uio_probe(struct hv_device *dev, /* mem resources */ pdata->info.mem[TXRX_RING_MAP].name = "txrx_rings"; pdata->info.mem[TXRX_RING_MAP].addr - = (uintptr_t)page_address(dev->channel->ringbuffer_page); + = (uintptr_t)virt_to_phys(page_address(dev->channel->ringbuffer_page)); pdata->info.mem[TXRX_RING_MAP].size = dev->channel->ringbuffer_pagecount << PAGE_SHIFT; - pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_LOGICAL; + pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_IOVA; pdata->info.mem[INT_PAGE_MAP].name = "int_page"; pdata->info.mem[INT_PAGE_MAP].addr -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/6] vmbus: keep pointer to ring buffer page
Avoid going from struct page to virt address (and back) by just keeping pointer to the allocated pages instead of virt address. Signed-off-by: Stephen Hemminger --- drivers/hv/channel.c | 20 +--- drivers/uio/uio_hv_generic.c | 5 +++-- include/linux/hyperv.h | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 33e6db02dbab..56ec0d96d876 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -91,11 +91,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, unsigned long flags; int ret, err = 0; struct page *page; + unsigned int order; if (send_ringbuffer_size % PAGE_SIZE || recv_ringbuffer_size % PAGE_SIZE) return -EINVAL; + order = get_order(send_ringbuffer_size + recv_ringbuffer_size); + spin_lock_irqsave(&newchannel->lock, flags); if (newchannel->state == CHANNEL_OPEN_STATE) { newchannel->state = CHANNEL_OPENING_STATE; @@ -110,21 +113,17 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, /* Allocate the ring buffer */ page = alloc_pages_node(cpu_to_node(newchannel->target_cpu), - GFP_KERNEL|__GFP_ZERO, - get_order(send_ringbuffer_size + - recv_ringbuffer_size)); + GFP_KERNEL|__GFP_ZERO, order); if (!page) - page = alloc_pages(GFP_KERNEL|__GFP_ZERO, - get_order(send_ringbuffer_size + -recv_ringbuffer_size)); + page = alloc_pages(GFP_KERNEL|__GFP_ZERO, order); if (!page) { err = -ENOMEM; goto error_set_chnstate; } - newchannel->ringbuffer_pages = page_address(page); + newchannel->ringbuffer_page = page; newchannel->ringbuffer_pagecount = (send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT; @@ -239,8 +238,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, error_free_pages: hv_ringbuffer_cleanup(&newchannel->outbound); hv_ringbuffer_cleanup(&newchannel->inbound); - __free_pages(page, -get_order(send_ringbuffer_size + recv_ringbuffer_size)); + __free_pages(page, order); error_set_chnstate: newchannel->state = CHANNEL_OPEN_STATE; return err; @@ -658,8 +656,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel) hv_ringbuffer_cleanup(&channel->outbound); hv_ringbuffer_cleanup(&channel->inbound); - free_pages((unsigned long)channel->ringbuffer_pages, - get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); + __free_pages(channel->ringbuffer_page, +get_order(channel->ringbuffer_pagecount << PAGE_SHIFT)); out: return ret; diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index a08860260f55..ba67a5267557 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -130,11 +130,12 @@ static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj, = container_of(kobj, struct vmbus_channel, kobj); struct hv_device *dev = channel->primary_channel->device_obj; u16 q_idx = channel->offermsg.offer.sub_channel_index; + void *ring_buffer = page_address(channel->ringbuffer_page); dev_dbg(&dev->device, "mmap channel %u pages %#lx at %#lx\n", q_idx, vma_pages(vma), vma->vm_pgoff); - return vm_iomap_memory(vma, virt_to_phys(channel->ringbuffer_pages), + return vm_iomap_memory(vma, virt_to_phys(ring_buffer), channel->ringbuffer_pagecount << PAGE_SHIFT); } @@ -223,7 +224,7 @@ hv_uio_probe(struct hv_device *dev, /* mem resources */ pdata->info.mem[TXRX_RING_MAP].name = "txrx_rings"; pdata->info.mem[TXRX_RING_MAP].addr - = (uintptr_t)dev->channel->ringbuffer_pages; + = (uintptr_t)page_address(dev->channel->ringbuffer_page); pdata->info.mem[TXRX_RING_MAP].size = dev->channel->ringbuffer_pagecount << PAGE_SHIFT; pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_LOGICAL; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 6c4575c7f46b..a6c32d2d090b 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -739,7 +739,7 @@ struct vmbus_channel { u32 ringbuffer_gpadlhandle; /* Allocated memory for ring buffer */ - void *ringbuffer_pages; + struct page *ringbuffer_page; u32 ringbuffer_pagecount; struct hv_ring_buffer_info outbound;/* send to parent */ struct hv_ring_buffer_info inbound; /*
[PATCH 1/6] vmbus: pass channel to hv_process_channel_removal
Rather than passing relid and then looking up the channel. Pass the channel directly, since caller already knows it. Signed-off-by: Stephen Hemminger --- drivers/hv/channel.c | 3 +-- drivers/hv/channel_mgmt.c | 17 + drivers/hv/vmbus_drv.c| 3 +-- include/linux/hyperv.h| 2 +- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 741857d80da1..33e6db02dbab 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -690,8 +690,7 @@ void vmbus_close(struct vmbus_channel *channel) wait_for_completion(&cur_channel->rescind_event); mutex_lock(&vmbus_connection.channel_mutex); vmbus_close_internal(cur_channel); - hv_process_channel_removal( - cur_channel->offermsg.child_relid); + hv_process_channel_removal(cur_channel); } else { mutex_lock(&vmbus_connection.channel_mutex); vmbus_close_internal(cur_channel); diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 0f0e091c117c..b7c48ebdf6a1 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -385,21 +385,14 @@ static void vmbus_release_relid(u32 relid) trace_vmbus_release_relid(&msg, ret); } -void hv_process_channel_removal(u32 relid) +void hv_process_channel_removal(struct vmbus_channel *channel) { + struct vmbus_channel *primary_channel; unsigned long flags; - struct vmbus_channel *primary_channel, *channel; BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex)); - - /* -* Make sure channel is valid as we may have raced. -*/ - channel = relid2channel(relid); - if (!channel) - return; - BUG_ON(!channel->rescind); + if (channel->target_cpu != get_cpu()) { put_cpu(); smp_call_function_single(channel->target_cpu, @@ -429,7 +422,7 @@ void hv_process_channel_removal(u32 relid) cpumask_clear_cpu(channel->target_cpu, &primary_channel->alloced_cpus_in_node); - vmbus_release_relid(relid); + vmbus_release_relid(channel->offermsg.child_relid); free_channel(channel); } @@ -943,7 +936,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) * The channel is currently not open; * it is safe for us to cleanup the channel. */ - hv_process_channel_removal(rescind->child_relid); + hv_process_channel_removal(channel); } else { complete(&channel->rescind_event); } diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index e6d8fdac6d8b..007ee8e5986a 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -864,10 +864,9 @@ static void vmbus_device_release(struct device *device) struct vmbus_channel *channel = hv_dev->channel; mutex_lock(&vmbus_connection.channel_mutex); - hv_process_channel_removal(channel->offermsg.child_relid); + hv_process_channel_removal(channel); mutex_unlock(&vmbus_connection.channel_mutex); kfree(hv_dev); - } /* The one and only one */ diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 2c3798bcb01c..6c4575c7f46b 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1443,7 +1443,7 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf, const int *srv_version, int srv_vercnt, int *nego_fw_version, int *nego_srv_version); -void hv_process_channel_removal(u32 relid); +void hv_process_channel_removal(struct vmbus_channel *channel); void vmbus_setevent(struct vmbus_channel *channel); /* -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 6/6] uio_hv_generic: defer opening vmbus until first use
This fixes two design flaws in hv_uio_generic. Since hv_uio_probe is called from vmbus_probe with lock held it potentially can cause sleep in an atomic section because vmbus_open will wait for response from host. The hv_uio_generic driver could not handle applications exiting and restarting because the vmbus channel was persistent. Change the semantics so that the buffers are allocated on probe, but not attached to host until device is opened. Signed-off-by: Stephen Hemminger --- drivers/uio/uio_hv_generic.c | 104 +-- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 53f5610c6065..f2ec981d66cb 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -55,6 +55,7 @@ enum hv_uio_map { struct hv_uio_private_data { struct uio_info info; struct hv_device *device; + atomic_t refcnt; void*recv_buf; u32 recv_gpadl; @@ -128,12 +129,10 @@ static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj, { struct vmbus_channel *channel = container_of(kobj, struct vmbus_channel, kobj); - struct hv_device *dev = channel->primary_channel->device_obj; - u16 q_idx = channel->offermsg.offer.sub_channel_index; void *ring_buffer = page_address(channel->ringbuffer_page); - dev_dbg(&dev->device, "mmap channel %u pages %#lx at %#lx\n", - q_idx, vma_pages(vma), vma->vm_pgoff); + if (channel->state != CHANNEL_OPENED_STATE) + return -ENODEV; return vm_iomap_memory(vma, virt_to_phys(ring_buffer), channel->ringbuffer_pagecount << PAGE_SHIFT); @@ -176,57 +175,103 @@ hv_uio_new_channel(struct vmbus_channel *new_sc) } } +/* free the reserved buffers for send and receive */ static void hv_uio_cleanup(struct hv_device *dev, struct hv_uio_private_data *pdata) { - if (pdata->send_gpadl) + if (pdata->send_gpadl) { vmbus_teardown_gpadl(dev->channel, pdata->send_gpadl); - vfree(pdata->send_buf); + pdata->send_gpadl = 0; + vfree(pdata->send_buf); + } - if (pdata->recv_gpadl) + if (pdata->recv_gpadl) { vmbus_teardown_gpadl(dev->channel, pdata->recv_gpadl); - vfree(pdata->recv_buf); + pdata->recv_gpadl = 0; + vfree(pdata->recv_buf); + } +} + +/* VMBus primary channel is opened on first use */ +static int +hv_uio_open(struct uio_info *info, struct inode *inode) +{ + struct hv_uio_private_data *pdata + = container_of(info, struct hv_uio_private_data, info); + struct hv_device *dev = pdata->device; + int ret; + + if (atomic_inc_return(&pdata->refcnt) != 1) + return 0; + + ret = vmbus_connect_ring(dev->channel, +hv_uio_channel_cb, dev->channel); + + if (ret == 0) + dev->channel->inbound.ring_buffer->interrupt_mask = 1; + else + atomic_dec(&pdata->refcount); + + return ret; +} + +/* VMBus primary channel is closed on last close */ +static int +hv_uio_release(struct uio_info *info, struct inode *inode) +{ + struct hv_uio_private_data *pdata + = container_of(info, struct hv_uio_private_data, info); + struct hv_device *dev = pdata->device; + int ret = 0; + + if (atomic_dec_and_test(&pdata->refcnt)) + ret = vmbus_disconnect_ring(dev->channel); + + return ret; } static int hv_uio_probe(struct hv_device *dev, const struct hv_vmbus_device_id *dev_id) { + struct vmbus_channel *channel = dev->channel; struct hv_uio_private_data *pdata; + void *ring_buffer; int ret; + /* Communicating with host has to be via shared memory not hypercall */ + if (!channel->offermsg.monitor_allocated) { + dev_err(&dev->device, "vmbus channel requires hypercall\n"); + return -ENOTSUPP; + } + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; - ret = vmbus_open(dev->channel, HV_RING_SIZE * PAGE_SIZE, -HV_RING_SIZE * PAGE_SIZE, NULL, 0, -hv_uio_channel_cb, dev->channel); + ret = vmbus_alloc_ring(channel, HV_RING_SIZE * PAGE_SIZE, + HV_RING_SIZE * PAGE_SIZE); if (ret) goto fail; - /* Communicating with host has to be via shared memory not hypercall */ - if (!dev->channel->offermsg.monitor_allocated) { - dev_err(&dev->device, "vmbus channel requires hypercall\n"); - ret = -ENOTSUPP; - goto fail_close; - } - - dev->channel->inbound.ring_buffer->interrupt_mask = 1; - set_channel_read_mode(dev->channe
[PATCH 4/6] uio: introduce UIO_MEM_IOVA
Introduce the concept of mapping physical memory locations that are normal memory. The new type UIO_MEM_IOVA are similar to existing UIO_MEM_PHYS but the backing memory is not marked as uncached. Also, indent related switch to the currently used style. Signed-off-by: Stephen Hemminger --- drivers/uio/uio.c | 24 +--- include/linux/uio_driver.h | 1 + 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 0ffb324aa038..e601bd3fbae1 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -738,7 +738,8 @@ static int uio_mmap_physical(struct vm_area_struct *vma) return -EINVAL; vma->vm_ops = &uio_physical_vm_ops; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + if (idev->info->mem[mi].memtype == UIO_MEM_PHYS) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* * We cannot use the vm_iomap_memory() helper here, @@ -795,18 +796,19 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma) } switch (idev->info->mem[mi].memtype) { - case UIO_MEM_PHYS: - ret = uio_mmap_physical(vma); - break; - case UIO_MEM_LOGICAL: - case UIO_MEM_VIRTUAL: - ret = uio_mmap_logical(vma); - break; - default: - ret = -EINVAL; + case UIO_MEM_IOVA: + case UIO_MEM_PHYS: + ret = uio_mmap_physical(vma); + break; + case UIO_MEM_LOGICAL: + case UIO_MEM_VIRTUAL: + ret = uio_mmap_logical(vma); + break; + default: + ret = -EINVAL; } -out: + out: mutex_unlock(&idev->info_lock); return ret; } diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h index 6f8b68cd460f..a3cd7cb67a69 100644 --- a/include/linux/uio_driver.h +++ b/include/linux/uio_driver.h @@ -133,6 +133,7 @@ extern void uio_event_notify(struct uio_info *info); #define UIO_MEM_PHYS 1 #define UIO_MEM_LOGICAL2 #define UIO_MEM_VIRTUAL 3 +#define UIO_MEM_IOVA 4 /* defines for uio_port->porttype */ #define UIO_PORT_NONE 0 -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] staging: rtl8188eu: remove code that is valid only for 5 GHz
> On Thu, Sep 13, 2018 at 10:32:39PM +0200, Robert Węcławski wrote: > > diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c > > b/drivers/staging/rtl8188eu/core/rtw_mlme.c > > index eca06f05c0c4..b610443f2ac6 100644 > > --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c > > +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c > > @@ -1819,16 +1819,6 @@ void rtw_update_registrypriv_dev_network(struct > > adapter *adapter) > > case WIRELESS_11BG_24N: > > pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; > > break; > > - case WIRELESS_11A: > > - case WIRELESS_11A_5N: > > - pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; > > - break; > > - case WIRELESS_11ABGN: > > - if (pregistrypriv->channel > 14) > > - pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; > > - else > > - pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; > > - break; > > default: > > /* TODO */ > > break; > > Are you sure about this chunk? I would have thought that <= 14 was not > 5G. (I try to avoid rhetorical questions and I don't know the answer > here). > > regards, > dan carpenter I'm 99% sure this part is not needed because this chipset only supports B, G and N WiFi networks. I think we should add pdev_network->NetworkTypeInUse = Ndis802_110FDM5 to default case to be 100% sure it won't break anything. If we do this we can be sure pdev_network->NetworkTypeInUse will be set. Should I make a new version of this patch? ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 4/6] uio: introduce UIO_MEM_IOVA
Introduce the concept of mapping physical memory locations that are normal memory. The new type UIO_MEM_IOVA are similar to existing UIO_MEM_PHYS but the backing memory is not marked as uncached. Also, indent related switch to the currently used style. Signed-off-by: Stephen Hemminger --- drivers/uio/uio.c | 24 +--- include/linux/uio_driver.h | 1 + 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 0ffb324aa038..e601bd3fbae1 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -738,7 +738,8 @@ static int uio_mmap_physical(struct vm_area_struct *vma) return -EINVAL; vma->vm_ops = &uio_physical_vm_ops; - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); + if (idev->info->mem[mi].memtype == UIO_MEM_PHYS) + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* * We cannot use the vm_iomap_memory() helper here, @@ -795,18 +796,19 @@ static int uio_mmap(struct file *filep, struct vm_area_struct *vma) } switch (idev->info->mem[mi].memtype) { - case UIO_MEM_PHYS: - ret = uio_mmap_physical(vma); - break; - case UIO_MEM_LOGICAL: - case UIO_MEM_VIRTUAL: - ret = uio_mmap_logical(vma); - break; - default: - ret = -EINVAL; + case UIO_MEM_IOVA: + case UIO_MEM_PHYS: + ret = uio_mmap_physical(vma); + break; + case UIO_MEM_LOGICAL: + case UIO_MEM_VIRTUAL: + ret = uio_mmap_logical(vma); + break; + default: + ret = -EINVAL; } -out: + out: mutex_unlock(&idev->info_lock); return ret; } diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h index 6f8b68cd460f..a3cd7cb67a69 100644 --- a/include/linux/uio_driver.h +++ b/include/linux/uio_driver.h @@ -133,6 +133,7 @@ extern void uio_event_notify(struct uio_info *info); #define UIO_MEM_PHYS 1 #define UIO_MEM_LOGICAL2 #define UIO_MEM_VIRTUAL 3 +#define UIO_MEM_IOVA 4 /* defines for uio_port->porttype */ #define UIO_PORT_NONE 0 -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 5/6] hv_uio_generic: map ringbuffer phys addr
The ring buffer is contiguous IOVA and is mapped via phys addr for sysfs file. Use same method for the UIO mapping. Signed-off-by: Stephen Hemminger --- drivers/uio/uio_hv_generic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index ba67a5267557..53f5610c6065 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -224,10 +224,10 @@ hv_uio_probe(struct hv_device *dev, /* mem resources */ pdata->info.mem[TXRX_RING_MAP].name = "txrx_rings"; pdata->info.mem[TXRX_RING_MAP].addr - = (uintptr_t)page_address(dev->channel->ringbuffer_page); + = (uintptr_t)virt_to_phys(page_address(dev->channel->ringbuffer_page)); pdata->info.mem[TXRX_RING_MAP].size = dev->channel->ringbuffer_pagecount << PAGE_SHIFT; - pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_LOGICAL; + pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_IOVA; pdata->info.mem[INT_PAGE_MAP].name = "int_page"; pdata->info.mem[INT_PAGE_MAP].addr -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 6/6] uio_hv_generic: defer opening vmbus until first use
This fixes two design flaws in hv_uio_generic. Since hv_uio_probe is called from vmbus_probe with lock held it potentially can cause sleep in an atomic section because vmbus_open will wait for response from host. The hv_uio_generic driver could not handle applications exiting and restarting because the vmbus channel was persistent. Change the semantics so that the buffers are allocated on probe, but not attached to host until device is opened. Signed-off-by: Stephen Hemminger --- drivers/uio/uio_hv_generic.c | 104 +-- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index 53f5610c6065..c2493d011225 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -55,6 +55,7 @@ enum hv_uio_map { struct hv_uio_private_data { struct uio_info info; struct hv_device *device; + atomic_t refcnt; void*recv_buf; u32 recv_gpadl; @@ -128,12 +129,10 @@ static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj, { struct vmbus_channel *channel = container_of(kobj, struct vmbus_channel, kobj); - struct hv_device *dev = channel->primary_channel->device_obj; - u16 q_idx = channel->offermsg.offer.sub_channel_index; void *ring_buffer = page_address(channel->ringbuffer_page); - dev_dbg(&dev->device, "mmap channel %u pages %#lx at %#lx\n", - q_idx, vma_pages(vma), vma->vm_pgoff); + if (channel->state != CHANNEL_OPENED_STATE) + return -ENODEV; return vm_iomap_memory(vma, virt_to_phys(ring_buffer), channel->ringbuffer_pagecount << PAGE_SHIFT); @@ -176,57 +175,103 @@ hv_uio_new_channel(struct vmbus_channel *new_sc) } } +/* free the reserved buffers for send and receive */ static void hv_uio_cleanup(struct hv_device *dev, struct hv_uio_private_data *pdata) { - if (pdata->send_gpadl) + if (pdata->send_gpadl) { vmbus_teardown_gpadl(dev->channel, pdata->send_gpadl); - vfree(pdata->send_buf); + pdata->send_gpadl = 0; + vfree(pdata->send_buf); + } - if (pdata->recv_gpadl) + if (pdata->recv_gpadl) { vmbus_teardown_gpadl(dev->channel, pdata->recv_gpadl); - vfree(pdata->recv_buf); + pdata->recv_gpadl = 0; + vfree(pdata->recv_buf); + } +} + +/* VMBus primary channel is opened on first use */ +static int +hv_uio_open(struct uio_info *info, struct inode *inode) +{ + struct hv_uio_private_data *pdata + = container_of(info, struct hv_uio_private_data, info); + struct hv_device *dev = pdata->device; + int ret; + + if (atomic_inc_return(&pdata->refcnt) != 1) + return 0; + + ret = vmbus_connect_ring(dev->channel, +hv_uio_channel_cb, dev->channel); + + if (ret == 0) + dev->channel->inbound.ring_buffer->interrupt_mask = 1; + else + atomic_dec(&pdata->refcnt); + + return ret; +} + +/* VMBus primary channel is closed on last close */ +static int +hv_uio_release(struct uio_info *info, struct inode *inode) +{ + struct hv_uio_private_data *pdata + = container_of(info, struct hv_uio_private_data, info); + struct hv_device *dev = pdata->device; + int ret = 0; + + if (atomic_dec_and_test(&pdata->refcnt)) + ret = vmbus_disconnect_ring(dev->channel); + + return ret; } static int hv_uio_probe(struct hv_device *dev, const struct hv_vmbus_device_id *dev_id) { + struct vmbus_channel *channel = dev->channel; struct hv_uio_private_data *pdata; + void *ring_buffer; int ret; + /* Communicating with host has to be via shared memory not hypercall */ + if (!channel->offermsg.monitor_allocated) { + dev_err(&dev->device, "vmbus channel requires hypercall\n"); + return -ENOTSUPP; + } + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; - ret = vmbus_open(dev->channel, HV_RING_SIZE * PAGE_SIZE, -HV_RING_SIZE * PAGE_SIZE, NULL, 0, -hv_uio_channel_cb, dev->channel); + ret = vmbus_alloc_ring(channel, HV_RING_SIZE * PAGE_SIZE, + HV_RING_SIZE * PAGE_SIZE); if (ret) goto fail; - /* Communicating with host has to be via shared memory not hypercall */ - if (!dev->channel->offermsg.monitor_allocated) { - dev_err(&dev->device, "vmbus channel requires hypercall\n"); - ret = -ENOTSUPP; - goto fail_close; - } - - dev->channel->inbound.ring_buffer->interrupt_mask = 1; - set_channel_read_mode(dev->channel,
[PATCH v3 2/6] vmbus: keep pointer to ring buffer page
Avoid going from struct page to virt address (and back) by just keeping pointer to the allocated pages instead of virt address. Signed-off-by: Stephen Hemminger --- drivers/hv/channel.c | 20 +--- drivers/uio/uio_hv_generic.c | 5 +++-- include/linux/hyperv.h | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 33e6db02dbab..56ec0d96d876 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -91,11 +91,14 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, unsigned long flags; int ret, err = 0; struct page *page; + unsigned int order; if (send_ringbuffer_size % PAGE_SIZE || recv_ringbuffer_size % PAGE_SIZE) return -EINVAL; + order = get_order(send_ringbuffer_size + recv_ringbuffer_size); + spin_lock_irqsave(&newchannel->lock, flags); if (newchannel->state == CHANNEL_OPEN_STATE) { newchannel->state = CHANNEL_OPENING_STATE; @@ -110,21 +113,17 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, /* Allocate the ring buffer */ page = alloc_pages_node(cpu_to_node(newchannel->target_cpu), - GFP_KERNEL|__GFP_ZERO, - get_order(send_ringbuffer_size + - recv_ringbuffer_size)); + GFP_KERNEL|__GFP_ZERO, order); if (!page) - page = alloc_pages(GFP_KERNEL|__GFP_ZERO, - get_order(send_ringbuffer_size + -recv_ringbuffer_size)); + page = alloc_pages(GFP_KERNEL|__GFP_ZERO, order); if (!page) { err = -ENOMEM; goto error_set_chnstate; } - newchannel->ringbuffer_pages = page_address(page); + newchannel->ringbuffer_page = page; newchannel->ringbuffer_pagecount = (send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT; @@ -239,8 +238,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, error_free_pages: hv_ringbuffer_cleanup(&newchannel->outbound); hv_ringbuffer_cleanup(&newchannel->inbound); - __free_pages(page, -get_order(send_ringbuffer_size + recv_ringbuffer_size)); + __free_pages(page, order); error_set_chnstate: newchannel->state = CHANNEL_OPEN_STATE; return err; @@ -658,8 +656,8 @@ static int vmbus_close_internal(struct vmbus_channel *channel) hv_ringbuffer_cleanup(&channel->outbound); hv_ringbuffer_cleanup(&channel->inbound); - free_pages((unsigned long)channel->ringbuffer_pages, - get_order(channel->ringbuffer_pagecount * PAGE_SIZE)); + __free_pages(channel->ringbuffer_page, +get_order(channel->ringbuffer_pagecount << PAGE_SHIFT)); out: return ret; diff --git a/drivers/uio/uio_hv_generic.c b/drivers/uio/uio_hv_generic.c index a08860260f55..ba67a5267557 100644 --- a/drivers/uio/uio_hv_generic.c +++ b/drivers/uio/uio_hv_generic.c @@ -130,11 +130,12 @@ static int hv_uio_ring_mmap(struct file *filp, struct kobject *kobj, = container_of(kobj, struct vmbus_channel, kobj); struct hv_device *dev = channel->primary_channel->device_obj; u16 q_idx = channel->offermsg.offer.sub_channel_index; + void *ring_buffer = page_address(channel->ringbuffer_page); dev_dbg(&dev->device, "mmap channel %u pages %#lx at %#lx\n", q_idx, vma_pages(vma), vma->vm_pgoff); - return vm_iomap_memory(vma, virt_to_phys(channel->ringbuffer_pages), + return vm_iomap_memory(vma, virt_to_phys(ring_buffer), channel->ringbuffer_pagecount << PAGE_SHIFT); } @@ -223,7 +224,7 @@ hv_uio_probe(struct hv_device *dev, /* mem resources */ pdata->info.mem[TXRX_RING_MAP].name = "txrx_rings"; pdata->info.mem[TXRX_RING_MAP].addr - = (uintptr_t)dev->channel->ringbuffer_pages; + = (uintptr_t)page_address(dev->channel->ringbuffer_page); pdata->info.mem[TXRX_RING_MAP].size = dev->channel->ringbuffer_pagecount << PAGE_SHIFT; pdata->info.mem[TXRX_RING_MAP].memtype = UIO_MEM_LOGICAL; diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 6c4575c7f46b..a6c32d2d090b 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -739,7 +739,7 @@ struct vmbus_channel { u32 ringbuffer_gpadlhandle; /* Allocated memory for ring buffer */ - void *ringbuffer_pages; + struct page *ringbuffer_page; u32 ringbuffer_pagecount; struct hv_ring_buffer_info outbound;/* send to parent */ struct hv_ring_buffer_info inbound; /*
[PATCH v3 1/6] vmbus: pass channel to hv_process_channel_removal
Rather than passing relid and then looking up the channel. Pass the channel directly, since caller already knows it. Signed-off-by: Stephen Hemminger --- drivers/hv/channel.c | 3 +-- drivers/hv/channel_mgmt.c | 17 + drivers/hv/vmbus_drv.c| 3 +-- include/linux/hyperv.h| 2 +- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 741857d80da1..33e6db02dbab 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -690,8 +690,7 @@ void vmbus_close(struct vmbus_channel *channel) wait_for_completion(&cur_channel->rescind_event); mutex_lock(&vmbus_connection.channel_mutex); vmbus_close_internal(cur_channel); - hv_process_channel_removal( - cur_channel->offermsg.child_relid); + hv_process_channel_removal(cur_channel); } else { mutex_lock(&vmbus_connection.channel_mutex); vmbus_close_internal(cur_channel); diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 0f0e091c117c..b7c48ebdf6a1 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -385,21 +385,14 @@ static void vmbus_release_relid(u32 relid) trace_vmbus_release_relid(&msg, ret); } -void hv_process_channel_removal(u32 relid) +void hv_process_channel_removal(struct vmbus_channel *channel) { + struct vmbus_channel *primary_channel; unsigned long flags; - struct vmbus_channel *primary_channel, *channel; BUG_ON(!mutex_is_locked(&vmbus_connection.channel_mutex)); - - /* -* Make sure channel is valid as we may have raced. -*/ - channel = relid2channel(relid); - if (!channel) - return; - BUG_ON(!channel->rescind); + if (channel->target_cpu != get_cpu()) { put_cpu(); smp_call_function_single(channel->target_cpu, @@ -429,7 +422,7 @@ void hv_process_channel_removal(u32 relid) cpumask_clear_cpu(channel->target_cpu, &primary_channel->alloced_cpus_in_node); - vmbus_release_relid(relid); + vmbus_release_relid(channel->offermsg.child_relid); free_channel(channel); } @@ -943,7 +936,7 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) * The channel is currently not open; * it is safe for us to cleanup the channel. */ - hv_process_channel_removal(rescind->child_relid); + hv_process_channel_removal(channel); } else { complete(&channel->rescind_event); } diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index e6d8fdac6d8b..007ee8e5986a 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -864,10 +864,9 @@ static void vmbus_device_release(struct device *device) struct vmbus_channel *channel = hv_dev->channel; mutex_lock(&vmbus_connection.channel_mutex); - hv_process_channel_removal(channel->offermsg.child_relid); + hv_process_channel_removal(channel); mutex_unlock(&vmbus_connection.channel_mutex); kfree(hv_dev); - } /* The one and only one */ diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 2c3798bcb01c..6c4575c7f46b 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1443,7 +1443,7 @@ extern bool vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, u8 *buf, const int *srv_version, int srv_vercnt, int *nego_fw_version, int *nego_srv_version); -void hv_process_channel_removal(u32 relid); +void hv_process_channel_removal(struct vmbus_channel *channel); void vmbus_setevent(struct vmbus_channel *channel); /* -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 0/6] fix hv_uio_generic open/close
This set of patches fixes the problem where DPDK applications using hv_uio_generic driver can not be successfully restarted. In order to get this working it required small change to uio to allow for mapping without no-cache. And refactoring of how ring buffer is setup in vmbus code. It could be backported as a fix, to 4.19 but that is not an LTS so probably not worth it. v3 - fix typo (sent wrong version for v2) v2 - fix refcount when hv_uio_open fails Stephen Hemminger (6): vmbus: pass channel to hv_process_channel_removal vmbus: keep pointer to ring buffer page vmbus: split ring buffer allocation from open uio: introduce UIO_MEM_IOVA hv_uio_generic: map ringbuffer phys addr uio_hv_generic: defer opening vmbus until first use drivers/hv/channel.c | 276 --- drivers/hv/channel_mgmt.c| 17 +-- drivers/hv/ring_buffer.c | 1 + drivers/hv/vmbus_drv.c | 3 +- drivers/uio/uio.c| 24 +-- drivers/uio/uio_hv_generic.c | 109 ++ include/linux/hyperv.h | 13 +- include/linux/uio_driver.h | 1 + 8 files changed, 264 insertions(+), 180 deletions(-) -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3 3/6] vmbus: split ring buffer allocation from open
The UIO driver needs the ring buffer to be persistent(reused) across open/close. Split the allocation and setup of ring buffer out of vmbus_open. For normal usage vmbus_open/vmbus_close there are no changes; only impacts uio_hv_generic which needs to keep ring buffer memory and reuse when application restarts. Signed-off-by: Stephen Hemminger --- drivers/hv/channel.c | 267 ++- drivers/hv/ring_buffer.c | 1 + include/linux/hyperv.h | 9 ++ 3 files changed, 162 insertions(+), 115 deletions(-) diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 56ec0d96d876..ddadb7efd1cc 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c @@ -79,84 +79,96 @@ void vmbus_setevent(struct vmbus_channel *channel) } EXPORT_SYMBOL_GPL(vmbus_setevent); -/* - * vmbus_open - Open the specified channel. - */ -int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, -u32 recv_ringbuffer_size, void *userdata, u32 userdatalen, -void (*onchannelcallback)(void *context), void *context) +/* vmbus_free_ring - drop mapping of ring buffer */ +void vmbus_free_ring(struct vmbus_channel *channel) { - struct vmbus_channel_open_channel *open_msg; - struct vmbus_channel_msginfo *open_info = NULL; - unsigned long flags; - int ret, err = 0; - struct page *page; - unsigned int order; + hv_ringbuffer_cleanup(&channel->outbound); + hv_ringbuffer_cleanup(&channel->inbound); - if (send_ringbuffer_size % PAGE_SIZE || - recv_ringbuffer_size % PAGE_SIZE) - return -EINVAL; + if (channel->ringbuffer_page) { + __free_pages(channel->ringbuffer_page, +get_order(channel->ringbuffer_pagecount + << PAGE_SHIFT)); + channel->ringbuffer_page = NULL; + } +} +EXPORT_SYMBOL_GPL(vmbus_free_ring); - order = get_order(send_ringbuffer_size + recv_ringbuffer_size); +/* vmbus_alloc_ring - allocate and map pages for ring buffer */ +int vmbus_alloc_ring(struct vmbus_channel *newchannel, +u32 send_size, u32 recv_size) +{ + struct page *page; + int order; - spin_lock_irqsave(&newchannel->lock, flags); - if (newchannel->state == CHANNEL_OPEN_STATE) { - newchannel->state = CHANNEL_OPENING_STATE; - } else { - spin_unlock_irqrestore(&newchannel->lock, flags); + if (send_size % PAGE_SIZE || recv_size % PAGE_SIZE) return -EINVAL; - } - spin_unlock_irqrestore(&newchannel->lock, flags); - - newchannel->onchannel_callback = onchannelcallback; - newchannel->channel_callback_context = context; /* Allocate the ring buffer */ + order = get_order(send_size + recv_size); page = alloc_pages_node(cpu_to_node(newchannel->target_cpu), GFP_KERNEL|__GFP_ZERO, order); if (!page) page = alloc_pages(GFP_KERNEL|__GFP_ZERO, order); - if (!page) { - err = -ENOMEM; - goto error_set_chnstate; - } + if (!page) + return -ENOMEM; newchannel->ringbuffer_page = page; - newchannel->ringbuffer_pagecount = (send_ringbuffer_size + - recv_ringbuffer_size) >> PAGE_SHIFT; + newchannel->ringbuffer_pagecount = (send_size + recv_size) >> PAGE_SHIFT; + newchannel->ringbuffer_send_offset = send_size >> PAGE_SHIFT; - ret = hv_ringbuffer_init(&newchannel->outbound, page, -send_ringbuffer_size >> PAGE_SHIFT); + return 0; +} +EXPORT_SYMBOL_GPL(vmbus_alloc_ring); - if (ret != 0) { - err = ret; - goto error_free_pages; - } +static int __vmbus_open(struct vmbus_channel *newchannel, + void *userdata, u32 userdatalen, + void (*onchannelcallback)(void *context), void *context) +{ + struct vmbus_channel_open_channel *open_msg; + struct vmbus_channel_msginfo *open_info = NULL; + struct page *page = newchannel->ringbuffer_page; + u32 send_pages, recv_pages; + unsigned long flags; + int err; - ret = hv_ringbuffer_init(&newchannel->inbound, -&page[send_ringbuffer_size >> PAGE_SHIFT], -recv_ringbuffer_size >> PAGE_SHIFT); - if (ret != 0) { - err = ret; - goto error_free_pages; + if (userdatalen > MAX_USER_DEFINED_BYTES) + return -EINVAL; + + send_pages = newchannel->ringbuffer_send_offset; + recv_pages = newchannel->ringbuffer_pagecount - send_pages; + + spin_lock_irqsave(&newchannel->lock, flags); + if (newchannel->state != CHANNEL_OPEN_STATE) { + spin_unlock_irqrest
Re: [PATCH v2 1/4] staging/vc04_services: Use correct cache line size
Hi Phil, > Phil Elwell hat am 14. September 2018 um 17:22 > geschrieben: > > > On 14/09/2018 14:22, Phil Elwell wrote: > > Use the compatible string in the DTB to select the correct cache line > > size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. > > > > Signed-off-by: Phil Elwell > > --- > > .../interface/vchiq_arm/vchiq_2835_arm.c | 4 ++- > > .../vc04_services/interface/vchiq_arm/vchiq_arm.c | 36 > > -- > > .../vc04_services/interface/vchiq_arm/vchiq_arm.h | 5 +++ > > 3 files changed, 34 insertions(+), 11 deletions(-) > > > > diff --git > > a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c > > b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c > > index e767209..83d740f 100644 > > --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c > > +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c > > @@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo, > > int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T > > *state) > > { > > struct device *dev = &pdev->dev; > > - struct rpi_firmware *fw = platform_get_drvdata(pdev); > > + struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev); > > + struct rpi_firmware *fw = drvdata->fw; > > VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; > > struct resource *res; > > void *slot_mem; > > @@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, > > VCHIQ_STATE_T *state) > > if (err < 0) > > return err; > > > > + g_cache_line_size = drvdata->cache_line_size; > > g_fragments_size = 2 * g_cache_line_size; > > > > /* Allocate space for the channels in coherent memory */ > > diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c > > b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c > > index bc05c69..b2ae9259 100644 > > --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c > > +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c > > @@ -170,6 +170,14 @@ static struct device *vchiq_dev; > > static DEFINE_SPINLOCK(msg_queue_spinlock); > > static struct platform_device *bcm2835_camera; > > > > +static struct vchiq_drvdata bcm2835_drvdata = { > > + .cache_line_size = 32, > > +}; > > + > > +static struct vchiq_drvdata bcm2836_drvdata = { > > + .cache_line_size = 64, > > +}; > > + > > static const char *const ioctl_names[] = { > > "CONNECT", > > "SHUTDOWN", > > @@ -3573,12 +3581,26 @@ void > > vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, > > } > > } > > > > +static const struct of_device_id vchiq_of_match[] = { > > + { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, > > + { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, > > + {}, > > +}; > > +MODULE_DEVICE_TABLE(of, vchiq_of_match); > > + > > static int vchiq_probe(struct platform_device *pdev) > > { > > struct device_node *fw_node; > > - struct rpi_firmware *fw; > > + const struct of_device_id *of_id; > > + struct vchiq_drvdata *drvdata; > > int err; > > > > + snd_rpi_simple.dev = &pdev->dev; > > + of_id = of_match_node(vchiq_of_match, pdev->dev.of_node); > > + drvdata = of_id->data; > > + if (!drvdata) > > + return -EINVAL; > > + > > fw_node = of_find_compatible_node(NULL, NULL, > > "raspberrypi,bcm2835-firmware"); > > if (!fw_node) { > > @@ -3586,12 +3608,12 @@ static int vchiq_probe(struct platform_device *pdev) > > return -ENOENT; > > } > > > > - fw = rpi_firmware_get(fw_node); > > + drvdata->fw = rpi_firmware_get(fw_node); > > of_node_put(fw_node); > > - if (!fw) > > + if (!drvdata->fw) > > return -EPROBE_DEFER; > > > > - platform_set_drvdata(pdev, fw); > > + platform_set_drvdata(pdev, drvdata); > > > > err = vchiq_platform_init(pdev, &g_state); > > if (err != 0) > > @@ -3661,12 +3683,6 @@ static int vchiq_remove(struct platform_device *pdev) > > return 0; > > } > > > > -static const struct of_device_id vchiq_of_match[] = { > > - { .compatible = "brcm,bcm2835-vchiq", }, > > - {}, > > -}; > > -MODULE_DEVICE_TABLE(of, vchiq_of_match); > > - > > static struct platform_driver vchiq_driver = { > > .driver = { > > .name = "bcm2835_vchiq", > > diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h > > b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h > > index 40bb0c6..2f3ebc9 100644 > > --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h > > +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h > > @@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct { > > > > } VCHIQ_ARM_STATE_T; > > > > +struct vchiq_drvdata { > > + const unsigned int cache_line_size; > > + struct rpi_firmware *fw; > > +
Re: [PATCH] staging: rtl8188eu: remove code that is valid only for 5 GHz
On Fri, Sep 14, 2018 at 05:58:58PM +0200, Robert Węcławski wrote: > > On Thu, Sep 13, 2018 at 10:32:39PM +0200, Robert Węcławski wrote: > > > diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme.c > > > b/drivers/staging/rtl8188eu/core/rtw_mlme.c > > > index eca06f05c0c4..b610443f2ac6 100644 > > > --- a/drivers/staging/rtl8188eu/core/rtw_mlme.c > > > +++ b/drivers/staging/rtl8188eu/core/rtw_mlme.c > > > @@ -1819,16 +1819,6 @@ void rtw_update_registrypriv_dev_network(struct > > > adapter *adapter) > > > case WIRELESS_11BG_24N: > > > pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; > > > break; > > > - case WIRELESS_11A: > > > - case WIRELESS_11A_5N: > > > - pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; > > > - break; > > > - case WIRELESS_11ABGN: > > > - if (pregistrypriv->channel > 14) > > > - pdev_network->NetworkTypeInUse = Ndis802_11OFDM5; > > > - else > > > - pdev_network->NetworkTypeInUse = Ndis802_11OFDM24; > > > - break; > > > default: > > > /* TODO */ > > > break; > > > > Are you sure about this chunk? I would have thought that <= 14 was not > > 5G. (I try to avoid rhetorical questions and I don't know the answer > > here). > > > > regards, > > dan carpenter > > I'm 99% sure this part is not needed because this chipset only supports B, G > and N WiFi networks. > > I think we should add pdev_network->NetworkTypeInUse = Ndis802_110FDM5 to > default case to be 100% sure it won't break anything. > If we do this we can be sure pdev_network->NetworkTypeInUse will be set. > Should I make a new version of this patch? Yes, please. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 4/4] ARM: dts: bcm283x: Correct mailbox register sizes
On 09/14/2018 06:22 AM, Phil Elwell wrote: > The size field in a Device Tree "reg" property is encoded in bytes, not > words. > > Signed-off-by: Phil Elwell This should probably have a: Fixes: 614fa22119d6 ("ARM: dts: bcm2835: Add VCHIQ node to the Raspberry Pi boards. (v3)") as well? > --- > arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi > b/arch/arm/boot/dts/bcm2835-rpi.dtsi > index 215d8cc..29f970f 100644 > --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi > +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi > @@ -32,7 +32,7 @@ > > vchiq: mailbox@7e00b840 { > compatible = "brcm,bcm2835-vchiq"; > - reg = <0x7e00b840 0xf>; > + reg = <0x7e00b840 0x3c>; > interrupts = <0 2>; > }; > }; > -- Florian ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/4] staging/vc04_services: Use correct cache line size
On 09/14/2018 06:22 AM, Phil Elwell wrote: > Use the compatible string in the DTB to select the correct cache line > size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. > > Signed-off-by: Phil Elwell > --- [snip] > @@ -170,6 +170,14 @@ static struct device *vchiq_dev; > static DEFINE_SPINLOCK(msg_queue_spinlock); > static struct platform_device *bcm2835_camera; > > +static struct vchiq_drvdata bcm2835_drvdata = { > + .cache_line_size = 32, > +}; > + > +static struct vchiq_drvdata bcm2836_drvdata = { > + .cache_line_size = 64, > +}; Those two structures could probably be marked const. Other than that, the approach definitively looks good to me. -- Florian ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [ 1/1] KVM/MMU: Fix comment in walk_shadow_page_lockless_end()
On 07/09/2018 07:45, Tianyu Lan wrote: > kvm_commit_zap_page() has been renamed to kvm_mmu_commit_zap_page() > This patch is to fix the commit. > > Signed-off-by: Lan Tianyu > --- > arch/x86/kvm/mmu.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c > index 7ccd29b95746..648b839a349d 100644 > --- a/arch/x86/kvm/mmu.c > +++ b/arch/x86/kvm/mmu.c > @@ -947,7 +947,7 @@ static void walk_shadow_page_lockless_end(struct kvm_vcpu > *vcpu) > { > /* >* Make sure the write to vcpu->mode is not reordered in front of > - * reads to sptes. If it does, kvm_commit_zap_page() can see us > + * reads to sptes. If it does, kvm_mmu_commit_zap_page() can see us >* OUTSIDE_GUEST_MODE and proceed to free the shadow page table. >*/ > smp_store_release(&vcpu->mode, OUTSIDE_GUEST_MODE); > Queued, thanks. Paolo ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/4] staging/vc04_services: Use correct cache line size
On 14/09/2018 18:03, Florian Fainelli wrote: On 09/14/2018 06:22 AM, Phil Elwell wrote: Use the compatible string in the DTB to select the correct cache line size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. Signed-off-by: Phil Elwell --- [snip] @@ -170,6 +170,14 @@ static struct device *vchiq_dev; static DEFINE_SPINLOCK(msg_queue_spinlock); static struct platform_device *bcm2835_camera; +static struct vchiq_drvdata bcm2835_drvdata = { + .cache_line_size = 32, +}; + +static struct vchiq_drvdata bcm2836_drvdata = { + .cache_line_size = 64, +}; Those two structures could probably be marked const. Other than that, the approach definitively looks good to me. The mutability is intentional - the structure pointer to the firmware is also stored there. This isn't the only piece of mutable static data in a driver that will only have a single instance, so allocating and initialising a per-instance structure seems needlessly complicated. Thanks for the feedback. Phil ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 1/4] staging/vc04_services: Use correct cache line size
On 09/14/2018 11:12 AM, Phil Elwell wrote: > On 14/09/2018 18:03, Florian Fainelli wrote: >> On 09/14/2018 06:22 AM, Phil Elwell wrote: >>> Use the compatible string in the DTB to select the correct cache line >>> size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. >>> >>> Signed-off-by: Phil Elwell >>> --- >> >> [snip] >> >>> @@ -170,6 +170,14 @@ static struct device *vchiq_dev; >>> static DEFINE_SPINLOCK(msg_queue_spinlock); >>> static struct platform_device *bcm2835_camera; >>> +static struct vchiq_drvdata bcm2835_drvdata = { >>> + .cache_line_size = 32, >>> +}; >>> + >>> +static struct vchiq_drvdata bcm2836_drvdata = { >>> + .cache_line_size = 64, >>> +}; >> >> Those two structures could probably be marked const. Other than that, >> the approach definitively looks good to me. > > The mutability is intentional - the structure pointer to the firmware is > also > stored there. This isn't the only piece of mutable static data in a driver > that will only have a single instance, so allocating and initialising a > per-instance structure seems needlessly complicated. Fair enough, thanks for the explanation. -- Florian ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 0/2] hv_netvsc: associate VF and PV device by serial number
The Hyper-V implementation of PCI controller has concept of 32 bit serial number (not to be confused with PCI-E serial number). This value is sent in the protocol from the host to indicate SR-IOV VF device is attached to a synthetic NIC. Using the serial number (instead of MAC address) to associate the two devices avoids lots of potential problems when there are duplicate MAC addresses from tunnels or layered devices. The patch set is broken into two parts, one is for the PCI controller and the other is for the netvsc device. Normally, these go through different trees but sending them together here for better review. The PCI changes were submitted previously, but the main review comment was "why do you need this?". This is why. v2 - slot name can be shorter. remove locking when creating pci_slots; see comment for explaination Stephen Hemminger (2): PCI: hv: support reporting serial number as slot information hv_netvsc: pair VF based on serial number drivers/net/hyperv/netvsc.c | 3 ++ drivers/net/hyperv/netvsc_drv.c | 58 - drivers/pci/controller/pci-hyperv.c | 37 ++ 3 files changed, 73 insertions(+), 25 deletions(-) -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 2/2] hv_netvsc: pair VF based on serial number
Matching network device based on MAC address is problematic since a non VF network device can be creted with a duplicate MAC address causing confusion and problems. The VMBus API does provide a serial number that is a better matching method. Signed-off-by: Stephen Hemminger --- drivers/net/hyperv/netvsc.c | 3 ++ drivers/net/hyperv/netvsc_drv.c | 58 +++-- 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 31c3d77b4733..fe01e141c8f8 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -1203,6 +1203,9 @@ static void netvsc_send_vf(struct net_device *ndev, net_device_ctx->vf_alloc = nvmsg->msg.v4_msg.vf_assoc.allocated; net_device_ctx->vf_serial = nvmsg->msg.v4_msg.vf_assoc.serial; + netdev_info(ndev, "VF slot %u %s\n", + net_device_ctx->vf_serial, + net_device_ctx->vf_alloc ? "added" : "removed"); } static void netvsc_receive_inband(struct net_device *ndev, diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 1121a1ec407c..9dedc1463e88 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -1894,20 +1894,6 @@ static void netvsc_link_change(struct work_struct *w) rtnl_unlock(); } -static struct net_device *get_netvsc_bymac(const u8 *mac) -{ - struct net_device_context *ndev_ctx; - - list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) { - struct net_device *dev = hv_get_drvdata(ndev_ctx->device_ctx); - - if (ether_addr_equal(mac, dev->perm_addr)) - return dev; - } - - return NULL; -} - static struct net_device *get_netvsc_byref(struct net_device *vf_netdev) { struct net_device_context *net_device_ctx; @@ -2036,26 +2022,48 @@ static void netvsc_vf_setup(struct work_struct *w) rtnl_unlock(); } +/* Find netvsc by VMBus serial number. + * The PCI hyperv controller records the serial number as the slot. + */ +static struct net_device *get_netvsc_byslot(const struct net_device *vf_netdev) +{ + struct device *parent = vf_netdev->dev.parent; + struct net_device_context *ndev_ctx; + struct pci_dev *pdev; + + if (!parent || !dev_is_pci(parent)) + return NULL; /* not a PCI device */ + + pdev = to_pci_dev(parent); + if (!pdev->slot) { + netdev_notice(vf_netdev, "no PCI slot information\n"); + return NULL; + } + + list_for_each_entry(ndev_ctx, &netvsc_dev_list, list) { + if (!ndev_ctx->vf_alloc) + continue; + + if (ndev_ctx->vf_serial == pdev->slot->number) + return hv_get_drvdata(ndev_ctx->device_ctx); + } + + netdev_notice(vf_netdev, + "no netdev found for slot %u\n", pdev->slot->number); + return NULL; +} + static int netvsc_register_vf(struct net_device *vf_netdev) { - struct net_device *ndev; struct net_device_context *net_device_ctx; - struct device *pdev = vf_netdev->dev.parent; struct netvsc_device *netvsc_dev; + struct net_device *ndev; int ret; if (vf_netdev->addr_len != ETH_ALEN) return NOTIFY_DONE; - if (!pdev || !dev_is_pci(pdev) || dev_is_pf(pdev)) - return NOTIFY_DONE; - - /* -* We will use the MAC address to locate the synthetic interface to -* associate with the VF interface. If we don't find a matching -* synthetic interface, move on. -*/ - ndev = get_netvsc_bymac(vf_netdev->perm_addr); + ndev = get_netvsc_byslot(vf_netdev); if (!ndev) return NOTIFY_DONE; -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2 1/2] PCI: hv: support reporting serial number as slot information
The Hyper-V host API for PCI provides a unique "serial number" which can be used as basis for sysfs PCI slot table. This can be useful for cases where userspace wants to find the PCI device based on serial number. When an SR-IOV NIC is added, the host sends an attach message with serial number. The kernel doesn't use the serial number, but it is useful when doing the same thing in a userspace driver such as the DPDK. By having /sys/bus/pci/slots/N it provides a direct way to find the matching PCI device. There maybe some cases where serial number is not unique such as when using GPU's. But the PCI slot infrastructure will handle that. This has a side effect which may also be useful. The common udev network device naming policy uses the slot information (rather than PCI address). Signed-off-by: Stephen Hemminger --- drivers/pci/controller/pci-hyperv.c | 37 + 1 file changed, 37 insertions(+) diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index c00f82cc54aa..ee80e79db21a 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -89,6 +89,9 @@ static enum pci_protocol_version_t pci_protocol_version; #define STATUS_REVISION_MISMATCH 0xC059 +/* space for 32bit serial number as string */ +#define SLOT_NAME_SIZE 11 + /* * Message Types */ @@ -494,6 +497,7 @@ struct hv_pci_dev { struct list_head list_entry; refcount_t refs; enum hv_pcichild_state state; + struct pci_slot *pci_slot; struct pci_function_description desc; bool reported_missing; struct hv_pcibus_device *hbus; @@ -1457,6 +1461,34 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus) spin_unlock_irqrestore(&hbus->device_list_lock, flags); } +/* + * Assign entries in sysfs pci slot directory. + * + * Note that this function does not need to lock the children list + * because it is called from pci_devices_present_work which + * is serialized with hv_eject_device_work because they are on the + * same ordered workqueue. Therefore hbus->children list will not change + * even when pci_create_slot sleeps. + */ +static void hv_pci_assign_slots(struct hv_pcibus_device *hbus) +{ + struct hv_pci_dev *hpdev; + char name[SLOT_NAME_SIZE]; + int slot_nr; + + list_for_each_entry(hpdev, &hbus->children, list_entry) { + if (hpdev->pci_slot) + continue; + + slot_nr = PCI_SLOT(wslot_to_devfn(hpdev->desc.win_slot.slot)); + snprintf(name, SLOT_NAME_SIZE, "%u", hpdev->desc.ser); + hpdev->pci_slot = pci_create_slot(hbus->pci_bus, slot_nr, + name, NULL); + if (!hpdev->pci_slot) + pr_warn("pci_create slot %s failed\n", name); + } +} + /** * create_root_hv_pci_bus() - Expose a new root PCI bus * @hbus: Root PCI bus, as understood by this driver @@ -1480,6 +1512,7 @@ static int create_root_hv_pci_bus(struct hv_pcibus_device *hbus) pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); pci_bus_assign_resources(hbus->pci_bus); + hv_pci_assign_slots(hbus); pci_bus_add_devices(hbus->pci_bus); pci_unlock_rescan_remove(); hbus->state = hv_pcibus_installed; @@ -1742,6 +1775,7 @@ static void pci_devices_present_work(struct work_struct *work) */ pci_lock_rescan_remove(); pci_scan_child_bus(hbus->pci_bus); + hv_pci_assign_slots(hbus); pci_unlock_rescan_remove(); break; @@ -1858,6 +1892,9 @@ static void hv_eject_device_work(struct work_struct *work) list_del(&hpdev->list_entry); spin_unlock_irqrestore(&hpdev->hbus->device_list_lock, flags); + if (hpdev->pci_slot) + pci_destroy_slot(hpdev->pci_slot); + memset(&ctxt, 0, sizeof(ctxt)); ejct_pkt = (struct pci_eject_response *)&ctxt.pkt.message; ejct_pkt->message_type.type = PCI_EJECTION_COMPLETE; -- 2.18.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v2] staging: rtl8188eu: remove code that is valid only for 5 GHz
Remove code that is used only for 5 GHz. This addresses the below TODO item: - find and remove remaining code valid only for 5 GHz. Most of the obvious ones have been removed, but things like channel > 14 still exist. Signed-off-by: Robert Węcławski --- Changes in v2: - set pdev_network->NetworkTypeInUse to Ndis802_110FDM24 in default case drivers/staging/rtl8188eu/core/rtw_ap.c | 23 ++--- drivers/staging/rtl8188eu/core/rtw_debug.c| 25 +-- drivers/staging/rtl8188eu/core/rtw_mlme.c | 12 + drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 13 +- 4 files changed, 10 insertions(+), 63 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_ap.c b/drivers/staging/rtl8188eu/core/rtw_ap.c index e611eda11b5f..1c319c2ca86d 100644 --- a/drivers/staging/rtl8188eu/core/rtw_ap.c +++ b/drivers/staging/rtl8188eu/core/rtw_ap.c @@ -337,8 +337,6 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) unsigned char sta_band = 0, raid, shortGIrate = false; unsigned int tx_ra_bitmap = 0; struct ht_priv *psta_ht = NULL; - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - struct wlan_bssid_ex *pcur_network = (struct wlan_bssid_ex *)&pmlmepriv->cur_network.network; if (psta) psta_ht = &psta->htpriv; @@ -363,20 +361,13 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) shortGIrate = psta_ht->sgi; } - if (pcur_network->Configuration.DSConfig > 14) { - /* 5G band */ - if (tx_ra_bitmap & 0x000) - sta_band |= WIRELESS_11_5N | WIRELESS_11A; - else - sta_band |= WIRELESS_11A; - } else { - if (tx_ra_bitmap & 0x000) - sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B; - else if (tx_ra_bitmap & 0xff0) - sta_band |= WIRELESS_11G | WIRELESS_11B; - else - sta_band |= WIRELESS_11B; - } + if (tx_ra_bitmap & 0x000) + sta_band |= WIRELESS_11_24N | WIRELESS_11G | WIRELESS_11B; + else if (tx_ra_bitmap & 0xff0) + sta_band |= WIRELESS_11G | WIRELESS_11B; + else + sta_band |= WIRELESS_11B; + psta->wireless_mode = sta_band; diff --git a/drivers/staging/rtl8188eu/core/rtw_debug.c b/drivers/staging/rtl8188eu/core/rtw_debug.c index 67461fdf315c..6c2fe1a112ac 100644 --- a/drivers/staging/rtl8188eu/core/rtw_debug.c +++ b/drivers/staging/rtl8188eu/core/rtw_debug.c @@ -153,13 +153,11 @@ int proc_get_best_channel(char *page, char **start, struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; int len = 0; - u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0; + u32 i, best_channel_24G = 1, index_24G = 0; for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) { if (pmlmeext->channel_set[i].ChannelNum == 1) index_24G = i; - if (pmlmeext->channel_set[i].ChannelNum == 36) - index_5G = i; } for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) { @@ -171,32 +169,11 @@ int proc_get_best_channel(char *page, char **start, } } - /* 5G */ - if (pmlmeext->channel_set[i].ChannelNum >= 36 && - pmlmeext->channel_set[i].ChannelNum < 140) { - /* Find primary channel */ - if (((pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0) && - (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) { - index_5G = i; - best_channel_5G = pmlmeext->channel_set[i].ChannelNum; - } - } - - if (pmlmeext->channel_set[i].ChannelNum >= 149 && - pmlmeext->channel_set[i].ChannelNum < 165) { - /* find primary channel */ - if (((pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0) && - (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) { - index_5G = i; - best_channel_5G = pmlmeext->channel_set[i].ChannelNum; - } - } /* debug */ len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n", pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count); } - len += snprintf(page + len, count - len, "best_channel_5G = %d\n",
Re: [PATCH v2 05/17] compat_ioctl: move more drivers to generic_compat_ioctl_ptrarg
On Wed, Sep 12, 2018 at 05:08:52PM +0200, Arnd Bergmann wrote: > The .ioctl and .compat_ioctl file operations have the same prototype so > they can both point to the same function, which works great almost all > the time when all the commands are compatible. > > One exception is the s390 architecture, where a compat pointer is only > 31 bit wide, and converting it into a 64-bit pointer requires calling > compat_ptr(). Most drivers here will ever run in s390, but since we now > have a generic helper for it, it's easy enough to use it consistently. > > I double-checked all these drivers to ensure that all ioctl arguments > are used as pointers or are ignored, but are not interpreted as integer > values. > > Signed-off-by: Arnd Bergmann > --- ... > drivers/platform/x86/wmi.c | 2 +- ... > static void link_event_work(struct work_struct *work) > diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c > index 04791ea5d97b..e4d0697e07d6 100644 > --- a/drivers/platform/x86/wmi.c > +++ b/drivers/platform/x86/wmi.c > @@ -886,7 +886,7 @@ static const struct file_operations wmi_fops = { > .read = wmi_char_read, > .open = wmi_char_open, > .unlocked_ioctl = wmi_ioctl, > - .compat_ioctl = wmi_ioctl, > + .compat_ioctl = generic_compat_ioctl_ptrarg, > }; For platform/drivers/x86: Acked-by: Darren Hart (VMware) As for a longer term solution, would it be possible to init fops in such a way that the compat_ioctl call defaults to generic_compat_ioctl_ptrarg so we don't have to duplicate this boilerplate for every ioctl fops structure? -- Darren Hart VMware Open Source Technology Center ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2 05/17] compat_ioctl: move more drivers to generic_compat_ioctl_ptrarg
On Fri, Sep 14, 2018 at 01:35:06PM -0700, Darren Hart wrote: > Acked-by: Darren Hart (VMware) > > As for a longer term solution, would it be possible to init fops in such > a way that the compat_ioctl call defaults to generic_compat_ioctl_ptrarg > so we don't have to duplicate this boilerplate for every ioctl fops > structure? Bad idea, that... Because several years down the road somebody will add an ioctl that takes an unsigned int for argument. Without so much as looking at your magical mystery macro being used to initialize file_operations. FWIW, I would name that helper in more blunt way - something like compat_ioctl_only_compat_pointer_ioctls_here()... ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v6 3/3] staging: mt7621-mmc: Fix debug macro IRQ_MSG and its usages
On Mon, Sep 10, 2018 at 05:05:13PM +0200, Greg Kroah-Hartman wrote: > On Sat, Sep 01, 2018 at 03:51:10AM +0530, Nishad Kamdar wrote: > > Replace all usages of IRQ_MSG with with dev_ without __func__ > > or __LINE__ or current->comm and current->pid. Remove the do {} > > while(0) loop for the single statement macro. Drop IRQ_MSG from dbg.h. > > Issue found by checkpatch. > > > > Signed-off-by: Nishad Kamdar > > --- > > Changes in v6: > > - No change > > Changes in v5: > > - No change > > --- > > drivers/staging/mt7621-mmc/dbg.h | 12 --- > > drivers/staging/mt7621-mmc/sd.c | 36 > > 2 files changed, 27 insertions(+), 21 deletions(-) > > > > diff --git a/drivers/staging/mt7621-mmc/dbg.h > > b/drivers/staging/mt7621-mmc/dbg.h > > index 79914d98c573..4ab9f10dccc2 100644 > > --- a/drivers/staging/mt7621-mmc/dbg.h > > +++ b/drivers/staging/mt7621-mmc/dbg.h > > @@ -102,18 +102,6 @@ do { \ > > } while (0) > > #endif /* end of +++ */ > > > > -#if 1 > > -//defined CONFIG_MTK_MMC_CD_POLL > > -#define IRQ_MSG(fmt, args...) > > So right now this define does nothing, yet: > > > -#else > > -/* PID in ISR in not corrent */ > > -#define IRQ_MSG(fmt, args...) \ > > -do { \ > > - printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n", \ > > - host->id, ##args, __FUNCTION__, __LINE__); \ > > -} while (0); > > -#endif > > - > > void msdc_debug_proc_init(void); > > > > #if 0 /* --- chhung */ > > diff --git a/drivers/staging/mt7621-mmc/sd.c > > b/drivers/staging/mt7621-mmc/sd.c > > index 7474f9ed7b5b..f3ae19fe0f76 100644 > > --- a/drivers/staging/mt7621-mmc/sd.c > > +++ b/drivers/staging/mt7621-mmc/sd.c > > @@ -279,7 +279,9 @@ static void msdc_tasklet_card(struct work_struct *work) > > mmc_detect_change(host->mmc, msecs_to_jiffies(20)); > > } > > > > - IRQ_MSG("card found<%s>", inserted ? "inserted" : "removed"); > > + dev_err(mmc_dev(host->mmc), > > + "%d -> card found<%s>\n", > > + host->id, inserted ? "inserted" : "removed"); > > You are now printing out lots of "errors" that really are not errors. > > As these messages are not being printed at all right now, why not just > delete these as well? > > Your first 2 patches do look good, I've queued them up now. > > thanks, > > greg k-h Ok, I'll do that. Thanks for the review. regards, nishad ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/2] staging: rtl8723bs: Fix a sleep-in-atomic-context bug in issue_deauth_ex()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.17 are: [FUNC] msleep drivers/staging/rtl8723bs/core/rtw_mlme_ext.c, 3805: msleep in issue_deauth_ex drivers/staging/rtl8723bs/core/rtw_mlme_ext.c, 6336: issue_deauth_ex in disconnect_hdl drivers/staging/rtl8723bs/core/rtw_cmd.c, 963: disconnect_hdl in rtw_disassoc_cmd drivers/staging/rtl8723bs/core/rtw_ioctl_set.c, 506: rtw_disassoc_cmd in rtw_set_802_11_disassociate drivers/staging/rtl8723bs/core/rtw_ioctl_set.c, 501: spin_lock_bh in rtw_set_802_11_disassociate [FUNC] msleep drivers/staging/rtl8723bs/core/rtw_mlme_ext.c, 3805: msleep in issue_deauth_ex drivers/staging/rtl8723bs/core/rtw_mlme_ext.c, 6336: issue_deauth_ex in disconnect_hdl drivers/staging/rtl8723bs/core/rtw_cmd.c, 963: disconnect_hdl in rtw_disassoc_cmd drivers/staging/rtl8723bs/core/rtw_mlme.c, 2256: rtw_disassoc_cmd in rtw_select_and_join_from_scanned_queue drivers/staging/rtl8723bs/core/rtw_mlme.c, 2204: spin_lock_bh in rtw_select_and_join_from_scanned_queue To fix this bug, msleep() is replaced with mdelay(). This bug is found by my static analysis tool DSAC. Signed-off-by: Jia-Ju Bai --- drivers/staging/rtl8723bs/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index 0952d15f6d40..bf055935ef65 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -3796,7 +3796,7 @@ int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int break; if (i < try_cnt && wait_ms > 0 && ret == _FAIL) - msleep(wait_ms); + mdelay(wait_ms); } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); -- 2.17.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/2] staging: rtl8723bs: Fix two sleep-in-atomic-context bugs in _rtw_pwr_wakeup()
The driver may sleep with holding a spinlock. The function call paths (from bottom to top) in Linux-4.17 are: [FUNC] msleep drivers/staging/rtl8723bs/core/rtw_pwrctrl.c, 1243: msleep in _rtw_pwr_wakeup drivers/staging/rtl8723bs/core/rtw_ioctl_set.c, 510: _rtw_pwr_wakeup in rtw_set_802_11_disassociate drivers/staging/rtl8723bs/core/rtw_ioctl_set.c, 501: spin_lock_bh in rtw_set_802_11_disassociate [FUNC] msleep drivers/staging/rtl8723bs/core/rtw_pwrctrl.c, 1255: msleep in _rtw_pwr_wakeup drivers/staging/rtl8723bs/core/rtw_ioctl_set.c, 510: _rtw_pwr_wakeup in rtw_set_802_11_disassociate drivers/staging/rtl8723bs/core/rtw_ioctl_set.c, 501: spin_lock_bh in rtw_set_802_11_disassociate To fix these bugs, msleep() is replaced with mdelay(). These bugs are found by my static analysis tool DSAC. Signed-off-by: Jia-Ju Bai --- drivers/staging/rtl8723bs/core/rtw_pwrctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c index 110bbe340b78..59a667753266 100644 --- a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c @@ -1232,7 +1232,7 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal if (pwrpriv->ps_processing) { DBG_871X("%s wait ps_processing...\n", __func__); while (pwrpriv->ps_processing && jiffies_to_msecs(jiffies - start) <= 3000) - msleep(10); + mdelay(10); if (pwrpriv->ps_processing) DBG_871X("%s wait ps_processing timeout\n", __func__); else @@ -1244,7 +1244,7 @@ int _rtw_pwr_wakeup(struct adapter *padapter, u32 ips_deffer_ms, const char *cal while (pwrpriv->bInSuspend && jiffies_to_msecs(jiffies - start) <= 3000 ) { - msleep(10); + mdelay(10); } if (pwrpriv->bInSuspend) DBG_871X("%s wait bInSuspend timeout\n", __func__); -- 2.17.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v7 0/1] staging: mt7621-mmc: Fix debug macros and their usages
This patch fixes the the debug macro IRQ_MSG(). It deletes IRQ_MSG() and all its users as currently it is a no-op. Changes in v7: - Delete IRQ_MSG() macro and its users. - Patchset reduced to 1 patch as the patches fixing N_MSG() and ERR_MSG() have been accepted. Changes in v6: - Delete N_MSG() macro and its users as it is a no-op. - Patchset reduced to 3 patches as the INIT_MSG patch is accepted. Changes in v5: - Remove commented code for N_MSG(). - Remove commented ERR_MSG() usages. Changes in v4: - Create multiple patches, one for each type of macro being deleted/changed. Changes in v3: - Replace usages of ERR_MSG and IRQ_MSG with dev_err() in code itself. - Remove all INIT_MSG usages. - Drop ERR_MSG, INIT_MSG and IRQ_MSG from dbg.h. Changes in v2: - Replace printk with dev_. - Remove __func__, __LINE__, current->comm, current->pid from arguments. - Remove the do {} while(0) loop from these macros. - Modify commit message to include other changes. Nishad Kamdar (1): staging: mt7621-mmc: Delete IRQ_MSG() and its users drivers/staging/mt7621-mmc/dbg.h | 12 drivers/staging/mt7621-mmc/sd.c | 19 --- 2 files changed, 31 deletions(-) -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: rtl8188eu: Fix a sleep-in-atomic-context bug in issue_deauth_ex()
The driver may sleep with holding a spinlock. The function call path (from bottom to top) in Linux-4.17 is: [FUNC] msleep drivers/staging/rtl8188eu/core/rtw_mlme_ext.c, 1536: msleep in issue_deauth_ex drivers/staging/rtl8188eu/core/rtw_mlme_ext.c, 5110: issue_deauth_ex in disconnect_hdl drivers/staging/rtl8188eu/core/rtw_cmd.c, 521: disconnect_hdl in rtw_disassoc_cmd drivers/staging/rtl8188eu/core/rtw_ioctl_set.c, 352: rtw_disassoc_cmd in rtw_set_802_11_infrastructure_mode drivers/staging/rtl8188eu/os_dep/ioctl_linux.c, 1002: rtw_set_802_11_infrastructure_mode in rtw_wx_set_wap drivers/staging/rtl8188eu/os_dep/ioctl_linux.c, 988: spin_lock_bh in rtw_wx_set_wap To fix this bug, msleep() is replaced with mdelay(). This bug is found by my static analysis tool DSAC. Signed-off-by: Jia-Ju Bai --- drivers/staging/rtl8188eu/core/rtw_mlme_ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c index 1115050077e4..f47d83e6dfb9 100644 --- a/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8188eu/core/rtw_mlme_ext.c @@ -1513,7 +1513,7 @@ static int issue_deauth_ex(struct adapter *padapter, u8 *da, break; if (i < try_cnt && wait_ms > 0 && ret == _FAIL) - msleep(wait_ms); + mdelay(wait_ms); } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); if (ret != _FAIL) { -- 2.17.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v7 1/1] staging: mt7621-mmc: Delete IRQ_MSG() and its users.
This patch removes IRQ_MSG() and its users as currently it is a no-op. Signed-off-by: Nishad Kamdar --- Changes in v7: - Delete IRQ_MSG() and all its users Changes in v6: - No change Changes in v5: - No change --- drivers/staging/mt7621-mmc/dbg.h | 12 drivers/staging/mt7621-mmc/sd.c | 19 --- 2 files changed, 31 deletions(-) diff --git a/drivers/staging/mt7621-mmc/dbg.h b/drivers/staging/mt7621-mmc/dbg.h index 79914d98c573..4ab9f10dccc2 100644 --- a/drivers/staging/mt7621-mmc/dbg.h +++ b/drivers/staging/mt7621-mmc/dbg.h @@ -102,18 +102,6 @@ do { \ } while (0) #endif /* end of +++ */ -#if 1 -//defined CONFIG_MTK_MMC_CD_POLL -#define IRQ_MSG(fmt, args...) -#else -/* PID in ISR in not corrent */ -#define IRQ_MSG(fmt, args...) \ -do { \ - printk(KERN_ERR TAG"%d -> "fmt" <- %s() : L<%d>\n", \ - host->id, ##args, __FUNCTION__, __LINE__); \ -} while (0); -#endif - void msdc_debug_proc_init(void); #if 0 /* --- chhung */ diff --git a/drivers/staging/mt7621-mmc/sd.c b/drivers/staging/mt7621-mmc/sd.c index 7474f9ed7b5b..273593427d3a 100644 --- a/drivers/staging/mt7621-mmc/sd.c +++ b/drivers/staging/mt7621-mmc/sd.c @@ -278,8 +278,6 @@ static void msdc_tasklet_card(struct work_struct *work) host->mmc->f_max = HOST_MAX_MCLK; mmc_detect_change(host->mmc, msecs_to_jiffies(20)); } - - IRQ_MSG("card found<%s>", inserted ? "inserted" : "removed"); #endif spin_unlock(&host->lock); @@ -1638,17 +1636,10 @@ static irqreturn_t msdc_irq(int irq, void *dev_id) if (intsts & MSDC_INT_CDSC) { if (host->mmc->caps & MMC_CAP_NEEDS_POLL) return IRQ_HANDLED; - IRQ_MSG("MSDC_INT_CDSC irq<0x%.8x>", intsts); schedule_delayed_work(&host->card_delaywork, HZ); /* tuning when plug card ? */ } - /* sdio interrupt */ - if (intsts & MSDC_INT_SDIOIRQ) { - IRQ_MSG("XXX MSDC_INT_SDIOIRQ"); /* seems not sdio irq */ - //mmc_signal_sdio_irq(host->mmc); - } - /* transfer complete interrupt */ if (data != NULL) { if (inten & MSDC_INT_XFER_COMPL) { @@ -1663,10 +1654,8 @@ static irqreturn_t msdc_irq(int irq, void *dev_id) msdc_clr_int(); if (intsts & MSDC_INT_DATTMO) { - IRQ_MSG("XXX CMD<%d> MSDC_INT_DATTMO", host->mrq->cmd->opcode); data->error = -ETIMEDOUT; } else if (intsts & MSDC_INT_DATCRCERR) { - IRQ_MSG("XXX CMD<%d> MSDC_INT_DATCRCERR, SDC_DCRC_STS<0x%x>", host->mrq->cmd->opcode, readl(host->base + SDC_DCRC_STS)); data->error = -EIO; } @@ -1698,16 +1687,8 @@ static irqreturn_t msdc_irq(int irq, void *dev_id) break; } } else if ((intsts & MSDC_INT_RSPCRCERR) || (intsts & MSDC_INT_ACMDCRCERR)) { - if (intsts & MSDC_INT_ACMDCRCERR) - IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDCRCERR", cmd->opcode); - else - IRQ_MSG("XXX CMD<%d> MSDC_INT_RSPCRCERR", cmd->opcode); cmd->error = -EIO; } else if ((intsts & MSDC_INT_CMDTMO) || (intsts & MSDC_INT_ACMDTMO)) { - if (intsts & MSDC_INT_ACMDTMO) - IRQ_MSG("XXX CMD<%d> MSDC_INT_ACMDTMO", cmd->opcode); - else - IRQ_MSG("XXX CMD<%d> MSDC_INT_CMDTMO", cmd->opcode); cmd->error = -ETIMEDOUT; msdc_reset_hw(host); msdc_clr_fifo(host); -- 2.17.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] staging: dgnc: Fix a sleep-in-atomic-context bug in cls_assert_modem_signals()
The driver may sleep with holding a spinlock. The function call path (from bottom to top) in Linux-4.17 is: [FUNC] usleep_range drivers/staging/dgnc/dgnc_cls.c, 391: usleep_range in cls_assert_modem_signals drivers/staging/dgnc/dgnc_cls.c, 449: cls_assert_modem_signals in cls_copy_data_from_queue_to_uart drivers/staging/dgnc/dgnc_cls.c, 406: _raw_spin_lock_irqsave in cls_copy_data_from_queue_to_uart To fix this bug, usleep_range() is replaced with udelay(). This bug is found by my static analysis tool DSAC. Signed-off-by: Jia-Ju Bai --- drivers/staging/dgnc/dgnc_cls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index 7e6cbfe4e4ee..a1e98ee7f9e0 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -388,7 +388,7 @@ static void cls_assert_modem_signals(struct channel_t *ch) writeb(out, &ch->ch_cls_uart->mcr); /* Give time for the UART to actually drop the signals */ - usleep_range(10, 20); + udelay(20); } static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) -- 2.17.0 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [patch 02/11] x86/time: Implement clocksource_arch_init()
On Fri, 14 Sep 2018, Vitaly Kuznetsov wrote: > Thomas Gleixner writes: > > + > > + if (cs->archdata.vclock_mode >= VCLOCK_MAX) { > > It should be '>' as VCLOCK_MAX == VCLOCK_HVCLOCK == 3 Indeed. Thanks, tglx ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel