[Regression?] iptables broken on 32bit with pre-4.7-rc
Hey Florian, Pablo, In updating a 32bit arm device from 4.6 to Linus' current HEAD, I noticed I was having some trouble with networking, and realized that /proc/net/ip_tables_names was suddenly empty. Digging through the registration process, it seems we're catching on the: if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 && target_offset + sizeof(struct xt_standard_target) != next_offset) return -EINVAL; check added in 7ed2abddd20cf ("netfilter: x_tables: check standard target size too"). Where next_offset seems to be 4 bytes larger then the the offset + standard_target struct size. Commenting out those checks (the commit doesn't revert cleanly), seems to get things going again for me. I'm not exactly sure how the next_offset value is set, so I'm hoping the proper fix is more obvious to one of you. thanks -john
[Regression?] iptables broken on 32bit with pre-4.7-rc
Hey Florian, Pablo, In updating a 32bit arm device from 4.6 to Linus' current HEAD, I noticed I was having some trouble with networking, and realized that /proc/net/ip_tables_names was suddenly empty. Digging through the registration process, it seems we're catching on the: if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 && target_offset + sizeof(struct xt_standard_target) != next_offset) return -EINVAL; check added in 7ed2abddd20cf ("netfilter: x_tables: check standard target size too"). Where next_offset seems to be 4 bytes larger then the the offset + standard_target struct size. Commenting out those checks (the commit doesn't revert cleanly), seems to get things going again for me. I'm not exactly sure how the next_offset value is set, so I'm hoping the proper fix is more obvious to one of you. thanks -john
Re: [PATCH 0/2] arm: dra7: Add i2c6 instance hwmod and dt entries
On 25/05/16 19:09, Nishanth Menon wrote: On 05/25/2016 07:53 AM, Ravikumar Kattekola wrote: DRA72x devices have a sixth i2c ocntroller instance. Following patches add the required hwmod structure and device tree nodes. Reference doc: DRA72x TRM [ SPRUHP2Q ] Tested on : DRA72x Rev B EVM Ravikumar Kattekola (2): arm: dra7: Add hwmod entry for i2c6 dts: dra7: Add device tree node for i2c6 arch/arm/boot/dts/dra7.dtsi | 11 +++ arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 23 +++ 2 files changed, 34 insertions(+) NAK. reasoning: a) i2c6 is a custom IP integration with completely non-standard dependencies with cross device dependencies for pretty much a specific usecase -> usage is pretty much limited for generic support - the decision is NOT to support this instance in Linux kernel - internal discussion forwarded to developer. b) the patches themselves are wrong -> it applies to DRA72x not generic DRA7x platform c) patches themselves are in the wrong format (wrong subject line etc). d) patches don't handle the SoC internal device dependencies either -> in short will not function in a generic solution for all variations of platforms. Yes please drop this, attempting to support it in upstream is just going to cause unnecessary pain. -Tero
Re: [PATCH 0/2] arm: dra7: Add i2c6 instance hwmod and dt entries
On 25/05/16 19:09, Nishanth Menon wrote: On 05/25/2016 07:53 AM, Ravikumar Kattekola wrote: DRA72x devices have a sixth i2c ocntroller instance. Following patches add the required hwmod structure and device tree nodes. Reference doc: DRA72x TRM [ SPRUHP2Q ] Tested on : DRA72x Rev B EVM Ravikumar Kattekola (2): arm: dra7: Add hwmod entry for i2c6 dts: dra7: Add device tree node for i2c6 arch/arm/boot/dts/dra7.dtsi | 11 +++ arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 23 +++ 2 files changed, 34 insertions(+) NAK. reasoning: a) i2c6 is a custom IP integration with completely non-standard dependencies with cross device dependencies for pretty much a specific usecase -> usage is pretty much limited for generic support - the decision is NOT to support this instance in Linux kernel - internal discussion forwarded to developer. b) the patches themselves are wrong -> it applies to DRA72x not generic DRA7x platform c) patches themselves are in the wrong format (wrong subject line etc). d) patches don't handle the SoC internal device dependencies either -> in short will not function in a generic solution for all variations of platforms. Yes please drop this, attempting to support it in upstream is just going to cause unnecessary pain. -Tero
Re: [Intel-gfx] [v4.6-10530-g28165ec7a99b] i915: *ERROR* "CPU pipe/PCH transcoder" A FIFO underrun
On 5/25/16, Jani Nikulawrote: > On Wed, 25 May 2016, Sedat Dilek wrote: >> Hi Daniel, >> >> with latest Linus Git I see this with my Intel SandyBridge GPU... >> >> [ 17.629014] [drm:intel_cpu_fifo_underrun_irq_handler [i915]] >> *ERROR* CPU pipe A FIFO underrun >> [ 17.630652] [drm:intel_set_pch_fifo_underrun_reporting [i915]] >> *ERROR* uncleared pch fifo underrun on pch transcoder A >> [ 17.630685] [drm:intel_pch_fifo_underrun_irq_handler [i915]] >> *ERROR* PCH transcoder A FIFO underrun >> >> Attached are my linux-config, dmesg-output anx Xorg-log. >> >> Any other informations you need? > > For starters, please try the fixes pull I just sent on top [1]. There's > a couple of watermark fixes. > > BR, > Jani. > > > > [1] http://mid.gmane.org/87zirebjm7@intel.com > > > > -- > Jani Nikula, Intel Open Source Technology Center > I pulled in drm-intel.git#tags/drm-intel-next-fixes-2016-05-25 on top of above mentionned latest Linus Git and the problem still remains! $ dmesg | egrep i915 | grep -i error [ 19.583713] [drm:intel_cpu_fifo_underrun_irq_handler [i915]] *ERROR* CPU pipe A FIFO underrun [ 19.586363] [drm:intel_set_pch_fifo_underrun_reporting [i915]] *ERROR* uncleared pch fifo underrun on pch transcoder A [ 19.586399] [drm:intel_pch_fifo_underrun_irq_handler [i915]] *ERROR* PCH transcoder A FIFO underrun I have attached my dmesg-output only, the linux-config I had sent earlier. - Sedat - [0.00] Linux version 4.6.0-10530.2-iniza-small (sedat.di...@gmail.com@fambox) (gcc version 4.9.2 (Ubuntu 4.9.2-0ubuntu1~12.04) ) #1 SMP Thu May 26 07:20:40 CEST 2016 [0.00] Command line: BOOT_IMAGE=/boot/vmlinuz-4.6.0-10530.2-iniza-small root=UUID=001AADA61AAD9964 loop=/ubuntu/disks/root.disk ro intel_pstate=disable [0.00] KERNEL supported cpus: [0.00] Intel GenuineIntel [0.00] AMD AuthenticAMD [0.00] Centaur CentaurHauls [0.00] Disabled fast string operations [0.00] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256 [0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' [0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers' [0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers' [0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format. [0.00] x86/fpu: Using 'eager' FPU context switches. [0.00] e820: BIOS-provided physical RAM map: [0.00] BIOS-e820: [mem 0x-0x0009d7ff] usable [0.00] BIOS-e820: [mem 0x0009d800-0x0009] reserved [0.00] BIOS-e820: [mem 0x000e-0x000f] reserved [0.00] BIOS-e820: [mem 0x0010-0x1fff] usable [0.00] BIOS-e820: [mem 0x2000-0x201f] reserved [0.00] BIOS-e820: [mem 0x2020-0x3fff] usable [0.00] BIOS-e820: [mem 0x4000-0x401f] reserved [0.00] BIOS-e820: [mem 0x4020-0xd9c9efff] usable [0.00] BIOS-e820: [mem 0xd9c9f000-0xdae7efff] reserved [0.00] BIOS-e820: [mem 0xdae7f000-0xdaf9efff] ACPI NVS [0.00] BIOS-e820: [mem 0xdaf9f000-0xdaffefff] ACPI data [0.00] BIOS-e820: [mem 0xdafff000-0xdaff] usable [0.00] BIOS-e820: [mem 0xdb00-0xdf9f] reserved [0.00] BIOS-e820: [mem 0xf800-0xfbff] reserved [0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved [0.00] BIOS-e820: [mem 0xfed08000-0xfed08fff] reserved [0.00] BIOS-e820: [mem 0xfed1-0xfed19fff] reserved [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved [0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved [0.00] BIOS-e820: [mem 0xffd8-0x] reserved [0.00] BIOS-e820: [mem 0x0001-0x00011fdf] usable [0.00] NX (Execute Disable) protection: active [0.00] SMBIOS 2.6 present. [0.00] DMI: SAMSUNG ELECTRONICS CO., LTD. 530U3BI/530U4BI/530U4BH/530U3BI/530U4BI/530U4BH, BIOS 13XK 03/28/2013 [0.00] e820: update [mem 0x-0x0fff] usable ==> reserved [0.00] e820: remove [mem 0x000a-0x000f] usable [0.00] e820: last_pfn = 0x11fe00 max_arch_pfn = 0x4 [0.00] MTRR default type: uncachable [0.00] MTRR fixed ranges enabled: [0.00] 0-9 write-back [0.00] A-B uncachable [0.00] C-F write-protect [0.00] MTRR variable ranges enabled: [0.00] 0 base 0 mask F8000 write-back [0.00] 1 base 08000 mask FC000 write-back [0.00]
Re: [Intel-gfx] [v4.6-10530-g28165ec7a99b] i915: *ERROR* "CPU pipe/PCH transcoder" A FIFO underrun
On 5/25/16, Jani Nikula wrote: > On Wed, 25 May 2016, Sedat Dilek wrote: >> Hi Daniel, >> >> with latest Linus Git I see this with my Intel SandyBridge GPU... >> >> [ 17.629014] [drm:intel_cpu_fifo_underrun_irq_handler [i915]] >> *ERROR* CPU pipe A FIFO underrun >> [ 17.630652] [drm:intel_set_pch_fifo_underrun_reporting [i915]] >> *ERROR* uncleared pch fifo underrun on pch transcoder A >> [ 17.630685] [drm:intel_pch_fifo_underrun_irq_handler [i915]] >> *ERROR* PCH transcoder A FIFO underrun >> >> Attached are my linux-config, dmesg-output anx Xorg-log. >> >> Any other informations you need? > > For starters, please try the fixes pull I just sent on top [1]. There's > a couple of watermark fixes. > > BR, > Jani. > > > > [1] http://mid.gmane.org/87zirebjm7@intel.com > > > > -- > Jani Nikula, Intel Open Source Technology Center > I pulled in drm-intel.git#tags/drm-intel-next-fixes-2016-05-25 on top of above mentionned latest Linus Git and the problem still remains! $ dmesg | egrep i915 | grep -i error [ 19.583713] [drm:intel_cpu_fifo_underrun_irq_handler [i915]] *ERROR* CPU pipe A FIFO underrun [ 19.586363] [drm:intel_set_pch_fifo_underrun_reporting [i915]] *ERROR* uncleared pch fifo underrun on pch transcoder A [ 19.586399] [drm:intel_pch_fifo_underrun_irq_handler [i915]] *ERROR* PCH transcoder A FIFO underrun I have attached my dmesg-output only, the linux-config I had sent earlier. - Sedat - [0.00] Linux version 4.6.0-10530.2-iniza-small (sedat.di...@gmail.com@fambox) (gcc version 4.9.2 (Ubuntu 4.9.2-0ubuntu1~12.04) ) #1 SMP Thu May 26 07:20:40 CEST 2016 [0.00] Command line: BOOT_IMAGE=/boot/vmlinuz-4.6.0-10530.2-iniza-small root=UUID=001AADA61AAD9964 loop=/ubuntu/disks/root.disk ro intel_pstate=disable [0.00] KERNEL supported cpus: [0.00] Intel GenuineIntel [0.00] AMD AuthenticAMD [0.00] Centaur CentaurHauls [0.00] Disabled fast string operations [0.00] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256 [0.00] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' [0.00] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers' [0.00] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers' [0.00] x86/fpu: Enabled xstate features 0x7, context size is 832 bytes, using 'standard' format. [0.00] x86/fpu: Using 'eager' FPU context switches. [0.00] e820: BIOS-provided physical RAM map: [0.00] BIOS-e820: [mem 0x-0x0009d7ff] usable [0.00] BIOS-e820: [mem 0x0009d800-0x0009] reserved [0.00] BIOS-e820: [mem 0x000e-0x000f] reserved [0.00] BIOS-e820: [mem 0x0010-0x1fff] usable [0.00] BIOS-e820: [mem 0x2000-0x201f] reserved [0.00] BIOS-e820: [mem 0x2020-0x3fff] usable [0.00] BIOS-e820: [mem 0x4000-0x401f] reserved [0.00] BIOS-e820: [mem 0x4020-0xd9c9efff] usable [0.00] BIOS-e820: [mem 0xd9c9f000-0xdae7efff] reserved [0.00] BIOS-e820: [mem 0xdae7f000-0xdaf9efff] ACPI NVS [0.00] BIOS-e820: [mem 0xdaf9f000-0xdaffefff] ACPI data [0.00] BIOS-e820: [mem 0xdafff000-0xdaff] usable [0.00] BIOS-e820: [mem 0xdb00-0xdf9f] reserved [0.00] BIOS-e820: [mem 0xf800-0xfbff] reserved [0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved [0.00] BIOS-e820: [mem 0xfed08000-0xfed08fff] reserved [0.00] BIOS-e820: [mem 0xfed1-0xfed19fff] reserved [0.00] BIOS-e820: [mem 0xfed1c000-0xfed1] reserved [0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved [0.00] BIOS-e820: [mem 0xffd8-0x] reserved [0.00] BIOS-e820: [mem 0x0001-0x00011fdf] usable [0.00] NX (Execute Disable) protection: active [0.00] SMBIOS 2.6 present. [0.00] DMI: SAMSUNG ELECTRONICS CO., LTD. 530U3BI/530U4BI/530U4BH/530U3BI/530U4BI/530U4BH, BIOS 13XK 03/28/2013 [0.00] e820: update [mem 0x-0x0fff] usable ==> reserved [0.00] e820: remove [mem 0x000a-0x000f] usable [0.00] e820: last_pfn = 0x11fe00 max_arch_pfn = 0x4 [0.00] MTRR default type: uncachable [0.00] MTRR fixed ranges enabled: [0.00] 0-9 write-back [0.00] A-B uncachable [0.00] C-F write-protect [0.00] MTRR variable ranges enabled: [0.00] 0 base 0 mask F8000 write-back [0.00] 1 base 08000 mask FC000 write-back [0.00] 2 base 0C000 mask FE000 write-back [
Re: [PATCH] ACPI / Thermal / video: fix max_level incorrect value
On 05/26/2016 09:49 AM, valdis.kletni...@vt.edu wrote: > On Wed, 25 May 2016 13:15:26 +0800, Aaron Lu said: >> Valdis, can you please give the patch a try? Thanks. > > Sorry, had a few days where actual work commitments and other > things got in the way... I tested this patch against next-20160524, > and can report that the problem is fixed, so feel free to > stick a "Tested-By:" on it Thanks a lot for the confirm, here is the updated patch with your tested-by tag added. From: Aaron LuDate: Sat, 21 May 2016 15:30:46 +0800 Subject: [PATCH] ACPI / Thermal / video: fix max_level incorrect value commit 059500940def("ACPI/video: export acpi_video_get_levels") mistakenly dropped the correct value of max_level and that caused the set_level function following failed and the acpi_video backlight interface didn't get created. Fix this by passing back the correct max_level value. While at it, also fix the param used in acpi_video_device_lcd_query_levels where acpi_handle is expected but acpi_video_device is passed. Reported-and-tested-by: Valdis Kletnieks Signed-off-by: Aaron Lu --- drivers/acpi/acpi_video.c | 9 ++--- drivers/thermal/int340x_thermal/int3406_thermal.c | 2 +- include/acpi/video.h | 6 -- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 3d5b8a099351..c1d138e128cb 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -754,7 +754,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device, } int acpi_video_get_levels(struct acpi_device *device, - struct acpi_video_device_brightness **dev_br) + struct acpi_video_device_brightness **dev_br, + int *pmax_level) { union acpi_object *obj = NULL; int i, max_level = 0, count = 0, level_ac_battery = 0; @@ -841,6 +842,8 @@ int acpi_video_get_levels(struct acpi_device *device, br->count = count; *dev_br = br; + if (pmax_level) + *pmax_level = max_level; out: kfree(obj); @@ -869,7 +872,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) struct acpi_video_device_brightness *br = NULL; int result = -EINVAL; - result = acpi_video_get_levels(device->dev, ); + result = acpi_video_get_levels(device->dev, , _level); if (result) return result; device->brightness = br; @@ -1737,7 +1740,7 @@ static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video) mutex_lock(>device_list_lock); list_for_each_entry(dev, >video_device_list, entry) { - if (!acpi_video_device_lcd_query_levels(dev, )) + if (!acpi_video_device_lcd_query_levels(dev->dev->handle, )) kfree(levels); } mutex_unlock(>device_list_lock); diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c b/drivers/thermal/int340x_thermal/int3406_thermal.c index 13d431cbd29e..a578cd257db4 100644 --- a/drivers/thermal/int340x_thermal/int3406_thermal.c +++ b/drivers/thermal/int340x_thermal/int3406_thermal.c @@ -177,7 +177,7 @@ static int int3406_thermal_probe(struct platform_device *pdev) return -ENODEV; d->raw_bd = bd; - ret = acpi_video_get_levels(ACPI_COMPANION(>dev), >br); + ret = acpi_video_get_levels(ACPI_COMPANION(>dev), >br, NULL); if (ret) return ret; diff --git a/include/acpi/video.h b/include/acpi/video.h index 70a41f742037..5731ccb42585 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -51,7 +51,8 @@ extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type); */ extern bool acpi_video_handles_brightness_key_presses(void); extern int acpi_video_get_levels(struct acpi_device *device, -struct acpi_video_device_brightness **dev_br); +struct acpi_video_device_brightness **dev_br, +int *pmax_level); #else static inline int acpi_video_register(void) { return 0; } static inline void acpi_video_unregister(void) { return; } @@ -72,7 +73,8 @@ static inline bool acpi_video_handles_brightness_key_presses(void) return false; } static inline int acpi_video_get_levels(struct acpi_device *device, - struct acpi_video_device_brightness **dev_br) + struct acpi_video_device_brightness **dev_br, + int *pmax_level) { return -ENODEV; } -- 2.5.5
Re: [PATCH] ACPI / Thermal / video: fix max_level incorrect value
On 05/26/2016 09:49 AM, valdis.kletni...@vt.edu wrote: > On Wed, 25 May 2016 13:15:26 +0800, Aaron Lu said: >> Valdis, can you please give the patch a try? Thanks. > > Sorry, had a few days where actual work commitments and other > things got in the way... I tested this patch against next-20160524, > and can report that the problem is fixed, so feel free to > stick a "Tested-By:" on it Thanks a lot for the confirm, here is the updated patch with your tested-by tag added. From: Aaron Lu Date: Sat, 21 May 2016 15:30:46 +0800 Subject: [PATCH] ACPI / Thermal / video: fix max_level incorrect value commit 059500940def("ACPI/video: export acpi_video_get_levels") mistakenly dropped the correct value of max_level and that caused the set_level function following failed and the acpi_video backlight interface didn't get created. Fix this by passing back the correct max_level value. While at it, also fix the param used in acpi_video_device_lcd_query_levels where acpi_handle is expected but acpi_video_device is passed. Reported-and-tested-by: Valdis Kletnieks Signed-off-by: Aaron Lu --- drivers/acpi/acpi_video.c | 9 ++--- drivers/thermal/int340x_thermal/int3406_thermal.c | 2 +- include/acpi/video.h | 6 -- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 3d5b8a099351..c1d138e128cb 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -754,7 +754,8 @@ static int acpi_video_bqc_quirk(struct acpi_video_device *device, } int acpi_video_get_levels(struct acpi_device *device, - struct acpi_video_device_brightness **dev_br) + struct acpi_video_device_brightness **dev_br, + int *pmax_level) { union acpi_object *obj = NULL; int i, max_level = 0, count = 0, level_ac_battery = 0; @@ -841,6 +842,8 @@ int acpi_video_get_levels(struct acpi_device *device, br->count = count; *dev_br = br; + if (pmax_level) + *pmax_level = max_level; out: kfree(obj); @@ -869,7 +872,7 @@ acpi_video_init_brightness(struct acpi_video_device *device) struct acpi_video_device_brightness *br = NULL; int result = -EINVAL; - result = acpi_video_get_levels(device->dev, ); + result = acpi_video_get_levels(device->dev, , _level); if (result) return result; device->brightness = br; @@ -1737,7 +1740,7 @@ static void acpi_video_run_bcl_for_osi(struct acpi_video_bus *video) mutex_lock(>device_list_lock); list_for_each_entry(dev, >video_device_list, entry) { - if (!acpi_video_device_lcd_query_levels(dev, )) + if (!acpi_video_device_lcd_query_levels(dev->dev->handle, )) kfree(levels); } mutex_unlock(>device_list_lock); diff --git a/drivers/thermal/int340x_thermal/int3406_thermal.c b/drivers/thermal/int340x_thermal/int3406_thermal.c index 13d431cbd29e..a578cd257db4 100644 --- a/drivers/thermal/int340x_thermal/int3406_thermal.c +++ b/drivers/thermal/int340x_thermal/int3406_thermal.c @@ -177,7 +177,7 @@ static int int3406_thermal_probe(struct platform_device *pdev) return -ENODEV; d->raw_bd = bd; - ret = acpi_video_get_levels(ACPI_COMPANION(>dev), >br); + ret = acpi_video_get_levels(ACPI_COMPANION(>dev), >br, NULL); if (ret) return ret; diff --git a/include/acpi/video.h b/include/acpi/video.h index 70a41f742037..5731ccb42585 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h @@ -51,7 +51,8 @@ extern void acpi_video_set_dmi_backlight_type(enum acpi_backlight_type type); */ extern bool acpi_video_handles_brightness_key_presses(void); extern int acpi_video_get_levels(struct acpi_device *device, -struct acpi_video_device_brightness **dev_br); +struct acpi_video_device_brightness **dev_br, +int *pmax_level); #else static inline int acpi_video_register(void) { return 0; } static inline void acpi_video_unregister(void) { return; } @@ -72,7 +73,8 @@ static inline bool acpi_video_handles_brightness_key_presses(void) return false; } static inline int acpi_video_get_levels(struct acpi_device *device, - struct acpi_video_device_brightness **dev_br) + struct acpi_video_device_brightness **dev_br, + int *pmax_level) { return -ENODEV; } -- 2.5.5
[PATCH] mm/cma: silence warnings due to max() usage
pageblock_order can be (at least) an unsigned int or an unsigned long depending on the kernel config and architecture, so use max_t(unsigned long, ...) when comparing it. fixes these warnings: In file included from include/asm-generic/bug.h:13:0, from arch/powerpc/include/asm/bug.h:127, from include/linux/bug.h:4, from include/linux/mmdebug.h:4, from include/linux/mm.h:8, from include/linux/memblock.h:18, from mm/cma.c:28: mm/cma.c: In function 'cma_init_reserved_mem': include/linux/kernel.h:748:17: warning: comparison of distinct pointer types lacks a cast (void) (&_max1 == &_max2); \ ^ mm/cma.c:186:27: note: in expansion of macro 'max' alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); ^ mm/cma.c: In function 'cma_declare_contiguous': include/linux/kernel.h:748:17: warning: comparison of distinct pointer types lacks a cast (void) (&_max1 == &_max2); \ ^ include/linux/kernel.h:747:9: note: in definition of macro 'max' typeof(y) _max2 = (y); \ ^ mm/cma.c:270:29: note: in expansion of macro 'max' (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order)); ^ include/linux/kernel.h:748:17: warning: comparison of distinct pointer types lacks a cast (void) (&_max1 == &_max2); \ ^ include/linux/kernel.h:747:21: note: in definition of macro 'max' typeof(y) _max2 = (y); \ ^ mm/cma.c:270:29: note: in expansion of macro 'max' (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order)); ^ Signed-off-by: Stephen Rothwell--- mm/cma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) These warnings have been irking me for some time now ... applies to Linus' tree and linux-next (and so to the mmotm tree). diff --git a/mm/cma.c b/mm/cma.c index ea506eb18cd6..fa823dc2ff15 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -183,7 +183,7 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, return -EINVAL; /* ensure minimal alignment required by mm core */ - alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); + alignment = PAGE_SIZE << max_t(unsigned long, MAX_ORDER - 1, pageblock_order); /* alignment should be aligned with order_per_bit */ if (!IS_ALIGNED(alignment >> PAGE_SHIFT, 1 << order_per_bit)) @@ -267,7 +267,7 @@ int __init cma_declare_contiguous(phys_addr_t base, * you couldn't get a contiguous memory, which is not what we want. */ alignment = max(alignment, - (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order)); + (phys_addr_t)PAGE_SIZE << max_t(unsigned long, MAX_ORDER - 1, pageblock_order)); base = ALIGN(base, alignment); size = ALIGN(size, alignment); limit &= ~(alignment - 1); -- 2.8.1 -- Cheers, Stephen Rothwell
[PATCH] mm/cma: silence warnings due to max() usage
pageblock_order can be (at least) an unsigned int or an unsigned long depending on the kernel config and architecture, so use max_t(unsigned long, ...) when comparing it. fixes these warnings: In file included from include/asm-generic/bug.h:13:0, from arch/powerpc/include/asm/bug.h:127, from include/linux/bug.h:4, from include/linux/mmdebug.h:4, from include/linux/mm.h:8, from include/linux/memblock.h:18, from mm/cma.c:28: mm/cma.c: In function 'cma_init_reserved_mem': include/linux/kernel.h:748:17: warning: comparison of distinct pointer types lacks a cast (void) (&_max1 == &_max2); \ ^ mm/cma.c:186:27: note: in expansion of macro 'max' alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); ^ mm/cma.c: In function 'cma_declare_contiguous': include/linux/kernel.h:748:17: warning: comparison of distinct pointer types lacks a cast (void) (&_max1 == &_max2); \ ^ include/linux/kernel.h:747:9: note: in definition of macro 'max' typeof(y) _max2 = (y); \ ^ mm/cma.c:270:29: note: in expansion of macro 'max' (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order)); ^ include/linux/kernel.h:748:17: warning: comparison of distinct pointer types lacks a cast (void) (&_max1 == &_max2); \ ^ include/linux/kernel.h:747:21: note: in definition of macro 'max' typeof(y) _max2 = (y); \ ^ mm/cma.c:270:29: note: in expansion of macro 'max' (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order)); ^ Signed-off-by: Stephen Rothwell --- mm/cma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) These warnings have been irking me for some time now ... applies to Linus' tree and linux-next (and so to the mmotm tree). diff --git a/mm/cma.c b/mm/cma.c index ea506eb18cd6..fa823dc2ff15 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -183,7 +183,7 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size, return -EINVAL; /* ensure minimal alignment required by mm core */ - alignment = PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order); + alignment = PAGE_SIZE << max_t(unsigned long, MAX_ORDER - 1, pageblock_order); /* alignment should be aligned with order_per_bit */ if (!IS_ALIGNED(alignment >> PAGE_SHIFT, 1 << order_per_bit)) @@ -267,7 +267,7 @@ int __init cma_declare_contiguous(phys_addr_t base, * you couldn't get a contiguous memory, which is not what we want. */ alignment = max(alignment, - (phys_addr_t)PAGE_SIZE << max(MAX_ORDER - 1, pageblock_order)); + (phys_addr_t)PAGE_SIZE << max_t(unsigned long, MAX_ORDER - 1, pageblock_order)); base = ALIGN(base, alignment); size = ALIGN(size, alignment); limit &= ~(alignment - 1); -- 2.8.1 -- Cheers, Stephen Rothwell
Re: [PATCH 2/2] staging: dgnc: remove redundant null check in
2016-05-26 7:00 GMT+09:00 Luis de Bethencourt: > On 20/05/16 10:51, Daeseok Youn wrote: >> the "brd" was already checked for NULL before calling dgnc_do_remap(). >> >> Signed-off-by: Daeseok Youn >> --- >> drivers/staging/dgnc/dgnc_driver.c | 3 --- >> 1 file changed, 3 deletions(-) >> >> diff --git a/drivers/staging/dgnc/dgnc_driver.c >> b/drivers/staging/dgnc/dgnc_driver.c >> index 22257d2..1882ef5 100644 >> --- a/drivers/staging/dgnc/dgnc_driver.c >> +++ b/drivers/staging/dgnc/dgnc_driver.c >> @@ -599,9 +599,6 @@ static int dgnc_finalize_board_init(struct dgnc_board >> *brd) >> */ >> static void dgnc_do_remap(struct dgnc_board *brd) >> { >> - if (!brd || brd->magic != DGNC_BOARD_MAGIC) >> - return; >> - >> brd->re_map_membase = ioremap(brd->membase, 0x1000); >> } >> >> > > Same comment as the 1/2 patch. I sent an e-mail from the 1/2 patch. it has same reason for this patch. dgnc_do_remap() function is called twice only in dgnc_found_board() function. and also DNGC_BOARD_MAGIC was assigned into "brd->magic". So I think it doesn't need to check about DGNC_BOARD_MAGIC. thanks regards, Daeseok. > > Do you want to keep the brd->magic != DGNC_BOARD_MAGIC check? > > Thanks, > Luis
Re: [PATCH] cpufreq: stats: Make the stats code non-modular
On 26-05-16, 00:23, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki> > The modularity of cpufreq_stats is quite problematic. > > First off, the usage of policy notifiers for the initialization > and cleanup in the cpufreq_stats module is inherently racy with > respect to CPU offline/online and the initialization and cleanup > of the cpufreq driver. > > Second, fast frequency switching (used by the schedutil governor) > cannot be enabled if any transition notifiers are registered, so > if the cpufreq_stats module (that registers a transition notifier > for updating transition statistics) is loaded, the schedutil governor > cannot use fast frequency switching. > > On the other hand, allowing cpufreq_stats to be built as a module > doesn't really add much value. Arguably, there's not much reason > for that code to be modular at all. > > For the above reasons, make the cpufreq stats code non-modular, > modify the core to invoke functions provided by that code directly > and drop the notifiers from it. > > While at it, clean up Kconfig help for the CPU_FREQ_STAT and > CPU_FREQ_STAT_DETAILS options. > > Signed-off-by: Rafael J. Wysocki > --- > drivers/cpufreq/Kconfig | 13 +-- > drivers/cpufreq/cpufreq.c |4 + > drivers/cpufreq/cpufreq_stats.c | 146 > +++- > include/linux/cpufreq.h | 12 +++ > 4 files changed, 34 insertions(+), 141 deletions(-) Looks far better now :) Acked-by: Viresh Kumar -- viresh
Re: [PATCH 2/2] staging: dgnc: remove redundant null check in
2016-05-26 7:00 GMT+09:00 Luis de Bethencourt : > On 20/05/16 10:51, Daeseok Youn wrote: >> the "brd" was already checked for NULL before calling dgnc_do_remap(). >> >> Signed-off-by: Daeseok Youn >> --- >> drivers/staging/dgnc/dgnc_driver.c | 3 --- >> 1 file changed, 3 deletions(-) >> >> diff --git a/drivers/staging/dgnc/dgnc_driver.c >> b/drivers/staging/dgnc/dgnc_driver.c >> index 22257d2..1882ef5 100644 >> --- a/drivers/staging/dgnc/dgnc_driver.c >> +++ b/drivers/staging/dgnc/dgnc_driver.c >> @@ -599,9 +599,6 @@ static int dgnc_finalize_board_init(struct dgnc_board >> *brd) >> */ >> static void dgnc_do_remap(struct dgnc_board *brd) >> { >> - if (!brd || brd->magic != DGNC_BOARD_MAGIC) >> - return; >> - >> brd->re_map_membase = ioremap(brd->membase, 0x1000); >> } >> >> > > Same comment as the 1/2 patch. I sent an e-mail from the 1/2 patch. it has same reason for this patch. dgnc_do_remap() function is called twice only in dgnc_found_board() function. and also DNGC_BOARD_MAGIC was assigned into "brd->magic". So I think it doesn't need to check about DGNC_BOARD_MAGIC. thanks regards, Daeseok. > > Do you want to keep the brd->magic != DGNC_BOARD_MAGIC check? > > Thanks, > Luis
Re: [PATCH] cpufreq: stats: Make the stats code non-modular
On 26-05-16, 00:23, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki > > The modularity of cpufreq_stats is quite problematic. > > First off, the usage of policy notifiers for the initialization > and cleanup in the cpufreq_stats module is inherently racy with > respect to CPU offline/online and the initialization and cleanup > of the cpufreq driver. > > Second, fast frequency switching (used by the schedutil governor) > cannot be enabled if any transition notifiers are registered, so > if the cpufreq_stats module (that registers a transition notifier > for updating transition statistics) is loaded, the schedutil governor > cannot use fast frequency switching. > > On the other hand, allowing cpufreq_stats to be built as a module > doesn't really add much value. Arguably, there's not much reason > for that code to be modular at all. > > For the above reasons, make the cpufreq stats code non-modular, > modify the core to invoke functions provided by that code directly > and drop the notifiers from it. > > While at it, clean up Kconfig help for the CPU_FREQ_STAT and > CPU_FREQ_STAT_DETAILS options. > > Signed-off-by: Rafael J. Wysocki > --- > drivers/cpufreq/Kconfig | 13 +-- > drivers/cpufreq/cpufreq.c |4 + > drivers/cpufreq/cpufreq_stats.c | 146 > +++- > include/linux/cpufreq.h | 12 +++ > 4 files changed, 34 insertions(+), 141 deletions(-) Looks far better now :) Acked-by: Viresh Kumar -- viresh
[PATCH] dwc3: gadget: Introduce dwc3_endpoint_xfer_xxx() to check endpoint type
When handling the endpoint interrupt handler, it maybe disable the endpoint from another core user to set the USB endpoint descriptor pointor to be NULL while issuing usb_gadget_giveback_request() function to release lock. So it will be one bug to check the endpoint type by usb_endpoint_xfer_xxx() APIs with one NULL USB endpoint descriptor. Thus this patch introduces safety dwc3_endpoint_xfer_xxx() APIs to check endpoint type with checking if the endpoint flag 'DWC3_EP_ENABLED' is set or not. [ 4007.812527] c1 init(1) call enable_store(0) [ 4007.812633] c0 dwc3 2050.dwc3: ep1out disabled while handling ep event [ 4007.812657] c0 Unable to handle kernel NULL pointer dereference at virtual address 0003 [ 4007.812669] c0 pgd = ffc0260a8000 [ 4007.812681] c0 [0003] *pgd=b4ab4003, *pud=b4ab4003, *pmd= [ 4007.812709] c0 Internal error: Oops: 9606 [#1] PREEMPT SMP [ 4007.818441] c0 Modules linked in: bcmdhd [ 4007.821854] c3 warning saudio_recv cache is empty! [ 4007.821860] c3 aud_recv_cmd ENODATA [ 4007.821869] c3 aud_send_cmd in,cmd =11 id:10 ret-value:0 [ 4007.821876] c3 saudio_send: dst=1, channel=0, timeout=-1 [ 4007.840767] c0 mali_kbase(O) [ 4007.843707] c0 [ 4007.843889] c0 CPU: 0 PID: 8126 Comm: adbd Tainted: GW O 3.18.12+ #1 [ 4007.851153] c0 Hardware name: Spreadtrum SP9860g Board (DT) [ 4007.856693] c0 task: ffc02638a400 ti: ffc026148000 task.ti: ffc026148000 [ 4007.864404] c0 PC is at dwc3_interrupt_bh+0x710/0x112c [ 4007.869503] c0 LR is at dwc3_interrupt_bh+0x70c/0x112c [ 4007.874604] c0 pc : [] lr : [] pstate: 21c5 [ 4007.882218] c0 sp : ffc02614b970 [ 4007.885766] c0 x29: ffc02614b970 x28: ffc000c75f90 [ 4007.891044] c0 x27: 0008 x26: [ 4007.896323] c0 x25: x24: 030c [ 4007.901602] c0 x23: ffc000ff1000 x22: 0004 [ 4007.906881] c0 x21: ffc03d9fb5d8 x20: ffc13e573600 [ 4007.912160] c0 x19: ffc13e133020 x18: 0007 [ 4007.917437] c0 x17: 000e x16: 0001 [ 4007.922717] c0 x15: 0007 x14: 0fff [ 4007.927996] c0 x13: 0001 x12: 0101010101010101 [ 4007.933274] c0 x11: 000c4f5d x10: 0002 [ 4007.938553] c0 x9 : x8 : 000c4f5e [ 4007.943833] c0 x7 : 696c646e61682065 x6 : ffc000fa6cdc [ 4007.949111] c0 x5 : x4 : 0105 [ 4007.954390] c0 x3 : x2 : [ 4007.959669] c0 x1 : 5533250a x0 : .. [ 4009.150699] c0 Call trace: [ 4009.153394] c0 [] dwc3_interrupt_bh+0x710/0x112c [ 4009.159532] c0 [] tasklet_action+0xb0/0x188 [ 4009.165243] c0 [] __do_softirq+0x114/0x3b4 [ 4009.170867] c0 [] irq_exit+0xa8/0xdc [ 4009.175975] c0 [] __handle_domain_irq+0x90/0xf8 [ 4009.182030] c0 [] gic_handle_irq+0x58/0x1b4 [ 4009.187739] c0 Exception stack(0xffc02614bb70 to 0xffc02614bc90) [ 4009.194404] c0 bb60: 0140 3e133108 ffc1 [ 4009.202802] c0 bb80: 2614bcd0 ffc0 009cff0c ffc0 8145 0018 [ 4009.211194] c0 bba0: 0400 00459900 ffc0 00d1aa50 ffc0 [ 4009.219589] c0 bbc0: 2614bc00 ffc0 26148000 ffc0 0001 3d2ce4e0 ffc1 [ 4009.227984] c0 bbe0: bdc0 0001 2638a980 ffc0 2614ba40 ffc0 [ 4009.236379] c0 bc00: 0400 0001 1d37bbb0 ffc0 0013 [ 4009.244772] c0 bc20: 000e 0007 0001 000e [ 4009.253167] c0 bc40: 0007 0140 3e133108 ffc1 3e133108 ffc1 [ 4009.261560] c0 bc60: 0140 3eb833c0 ffc1 0018 0400 [ 4009.269951] c0 bc80: 1eb29b80 ffc1 3acd7c00 ffc0 [ 4009.275233] c0 [] el1_irq+0x68/0xdc [ 4009.280255] c0 [] dwc3_gadget_ep_dequeue+0x180/0x1b8 [ 4009.286741] c0 [] ffs_epfile_io+0x330/0x374 [ 4009.292453] c0 [] ffs_epfile_read+0x30/0x40 [ 4009.298169] c0 [] vfs_read+0xa0/0x1dc [ 4009.303357] c0 [] SyS_read+0x50/0xb0 Signed-off-by: Baolin Wang--- drivers/usb/dwc3/gadget.c | 95 ++--- 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8e4a1b1..5d095f2 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -36,6 +36,56 @@ #include "io.h" /** +* dwc3_endpoint_xfer_bulk - check if the endpoint has bulk transfer type +* @ep: endpoint to be checked +* +* Returns true if the endpoint is of type bulk, otherwise it returns false. +*/ +static inline int dwc3_endpoint_xfer_bulk(struct dwc3_ep *ep) +{ + return ((ep->flags & DWC3_EP_ENABLED) && + ep->type == USB_ENDPOINT_XFER_BULK); +} + +/** +* dwc3_endpoint_xfer_control
[PATCH] dwc3: gadget: Introduce dwc3_endpoint_xfer_xxx() to check endpoint type
When handling the endpoint interrupt handler, it maybe disable the endpoint from another core user to set the USB endpoint descriptor pointor to be NULL while issuing usb_gadget_giveback_request() function to release lock. So it will be one bug to check the endpoint type by usb_endpoint_xfer_xxx() APIs with one NULL USB endpoint descriptor. Thus this patch introduces safety dwc3_endpoint_xfer_xxx() APIs to check endpoint type with checking if the endpoint flag 'DWC3_EP_ENABLED' is set or not. [ 4007.812527] c1 init(1) call enable_store(0) [ 4007.812633] c0 dwc3 2050.dwc3: ep1out disabled while handling ep event [ 4007.812657] c0 Unable to handle kernel NULL pointer dereference at virtual address 0003 [ 4007.812669] c0 pgd = ffc0260a8000 [ 4007.812681] c0 [0003] *pgd=b4ab4003, *pud=b4ab4003, *pmd= [ 4007.812709] c0 Internal error: Oops: 9606 [#1] PREEMPT SMP [ 4007.818441] c0 Modules linked in: bcmdhd [ 4007.821854] c3 warning saudio_recv cache is empty! [ 4007.821860] c3 aud_recv_cmd ENODATA [ 4007.821869] c3 aud_send_cmd in,cmd =11 id:10 ret-value:0 [ 4007.821876] c3 saudio_send: dst=1, channel=0, timeout=-1 [ 4007.840767] c0 mali_kbase(O) [ 4007.843707] c0 [ 4007.843889] c0 CPU: 0 PID: 8126 Comm: adbd Tainted: GW O 3.18.12+ #1 [ 4007.851153] c0 Hardware name: Spreadtrum SP9860g Board (DT) [ 4007.856693] c0 task: ffc02638a400 ti: ffc026148000 task.ti: ffc026148000 [ 4007.864404] c0 PC is at dwc3_interrupt_bh+0x710/0x112c [ 4007.869503] c0 LR is at dwc3_interrupt_bh+0x70c/0x112c [ 4007.874604] c0 pc : [] lr : [] pstate: 21c5 [ 4007.882218] c0 sp : ffc02614b970 [ 4007.885766] c0 x29: ffc02614b970 x28: ffc000c75f90 [ 4007.891044] c0 x27: 0008 x26: [ 4007.896323] c0 x25: x24: 030c [ 4007.901602] c0 x23: ffc000ff1000 x22: 0004 [ 4007.906881] c0 x21: ffc03d9fb5d8 x20: ffc13e573600 [ 4007.912160] c0 x19: ffc13e133020 x18: 0007 [ 4007.917437] c0 x17: 000e x16: 0001 [ 4007.922717] c0 x15: 0007 x14: 0fff [ 4007.927996] c0 x13: 0001 x12: 0101010101010101 [ 4007.933274] c0 x11: 000c4f5d x10: 0002 [ 4007.938553] c0 x9 : x8 : 000c4f5e [ 4007.943833] c0 x7 : 696c646e61682065 x6 : ffc000fa6cdc [ 4007.949111] c0 x5 : x4 : 0105 [ 4007.954390] c0 x3 : x2 : [ 4007.959669] c0 x1 : 5533250a x0 : .. [ 4009.150699] c0 Call trace: [ 4009.153394] c0 [] dwc3_interrupt_bh+0x710/0x112c [ 4009.159532] c0 [] tasklet_action+0xb0/0x188 [ 4009.165243] c0 [] __do_softirq+0x114/0x3b4 [ 4009.170867] c0 [] irq_exit+0xa8/0xdc [ 4009.175975] c0 [] __handle_domain_irq+0x90/0xf8 [ 4009.182030] c0 [] gic_handle_irq+0x58/0x1b4 [ 4009.187739] c0 Exception stack(0xffc02614bb70 to 0xffc02614bc90) [ 4009.194404] c0 bb60: 0140 3e133108 ffc1 [ 4009.202802] c0 bb80: 2614bcd0 ffc0 009cff0c ffc0 8145 0018 [ 4009.211194] c0 bba0: 0400 00459900 ffc0 00d1aa50 ffc0 [ 4009.219589] c0 bbc0: 2614bc00 ffc0 26148000 ffc0 0001 3d2ce4e0 ffc1 [ 4009.227984] c0 bbe0: bdc0 0001 2638a980 ffc0 2614ba40 ffc0 [ 4009.236379] c0 bc00: 0400 0001 1d37bbb0 ffc0 0013 [ 4009.244772] c0 bc20: 000e 0007 0001 000e [ 4009.253167] c0 bc40: 0007 0140 3e133108 ffc1 3e133108 ffc1 [ 4009.261560] c0 bc60: 0140 3eb833c0 ffc1 0018 0400 [ 4009.269951] c0 bc80: 1eb29b80 ffc1 3acd7c00 ffc0 [ 4009.275233] c0 [] el1_irq+0x68/0xdc [ 4009.280255] c0 [] dwc3_gadget_ep_dequeue+0x180/0x1b8 [ 4009.286741] c0 [] ffs_epfile_io+0x330/0x374 [ 4009.292453] c0 [] ffs_epfile_read+0x30/0x40 [ 4009.298169] c0 [] vfs_read+0xa0/0x1dc [ 4009.303357] c0 [] SyS_read+0x50/0xb0 Signed-off-by: Baolin Wang --- drivers/usb/dwc3/gadget.c | 95 ++--- 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8e4a1b1..5d095f2 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -36,6 +36,56 @@ #include "io.h" /** +* dwc3_endpoint_xfer_bulk - check if the endpoint has bulk transfer type +* @ep: endpoint to be checked +* +* Returns true if the endpoint is of type bulk, otherwise it returns false. +*/ +static inline int dwc3_endpoint_xfer_bulk(struct dwc3_ep *ep) +{ + return ((ep->flags & DWC3_EP_ENABLED) && + ep->type == USB_ENDPOINT_XFER_BULK); +} + +/** +* dwc3_endpoint_xfer_control - check if the endpoint
Re: [PATCH 1/2] staging: dgnc: remove redundant NULL check for brd
2016-05-26 6:48 GMT+09:00 Luis de Bethencourt: > On 20/05/16 10:51, Daeseok Youn wrote: >> the "brd" value cannot be NULL in dgnc_finalize_board_init(). >> Because "brd" as a parameter of this function was already >> checked for NULL. >> >> Signed-off-by: Daeseok Youn >> --- >> drivers/staging/dgnc/dgnc_driver.c | 3 --- >> 1 file changed, 3 deletions(-) >> >> diff --git a/drivers/staging/dgnc/dgnc_driver.c >> b/drivers/staging/dgnc/dgnc_driver.c >> index af2e835..22257d2 100644 >> --- a/drivers/staging/dgnc/dgnc_driver.c >> +++ b/drivers/staging/dgnc/dgnc_driver.c >> @@ -579,9 +579,6 @@ static int dgnc_finalize_board_init(struct dgnc_board >> *brd) >> { >> int rc = 0; >> >> - if (!brd || brd->magic != DGNC_BOARD_MAGIC) >> - return -ENODEV; >> - >> if (brd->irq) { >> rc = request_irq(brd->irq, brd->bd_ops->intr, >>IRQF_SHARED, "DGNC", brd); >> > > This is partially correct, the check for brd being NULL is in line 371. Hi Luis, Yes, right. but also brd was assigned the value DGNC_BOARD_MAGIC in line 384. brd->magic = DGNC_BOARD_MAGIC; and also dgnc_finalize_board_init() as a static function is only called in dgnc_found_board(), right? > > But there is a second check for brd->magic != DGNC_BOARD_MAGIC. Do you want > to keep that one? So.. I think it doesn't need to check about DGNC_BOARD_MAGIC. > > Also, how did you find this patch. It is useful to mention this in the commit > message if it was through some static analysis tool. For people using these > tools > in the future. There are some static analysis tool for checking linux kernel code. But I didn't use those tools for this patch. sometimes, I usually run "smatch" tool for checking linux kernel code. thanks. regards, Daeseok. > > Thanks for the patch :) > Luis
Re: [PATCH 1/2] staging: dgnc: remove redundant NULL check for brd
2016-05-26 6:48 GMT+09:00 Luis de Bethencourt : > On 20/05/16 10:51, Daeseok Youn wrote: >> the "brd" value cannot be NULL in dgnc_finalize_board_init(). >> Because "brd" as a parameter of this function was already >> checked for NULL. >> >> Signed-off-by: Daeseok Youn >> --- >> drivers/staging/dgnc/dgnc_driver.c | 3 --- >> 1 file changed, 3 deletions(-) >> >> diff --git a/drivers/staging/dgnc/dgnc_driver.c >> b/drivers/staging/dgnc/dgnc_driver.c >> index af2e835..22257d2 100644 >> --- a/drivers/staging/dgnc/dgnc_driver.c >> +++ b/drivers/staging/dgnc/dgnc_driver.c >> @@ -579,9 +579,6 @@ static int dgnc_finalize_board_init(struct dgnc_board >> *brd) >> { >> int rc = 0; >> >> - if (!brd || brd->magic != DGNC_BOARD_MAGIC) >> - return -ENODEV; >> - >> if (brd->irq) { >> rc = request_irq(brd->irq, brd->bd_ops->intr, >>IRQF_SHARED, "DGNC", brd); >> > > This is partially correct, the check for brd being NULL is in line 371. Hi Luis, Yes, right. but also brd was assigned the value DGNC_BOARD_MAGIC in line 384. brd->magic = DGNC_BOARD_MAGIC; and also dgnc_finalize_board_init() as a static function is only called in dgnc_found_board(), right? > > But there is a second check for brd->magic != DGNC_BOARD_MAGIC. Do you want > to keep that one? So.. I think it doesn't need to check about DGNC_BOARD_MAGIC. > > Also, how did you find this patch. It is useful to mention this in the commit > message if it was through some static analysis tool. For people using these > tools > in the future. There are some static analysis tool for checking linux kernel code. But I didn't use those tools for this patch. sometimes, I usually run "smatch" tool for checking linux kernel code. thanks. regards, Daeseok. > > Thanks for the patch :) > Luis
Re: [PATCH] soc: qcom: provide mechanism for drivers to access L2 registers
On Tue 24 May 12:54 PDT 2016, Neil Leeder wrote: > > > On 5/24/2016 07:23 AM, Mark Rutland wrote: > > On Mon, May 23, 2016 at 02:22:59PM -0400, Neil Leeder wrote: > >> > >> On 5/23/2016 01:25 PM, Mark Rutland wrote: > >>> On Fri, May 20, 2016 at 03:13:07PM -0400, Neil Leeder wrote: > > Signed-off-by: Neil Leeder> --- > drivers/soc/qcom/Kconfig | 9 + > drivers/soc/qcom/Makefile | 1 + > drivers/soc/qcom/l2-accessors.c | 66 > +++ > include/linux/soc/qcom/l2-accessors.h | 27 ++ > 4 files changed, 103 insertions(+) > create mode 100644 drivers/soc/qcom/l2-accessors.c > create mode 100644 include/linux/soc/qcom/l2-accessors.h > >>> > >>> These are awfully generic file names (and function names). Which SoCs > >>> does this apply to? > >>> > >>> It would be good to give these more specific names. > >> > >> It's under soc/qcom, and dependent on ARCH_QCOM and (in v2) also on ARM64. > >> It applies to all QCOM ARM64 SoCs. > > > > Per Christopher's comment, it sounds like this applies to QDF24xx. > > > > Given that the code uses IMPLEMENTATION DEFINED system registers, I > > presume that this does not apply to MSM8916 which uses Cortex-A53, for > > example (though perhaps it does, and I am mistaken). > > > >> Given that it can only be used in a QCOM driver, and the include path has > >> qcom in it, I'd > >> prefer not to add redundancy by adding another qcom in there. > > > > I'm not asking for another "qcom", but simply the SoC variant or family > > (e.g. "qdf24xx" would be fine). > > > > It applies to all ARMv8 SoCs with QCOM processors in them. So QDF24xx > and mobile 820, but not SoCs with ARM processors in them such as > MSM8916. So neither msm_ nor qdf_ are accurate prefixes. What's the code name for the SoC in QDF24xx? The 820 is Kryo, is it the same core in QDF24xx or does that have some other name. We should try to pick something adding value, not adding another generic thing. > As Timur pointed out, the majority of source files in drivers/soc/qcom > don't have any prefix, which is a reason why I didn't include one. > There's no reason to add a generic "qcom" to the qcom folder, if anything we should drop the "qcom" prefix of the only one in there. Regards, Bjorn
Re: [PATCH] soc: qcom: provide mechanism for drivers to access L2 registers
On Tue 24 May 12:54 PDT 2016, Neil Leeder wrote: > > > On 5/24/2016 07:23 AM, Mark Rutland wrote: > > On Mon, May 23, 2016 at 02:22:59PM -0400, Neil Leeder wrote: > >> > >> On 5/23/2016 01:25 PM, Mark Rutland wrote: > >>> On Fri, May 20, 2016 at 03:13:07PM -0400, Neil Leeder wrote: > > Signed-off-by: Neil Leeder > --- > drivers/soc/qcom/Kconfig | 9 + > drivers/soc/qcom/Makefile | 1 + > drivers/soc/qcom/l2-accessors.c | 66 > +++ > include/linux/soc/qcom/l2-accessors.h | 27 ++ > 4 files changed, 103 insertions(+) > create mode 100644 drivers/soc/qcom/l2-accessors.c > create mode 100644 include/linux/soc/qcom/l2-accessors.h > >>> > >>> These are awfully generic file names (and function names). Which SoCs > >>> does this apply to? > >>> > >>> It would be good to give these more specific names. > >> > >> It's under soc/qcom, and dependent on ARCH_QCOM and (in v2) also on ARM64. > >> It applies to all QCOM ARM64 SoCs. > > > > Per Christopher's comment, it sounds like this applies to QDF24xx. > > > > Given that the code uses IMPLEMENTATION DEFINED system registers, I > > presume that this does not apply to MSM8916 which uses Cortex-A53, for > > example (though perhaps it does, and I am mistaken). > > > >> Given that it can only be used in a QCOM driver, and the include path has > >> qcom in it, I'd > >> prefer not to add redundancy by adding another qcom in there. > > > > I'm not asking for another "qcom", but simply the SoC variant or family > > (e.g. "qdf24xx" would be fine). > > > > It applies to all ARMv8 SoCs with QCOM processors in them. So QDF24xx > and mobile 820, but not SoCs with ARM processors in them such as > MSM8916. So neither msm_ nor qdf_ are accurate prefixes. What's the code name for the SoC in QDF24xx? The 820 is Kryo, is it the same core in QDF24xx or does that have some other name. We should try to pick something adding value, not adding another generic thing. > As Timur pointed out, the majority of source files in drivers/soc/qcom > don't have any prefix, which is a reason why I didn't include one. > There's no reason to add a generic "qcom" to the qcom folder, if anything we should drop the "qcom" prefix of the only one in there. Regards, Bjorn
Re: [PATCH v6 11/12] zsmalloc: page migration support
On Thu, May 26, 2016 at 09:59:26AM +0900, Sergey Senozhatsky wrote: > btw, I've uploaded zram-fio test script to > https://github.com/sergey-senozhatsky/zram-perf-test > > it's very minimalistic and half baked, but can be used > to some degree. open to patches, improvements, etc. Awesome! Let's enhance it as zram benchmark tool. Maybe I will help something. :) Thanks.
Re: [PATCH v6 11/12] zsmalloc: page migration support
On Thu, May 26, 2016 at 09:59:26AM +0900, Sergey Senozhatsky wrote: > btw, I've uploaded zram-fio test script to > https://github.com/sergey-senozhatsky/zram-perf-test > > it's very minimalistic and half baked, but can be used > to some degree. open to patches, improvements, etc. Awesome! Let's enhance it as zram benchmark tool. Maybe I will help something. :) Thanks.
Re: [PATCH] f2fs: Return the errno to the caller to avoid using a wrong page
Forget this wrong version, I have re-sent a patch v2 version. -- Thanks, Yunlong Song
Re: [PATCH] f2fs: Return the errno to the caller to avoid using a wrong page
Forget this wrong version, I have re-sent a patch v2 version. -- Thanks, Yunlong Song
[PATCH v2] f2fs: Return the errno to the caller to avoid using a wrong page
Commit aaf9607516ed38825268515ef4d773289a44f429 ("f2fs: check node page contents all the time") pointed out that "sometimes it was reported that its contents was missing", so it checks the page's mapping and contents. When "nid != nid_of_node(page)", ERR_PTR(-EIO) will be returned to the caller. However, commit e1c51b9f1df2f9efc2ec11488717e40cd12015f9 ("f2fs: clean up node page updating flow") moves "nid != nid_of_node(page)" test to "f2fs_bug_on(sbi, nid != nid_of_node(page))", this will return a wrong page to the caller when F2FS_CHECK_FS is off when "sometimes it was reported that its contents was missing" happens. This patch restores to check node page contents all the time, and returns the errno to make the caller known something is wrong and avoid to use the page. This patch also moves f2fs_bug_on to its proper location. Signed-off-by: Yunlong Song--- fs/f2fs/node.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 1f21aae..eee56aa 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1149,16 +1149,21 @@ repeat: lock_page(page); - if (unlikely(!PageUptodate(page))) { - f2fs_put_page(page, 1); - return ERR_PTR(-EIO); - } + if (unlikely(!PageUptodate(page))) + goto out_err; + if (unlikely(page->mapping != NODE_MAPPING(sbi))) { f2fs_put_page(page, 1); goto repeat; } page_hit: - f2fs_bug_on(sbi, nid != nid_of_node(page)); + if(nid != nid_of_node(page)) { + f2fs_bug_on(sbi, 1); + ClearPageUptodate(page); +out_err: + f2fs_put_page(page, 1); + return ERR_PTR(-EIO); + } return page; } -- 1.8.5.2
[PATCH v2] f2fs: Return the errno to the caller to avoid using a wrong page
Commit aaf9607516ed38825268515ef4d773289a44f429 ("f2fs: check node page contents all the time") pointed out that "sometimes it was reported that its contents was missing", so it checks the page's mapping and contents. When "nid != nid_of_node(page)", ERR_PTR(-EIO) will be returned to the caller. However, commit e1c51b9f1df2f9efc2ec11488717e40cd12015f9 ("f2fs: clean up node page updating flow") moves "nid != nid_of_node(page)" test to "f2fs_bug_on(sbi, nid != nid_of_node(page))", this will return a wrong page to the caller when F2FS_CHECK_FS is off when "sometimes it was reported that its contents was missing" happens. This patch restores to check node page contents all the time, and returns the errno to make the caller known something is wrong and avoid to use the page. This patch also moves f2fs_bug_on to its proper location. Signed-off-by: Yunlong Song --- fs/f2fs/node.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 1f21aae..eee56aa 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1149,16 +1149,21 @@ repeat: lock_page(page); - if (unlikely(!PageUptodate(page))) { - f2fs_put_page(page, 1); - return ERR_PTR(-EIO); - } + if (unlikely(!PageUptodate(page))) + goto out_err; + if (unlikely(page->mapping != NODE_MAPPING(sbi))) { f2fs_put_page(page, 1); goto repeat; } page_hit: - f2fs_bug_on(sbi, nid != nid_of_node(page)); + if(nid != nid_of_node(page)) { + f2fs_bug_on(sbi, 1); + ClearPageUptodate(page); +out_err: + f2fs_put_page(page, 1); + return ERR_PTR(-EIO); + } return page; } -- 1.8.5.2
[PATCH] f2fs: Return the errno to the caller to avoid using a wrong page
Commit aaf9607516ed38825268515ef4d773289a44f429 ("f2fs: check node page contents all the time") pointed out that "sometimes it was reported that its contents was missing", so it checks the page's mapping and contents. When "nid != nid_of_node(page)", ERR_PTR(-EIO) will be returned to the caller. However, commit e1c51b9f1df2f9efc2ec11488717e40cd12015f9 ("f2fs: clean up node page updating flow") moves "nid != nid_of_node(page)" test to "f2fs_bug_on(sbi, nid != nid_of_node(page))", this will return a wrong page to the caller when F2FS_CHECK_FS is off when "sometimes it was reported that its contents was missing" happens. This patch restores to check node page contents all the time, and returns the errno to make the caller known something is wrong and avoid to use the page. This patch also moves f2fs_bug_on to its proper location. Signed-off-by: Yunlong Song--- fs/f2fs/node.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 1f21aae..eee56aa 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1149,16 +1149,21 @@ repeat: lock_page(page); - if (unlikely(!PageUptodate(page))) { - f2fs_put_page(page, 1); - return ERR_PTR(-EIO); - } + if (unlikely(!PageUptodate(page))) + goto out_err; + if (unlikely(page->mapping != NODE_MAPPING(sbi))) { f2fs_put_page(page, 1); goto repeat; } page_hit: - f2fs_bug_on(sbi, nid != nid_of_node(page)); + if(nid != nid_of_node(page)) { + f2fs_bug_on(sbi, 1); + ClearPageUptodate(page); +out_err: + f2fs_put_page(page, 1); + return ERR_PTR(-EIO); + } return page; } -- 1.8.5.2
[PATCH] f2fs: Return the errno to the caller to avoid using a wrong page
Commit aaf9607516ed38825268515ef4d773289a44f429 ("f2fs: check node page contents all the time") pointed out that "sometimes it was reported that its contents was missing", so it checks the page's mapping and contents. When "nid != nid_of_node(page)", ERR_PTR(-EIO) will be returned to the caller. However, commit e1c51b9f1df2f9efc2ec11488717e40cd12015f9 ("f2fs: clean up node page updating flow") moves "nid != nid_of_node(page)" test to "f2fs_bug_on(sbi, nid != nid_of_node(page))", this will return a wrong page to the caller when F2FS_CHECK_FS is off when "sometimes it was reported that its contents was missing" happens. This patch restores to check node page contents all the time, and returns the errno to make the caller known something is wrong and avoid to use the page. This patch also moves f2fs_bug_on to its proper location. Signed-off-by: Yunlong Song --- fs/f2fs/node.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 1f21aae..eee56aa 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -1149,16 +1149,21 @@ repeat: lock_page(page); - if (unlikely(!PageUptodate(page))) { - f2fs_put_page(page, 1); - return ERR_PTR(-EIO); - } + if (unlikely(!PageUptodate(page))) + goto out_err; + if (unlikely(page->mapping != NODE_MAPPING(sbi))) { f2fs_put_page(page, 1); goto repeat; } page_hit: - f2fs_bug_on(sbi, nid != nid_of_node(page)); + if(nid != nid_of_node(page)) { + f2fs_bug_on(sbi, 1); + ClearPageUptodate(page); +out_err: + f2fs_put_page(page, 1); + return ERR_PTR(-EIO); + } return page; } -- 1.8.5.2
linux-next: Tree for May 26
Hi all, Please do not add any v4.8 destined material to your linux-next included branches until after v4.7-rc1 has been released. Changes since 20160525: Non-merge commits (relative to Linus' tree): 1019 884 files changed, 34784 insertions(+), 11132 deletions(-) I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" and checkout or reset to the new master. You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc and an allmodconfig (with CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a native build of tools/perf. After the final fixups (if any), I do an x86_64 modules_install followed by builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig (this fails its final link) and pseries_le_defconfig and i386, sparc and sparc64 defconfig. Below is a summary of the state of the merge. I am currently merging 236 trees (counting Linus' and 35 trees of patches pending for Linus' tree). Stats about the size of the tree over time can be seen at http://neuling.org/linux-next-size.html . Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. -- Cheers, Stephen Rothwell $ git checkout master $ git reset --hard stable Merging origin/master (0985b65d3ba2 Merge branch 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs) Merging fixes/master (b507146bb6b9 Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6) Merging kbuild-current/rc-fixes (3d1450d54a4f Makefile: Force gzip and xz on module install) Merging arc-current/for-curr (44549e8f5eea Linux 4.6-rc7) Merging arm-current/fixes (ec953b70f368 ARM: 8573/1: domain: move {set,get}_domain under config guard) Merging m68k-current/for-linus (9a6462763b17 m68k/mvme16x: Include generic ) Merging metag-fixes/fixes (0164a711c97b metag: Fix ioremap_wc/ioremap_cached build errors) Merging powerpc-fixes/fixes (b4c112114aab powerpc: Fix bad inline asm constraint in create_zero_mask()) Merging powerpc-merge-mpe/fixes (bc0195aad0da Linux 4.2-rc2) Merging sparc/master (9ea46abe2255 sparc64: Take ctx_alloc_lock properly in hugetlb_setup().) Merging net/master (f6988cb63a4e team: don't call netdev_change_features under team->lock) Merging ipsec/master (d6af1a31cc72 vti: Add pmtu handling to vti_xmit.) Merging ipvs/master (f28f20da704d Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net) Merging wireless-drivers/master (cbbba30f1ac9 Merge tag 'iwlwifi-for-kalle-2016-05-04' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes) Merging mac80211/master (e6436be21e77 mac80211: fix statistics leak if dev_alloc_name() fails) Merging sound-current/for-linus (86c72d1ce91d ALSA: hda - Fix headset mic detection problem for one Dell machine) Merging pci-current/for-linus (9a2a5a638f8e PCI: Do not treat EPROBE_DEFER as device attach failure) Merging driver-core.current/driver-core-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging tty.current/tty-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging usb.current/usb-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging usb-gadget-fixes/fixes (38740a5b87d5 usb: gadget: f_fs: Fix use-after-free) Merging usb-serial-fixes/usb-linus (74d2a91aec97 USB: serial: option: add even more ZTE device ids) Merging usb-chipidea-fixes/ci-for-usb-stable (d144dfea8af7 usb: chipidea: otg: change workqueue ci_otg as freezable) Merging staging.current/staging-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging char-misc.current/char-misc-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging input-current/for-linus (affa80bd97f7 Input: uinput - handle compat ioctl for UI_SET_PHYS) Merging crypto-current/master (ab6a11a7c8ef crypto: ccp - Fix AES XTS error for request sizes above 4096) Merging ide/master (1993b176a822 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide) Merging devicetree-current/devicetree/merge (f76502aa9140 of/dynamic: Fix test for PPC_PSERIES) Merging rr-fixes/fixes (8244062ef1e5 modules: fix longstanding /proc/kallsyms vs module insertion ra
linux-next: Tree for May 26
Hi all, Please do not add any v4.8 destined material to your linux-next included branches until after v4.7-rc1 has been released. Changes since 20160525: Non-merge commits (relative to Linus' tree): 1019 884 files changed, 34784 insertions(+), 11132 deletions(-) I have created today's linux-next tree at git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git (patches at http://www.kernel.org/pub/linux/kernel/next/ ). If you are tracking the linux-next tree using git, you should not use "git pull" to do so as that will try to merge the new linux-next release with the old one. You should use "git fetch" and checkout or reset to the new master. You can see which trees have been included by looking in the Next/Trees file in the source. There are also quilt-import.log and merge.log files in the Next directory. Between each merge, the tree was built with a ppc64_defconfig for powerpc and an allmodconfig (with CONFIG_BUILD_DOCSRC=n) for x86_64, a multi_v7_defconfig for arm and a native build of tools/perf. After the final fixups (if any), I do an x86_64 modules_install followed by builds for x86_64 allnoconfig, powerpc allnoconfig (32 and 64 bit), ppc44x_defconfig, allyesconfig (this fails its final link) and pseries_le_defconfig and i386, sparc and sparc64 defconfig. Below is a summary of the state of the merge. I am currently merging 236 trees (counting Linus' and 35 trees of patches pending for Linus' tree). Stats about the size of the tree over time can be seen at http://neuling.org/linux-next-size.html . Status of my local build tests will be at http://kisskb.ellerman.id.au/linux-next . If maintainers want to give advice about cross compilers/configs that work, we are always open to add more builds. Thanks to Randy Dunlap for doing many randconfig builds. And to Paul Gortmaker for triage and bug fixes. -- Cheers, Stephen Rothwell $ git checkout master $ git reset --hard stable Merging origin/master (0985b65d3ba2 Merge branch 'work.iov_iter' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs) Merging fixes/master (b507146bb6b9 Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6) Merging kbuild-current/rc-fixes (3d1450d54a4f Makefile: Force gzip and xz on module install) Merging arc-current/for-curr (44549e8f5eea Linux 4.6-rc7) Merging arm-current/fixes (ec953b70f368 ARM: 8573/1: domain: move {set,get}_domain under config guard) Merging m68k-current/for-linus (9a6462763b17 m68k/mvme16x: Include generic ) Merging metag-fixes/fixes (0164a711c97b metag: Fix ioremap_wc/ioremap_cached build errors) Merging powerpc-fixes/fixes (b4c112114aab powerpc: Fix bad inline asm constraint in create_zero_mask()) Merging powerpc-merge-mpe/fixes (bc0195aad0da Linux 4.2-rc2) Merging sparc/master (9ea46abe2255 sparc64: Take ctx_alloc_lock properly in hugetlb_setup().) Merging net/master (f6988cb63a4e team: don't call netdev_change_features under team->lock) Merging ipsec/master (d6af1a31cc72 vti: Add pmtu handling to vti_xmit.) Merging ipvs/master (f28f20da704d Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net) Merging wireless-drivers/master (cbbba30f1ac9 Merge tag 'iwlwifi-for-kalle-2016-05-04' of https://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes) Merging mac80211/master (e6436be21e77 mac80211: fix statistics leak if dev_alloc_name() fails) Merging sound-current/for-linus (86c72d1ce91d ALSA: hda - Fix headset mic detection problem for one Dell machine) Merging pci-current/for-linus (9a2a5a638f8e PCI: Do not treat EPROBE_DEFER as device attach failure) Merging driver-core.current/driver-core-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging tty.current/tty-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging usb.current/usb-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging usb-gadget-fixes/fixes (38740a5b87d5 usb: gadget: f_fs: Fix use-after-free) Merging usb-serial-fixes/usb-linus (74d2a91aec97 USB: serial: option: add even more ZTE device ids) Merging usb-chipidea-fixes/ci-for-usb-stable (d144dfea8af7 usb: chipidea: otg: change workqueue ci_otg as freezable) Merging staging.current/staging-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging char-misc.current/char-misc-linus (5469dc270cd4 Merge branch 'akpm' (patches from Andrew)) Merging input-current/for-linus (affa80bd97f7 Input: uinput - handle compat ioctl for UI_SET_PHYS) Merging crypto-current/master (ab6a11a7c8ef crypto: ccp - Fix AES XTS error for request sizes above 4096) Merging ide/master (1993b176a822 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide) Merging devicetree-current/devicetree/merge (f76502aa9140 of/dynamic: Fix test for PPC_PSERIES) Merging rr-fixes/fixes (8244062ef1e5 modules: fix longstanding /proc/kallsyms vs module insertion ra
Re: [PATCH v3 1/5] thermal: Add support for hardware-tracked trip points
On 2016年05月26日 08:34, Caesar Wang wrote: On 2016年05月26日 00:42, Javi Merino wrote: Hi Caesar, On Wed, May 25, 2016 at 11:47:45AM +0800, Caesar Wang wrote: From: Sascha HauerThis adds support for hardware-tracked trip points to the device tree thermal sensor framework. The framework supports an arbitrary number of trip points. Whenever the current temperature is updated, the trip points immediately below and above the current temperature are found. A .set_trips callback is then called with the temperatures. If there is no trip point above or below the current temperature, the passed trip temperature will be -INT_MAX or INT_MAX respectively. In this callback, the driver should program the hardware such that it is notified when either of these trip points are triggered. When a trip point is triggered, the driver should call `thermal_zone_device_update' for the respective thermal zone. This will cause the trip points to be updated again. If .set_trips is not implemented, the framework behaves as before. This patch is based on an earlier version from Mikko Perttunen Signed-off-by: Sascha Hauer Signed-off-by: Caesar Wang Cc: Zhang Rui Cc: Eduardo Valentin Cc: linux...@vger.kernel.org --- Changes in v3: - as Javi comments on https://patchwork.kernel.org/patch/9001281/. - add the lock for preventing the called from multi placce - add the note for pre_low/high_trip. Changes in v2: - update the sysfs-api.txt for set_trips. Documentation/thermal/sysfs-api.txt | 7 + drivers/thermal/thermal_core.c | 52 + include/linux/thermal.h | 7 + 3 files changed, 66 insertions(+) diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt index efc3f3d..75d8838 100644 --- a/Documentation/thermal/sysfs-api.txt +++ b/Documentation/thermal/sysfs-api.txt @@ -49,6 +49,9 @@ temperature) and throttle appropriate devices. .bind: bind the thermal zone device with a thermal cooling device. .unbind: unbind the thermal zone device with a thermal cooling device. .get_temp: get the current temperature of the thermal zone. +.set_trips: set the trip points window. Whenever the current temperature +is updated, the trip points immediately below and above the +current temperature are found. .get_mode: get the current mode (enabled/disabled) of the thermal zone. - "enabled" means the kernel thermal management is enabled. - "disabled" will prevent kernel thermal driver action upon trip points @@ -95,6 +98,10 @@ temperature) and throttle appropriate devices. get_temp:a pointer to a function that reads the sensor temperature. This is mandatory callback provided by sensor driver. +set_trips: a pointer to a function that sets a +temperature window. When this window is +left the driver must inform the thermal +core via thermal_zone_device_update. get_trend: a pointer to a function that reads the sensor temperature trend. set_emul_temp:a pointer to a function that sets diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 5133cd1..e5bfbd3 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -520,6 +520,51 @@ exit: } EXPORT_SYMBOL_GPL(thermal_zone_get_temp); +static void thermal_zone_set_trips(struct thermal_zone_device *tz) +{ +int low = -INT_MAX; +int high = INT_MAX; +int trip_temp, hysteresis; +int temp = tz->temperature; +int i, ret; + +if (!tz->ops->set_trips) +return; + +for (i = 0; i < tz->trips; i++) { +int trip_low; + +tz->ops->get_trip_temp(tz, i, _temp); +tz->ops->get_trip_hyst(tz, i, ); + +trip_low = trip_temp - hysteresis; + +if (trip_low < temp && trip_low > low) +low = trip_low; + +if (trip_temp > temp && trip_temp < high) +high = trip_temp; +} + +/* No need to change trip points */ +if (tz->prev_low_trip == low && tz->prev_high_trip == high) +return; + +tz->prev_low_trip = low; +tz->prev_high_trip = high; + +dev_dbg(>device, "new temperature boundaries: %d < x < %d\n", +low, high); + +/* + * Set a temperature window. When this window is left the driver + * must inform the thermal core via thermal_zone_device_update. + */ +ret = tz->ops->set_trips(tz, low, high); +if (ret) +dev_err(>device, "Failed to set trips: %d\n", ret); In the v2 review (http://article.gmane.org/gmane.linux.documentation/38442) you agreed to add locking but you haven't done it. Maybe you sent
Re: [PATCH v3 1/5] thermal: Add support for hardware-tracked trip points
On 2016年05月26日 08:34, Caesar Wang wrote: On 2016年05月26日 00:42, Javi Merino wrote: Hi Caesar, On Wed, May 25, 2016 at 11:47:45AM +0800, Caesar Wang wrote: From: Sascha Hauer This adds support for hardware-tracked trip points to the device tree thermal sensor framework. The framework supports an arbitrary number of trip points. Whenever the current temperature is updated, the trip points immediately below and above the current temperature are found. A .set_trips callback is then called with the temperatures. If there is no trip point above or below the current temperature, the passed trip temperature will be -INT_MAX or INT_MAX respectively. In this callback, the driver should program the hardware such that it is notified when either of these trip points are triggered. When a trip point is triggered, the driver should call `thermal_zone_device_update' for the respective thermal zone. This will cause the trip points to be updated again. If .set_trips is not implemented, the framework behaves as before. This patch is based on an earlier version from Mikko Perttunen Signed-off-by: Sascha Hauer Signed-off-by: Caesar Wang Cc: Zhang Rui Cc: Eduardo Valentin Cc: linux...@vger.kernel.org --- Changes in v3: - as Javi comments on https://patchwork.kernel.org/patch/9001281/. - add the lock for preventing the called from multi placce - add the note for pre_low/high_trip. Changes in v2: - update the sysfs-api.txt for set_trips. Documentation/thermal/sysfs-api.txt | 7 + drivers/thermal/thermal_core.c | 52 + include/linux/thermal.h | 7 + 3 files changed, 66 insertions(+) diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt index efc3f3d..75d8838 100644 --- a/Documentation/thermal/sysfs-api.txt +++ b/Documentation/thermal/sysfs-api.txt @@ -49,6 +49,9 @@ temperature) and throttle appropriate devices. .bind: bind the thermal zone device with a thermal cooling device. .unbind: unbind the thermal zone device with a thermal cooling device. .get_temp: get the current temperature of the thermal zone. +.set_trips: set the trip points window. Whenever the current temperature +is updated, the trip points immediately below and above the +current temperature are found. .get_mode: get the current mode (enabled/disabled) of the thermal zone. - "enabled" means the kernel thermal management is enabled. - "disabled" will prevent kernel thermal driver action upon trip points @@ -95,6 +98,10 @@ temperature) and throttle appropriate devices. get_temp:a pointer to a function that reads the sensor temperature. This is mandatory callback provided by sensor driver. +set_trips: a pointer to a function that sets a +temperature window. When this window is +left the driver must inform the thermal +core via thermal_zone_device_update. get_trend: a pointer to a function that reads the sensor temperature trend. set_emul_temp:a pointer to a function that sets diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 5133cd1..e5bfbd3 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -520,6 +520,51 @@ exit: } EXPORT_SYMBOL_GPL(thermal_zone_get_temp); +static void thermal_zone_set_trips(struct thermal_zone_device *tz) +{ +int low = -INT_MAX; +int high = INT_MAX; +int trip_temp, hysteresis; +int temp = tz->temperature; +int i, ret; + +if (!tz->ops->set_trips) +return; + +for (i = 0; i < tz->trips; i++) { +int trip_low; + +tz->ops->get_trip_temp(tz, i, _temp); +tz->ops->get_trip_hyst(tz, i, ); + +trip_low = trip_temp - hysteresis; + +if (trip_low < temp && trip_low > low) +low = trip_low; + +if (trip_temp > temp && trip_temp < high) +high = trip_temp; +} + +/* No need to change trip points */ +if (tz->prev_low_trip == low && tz->prev_high_trip == high) +return; + +tz->prev_low_trip = low; +tz->prev_high_trip = high; + +dev_dbg(>device, "new temperature boundaries: %d < x < %d\n", +low, high); + +/* + * Set a temperature window. When this window is left the driver + * must inform the thermal core via thermal_zone_device_update. + */ +ret = tz->ops->set_trips(tz, low, high); +if (ret) +dev_err(>device, "Failed to set trips: %d\n", ret); In the v2 review (http://article.gmane.org/gmane.linux.documentation/38442) you agreed to add locking but you haven't done it. Maybe you sent the wrong version? My god! Yep, I remember to change it. Somehow why ... Thanks Javi for looking over it. Hoping the next version is
Re: [PATCH] mmc: dw_mmc: Consider HLE errors to be data and command errors
在 2016/5/26 11:59, Jaehoon Chung 写道: On 05/26/2016 11:23 AM, Shawn Lin wrote: Hi Jaehoon, On 2016/5/19 21:07, Jaehoon Chung wrote: On 05/19/2016 08:31 PM, Shawn Lin wrote: Hi, On 2016/5/19 1:37, Doug Anderson wrote: Hi, On Wed, May 18, 2016 at 2:14 AM, Shawn Linwrote: Hi On 2016-5-18 12:12, Doug Anderson wrote: Hi, On Tue, May 17, 2016 at 6:59 PM, Shawn Lin wrote: Could you try this patch to see if you can still find HLE? @@ -2356,12 +2356,22 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) static void dw_mci_handle_cd(struct dw_mci *host) { int i; + int present; for (i = 0; i < host->num_slots; i++) { struct dw_mci_slot *slot = host->slot[i]; if (!slot) continue; + present = !(mci_readl(slot->host, CDETECT) & (1 << slot->id)); + if (present) + set_bit(DW_MMC_CARD_PRESENT, >flags); + else + clear_bit(DW_MMC_CARD_PRESENT, >flags); No, because we don't use the builtin card detect on veyron. ;) We use GPIO card detect because we didn't like the way JTAG and SD interacted. Also on rk3288 the builtin card detect line had the wrong voltage domain (you couldn't detect a card when the IO lines were powered off). The builtin card detect line is always driven low on veyron. Okay, I see. I'm nearly certain that the root cause of my HLE errors is actually related to the same problem addressed by the commit 7c5209c315ea ("mmc: core: Increase delay for voltage to stabilize from 3.3V to 1.8V"). I think that on minnie we're still on the hairy edge and sometimes the line doesn't transition fast enough. Things are not so simple from your details. I was not enabling SD3.0 support, then I also found HLE sometimes. So it seems commit 7c5209c315ea does not contibute to this phenomenon. Just to clarify, in my case commit 7c5209c315ea didn't make the problem worse, but made it better. Just not better enough. ;) The scenario looks like: remove sd-card -> mmc_sd_detect -> send status(CMD13) ->power_off -> set_ios -> setup_bus -> disabled clk , then HLE irq storm coming From the code of dw_mci_prepare_command: SDMMC_CMD_PRV_DAT_WAIT will not be used for CMD13, so we don't wait_busy here, then cmd code is loding into queue of dw_mmc but still failing send out because it's in busy? With my patch, things go well: remove sd-card -> clear bit of DW_MMC_CARD_PRESENT -> send status(CMD13) return directly -> power_off -> set_ios -> setup_bus -> disable clk So why should we allow inquiry of card status if we sure the card is removed? I mean no any further cmds should be delivered. Quite honestly just dealing with the HLE error (my patch or equivalent) might be a sane solution for the problem you describe. Yes, your patch looks good to me, so it should be merged firstly. :) Then let's push it a bit further more that when HLEs are coming, somethings must be wrong(currently I don't see a obvious clue from the code itself although, I'm prone to think it belongs to the software issue). We don't know what's main cause for HLE..But i also think it's relevant to SW issue. But we need to consider all possibilities.. dw_mmc needs to be able to work with an external card detect GPIO. It's been part of the dw_mmc driver for a long time and is (in fact) in use upstream at least by rk3288-veyron. Any solution that only works for internal card detect is not enough. Just handling the HLE error to deal with the interrupt storm and then letting Linux remove the card (because of the card detect interrupt) seems totally OK to me. Sure, some of rockchip Socs use gpio for CD because they don't have a internal CD, such as RK3036, right? Note: I'd be very curious if your problems get better if you disable Not at all. the "grf_force_jtag" bit in the GRF. If you're using the builtin card detect and you use the boot default of "grf_force_jtag" then your pins will be unmuxed behind your back when the card is ejected. This could be causing the dw_mmc controller to get confused. Right, grf_force_jtag is also not a friend of mine. :) So I had disabled this function before I was debugging it. And another question: should we wait busy for cmd13? I don't think so. As I understand it CMD13 uses only the CMD line for communication and it should be appropriate to send this when the bus is "busy" (which means that the DATA lines are low). Ahh... take back my question.. I was just considering a wired situation that pins are unmuxed on the background(cmd line as well) when cmd13 is delivering Also: it seems odd that the HLE IRQ storm didn't come right after the CMD 13 in your description above. Are you sure it was the CMD 13 that caused the HLEs, or could it has been something else? Actually no. Any cmds be issued can trigger HLEs, I
Re: [PATCH] mmc: dw_mmc: Consider HLE errors to be data and command errors
在 2016/5/26 11:59, Jaehoon Chung 写道: On 05/26/2016 11:23 AM, Shawn Lin wrote: Hi Jaehoon, On 2016/5/19 21:07, Jaehoon Chung wrote: On 05/19/2016 08:31 PM, Shawn Lin wrote: Hi, On 2016/5/19 1:37, Doug Anderson wrote: Hi, On Wed, May 18, 2016 at 2:14 AM, Shawn Lin wrote: Hi On 2016-5-18 12:12, Doug Anderson wrote: Hi, On Tue, May 17, 2016 at 6:59 PM, Shawn Lin wrote: Could you try this patch to see if you can still find HLE? @@ -2356,12 +2356,22 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) static void dw_mci_handle_cd(struct dw_mci *host) { int i; + int present; for (i = 0; i < host->num_slots; i++) { struct dw_mci_slot *slot = host->slot[i]; if (!slot) continue; + present = !(mci_readl(slot->host, CDETECT) & (1 << slot->id)); + if (present) + set_bit(DW_MMC_CARD_PRESENT, >flags); + else + clear_bit(DW_MMC_CARD_PRESENT, >flags); No, because we don't use the builtin card detect on veyron. ;) We use GPIO card detect because we didn't like the way JTAG and SD interacted. Also on rk3288 the builtin card detect line had the wrong voltage domain (you couldn't detect a card when the IO lines were powered off). The builtin card detect line is always driven low on veyron. Okay, I see. I'm nearly certain that the root cause of my HLE errors is actually related to the same problem addressed by the commit 7c5209c315ea ("mmc: core: Increase delay for voltage to stabilize from 3.3V to 1.8V"). I think that on minnie we're still on the hairy edge and sometimes the line doesn't transition fast enough. Things are not so simple from your details. I was not enabling SD3.0 support, then I also found HLE sometimes. So it seems commit 7c5209c315ea does not contibute to this phenomenon. Just to clarify, in my case commit 7c5209c315ea didn't make the problem worse, but made it better. Just not better enough. ;) The scenario looks like: remove sd-card -> mmc_sd_detect -> send status(CMD13) ->power_off -> set_ios -> setup_bus -> disabled clk , then HLE irq storm coming From the code of dw_mci_prepare_command: SDMMC_CMD_PRV_DAT_WAIT will not be used for CMD13, so we don't wait_busy here, then cmd code is loding into queue of dw_mmc but still failing send out because it's in busy? With my patch, things go well: remove sd-card -> clear bit of DW_MMC_CARD_PRESENT -> send status(CMD13) return directly -> power_off -> set_ios -> setup_bus -> disable clk So why should we allow inquiry of card status if we sure the card is removed? I mean no any further cmds should be delivered. Quite honestly just dealing with the HLE error (my patch or equivalent) might be a sane solution for the problem you describe. Yes, your patch looks good to me, so it should be merged firstly. :) Then let's push it a bit further more that when HLEs are coming, somethings must be wrong(currently I don't see a obvious clue from the code itself although, I'm prone to think it belongs to the software issue). We don't know what's main cause for HLE..But i also think it's relevant to SW issue. But we need to consider all possibilities.. dw_mmc needs to be able to work with an external card detect GPIO. It's been part of the dw_mmc driver for a long time and is (in fact) in use upstream at least by rk3288-veyron. Any solution that only works for internal card detect is not enough. Just handling the HLE error to deal with the interrupt storm and then letting Linux remove the card (because of the card detect interrupt) seems totally OK to me. Sure, some of rockchip Socs use gpio for CD because they don't have a internal CD, such as RK3036, right? Note: I'd be very curious if your problems get better if you disable Not at all. the "grf_force_jtag" bit in the GRF. If you're using the builtin card detect and you use the boot default of "grf_force_jtag" then your pins will be unmuxed behind your back when the card is ejected. This could be causing the dw_mmc controller to get confused. Right, grf_force_jtag is also not a friend of mine. :) So I had disabled this function before I was debugging it. And another question: should we wait busy for cmd13? I don't think so. As I understand it CMD13 uses only the CMD line for communication and it should be appropriate to send this when the bus is "busy" (which means that the DATA lines are low). Ahh... take back my question.. I was just considering a wired situation that pins are unmuxed on the background(cmd line as well) when cmd13 is delivering Also: it seems odd that the HLE IRQ storm didn't come right after the CMD 13 in your description above. Are you sure it was the CMD 13 that caused the HLEs, or could it has been something else? Actually no. Any cmds be issued can trigger HLEs, I think, after sd card is removed When I hacked
RE: [v10, 7/7] mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
Hi Uffe, Could we merge this patchset? ... It has been a long time to wait for Arnd's response... Thanks a lot. Best regards, Yangbo Lu > -Original Message- > From: Yangbo Lu > Sent: Friday, May 20, 2016 2:06 PM > To: 'Scott Wood'; Arnd Bergmann; linux-arm-ker...@lists.infradead.org > Cc: linuxppc-...@lists.ozlabs.org; Mark Rutland; > devicet...@vger.kernel.org; ulf.hans...@linaro.org; Russell King; Bhupesh > Sharma; net...@vger.kernel.org; Joerg Roedel; Kumar Gala; linux- > m...@vger.kernel.org; linux-kernel@vger.kernel.org; Yang-Leo Li; > io...@lists.linux-foundation.org; Rob Herring; linux-...@vger.kernel.org; > Claudiu Manoil; Santosh Shilimkar; Xiaobo Xie; linux-...@vger.kernel.org; > Qiang Zhao > Subject: RE: [v10, 7/7] mmc: sdhci-of-esdhc: fix host version for T4240- > R1.0-R2.0 > > Hi Arnd, > > Any comments? > Please reply when you see the email since we want this eSDHC issue to be > fixed soon. > > All the patches are Freescale-specific and is to fix the eSDHC driver. > Could we let them merged first if you were talking about a new way of > abstracting getting SoC version. > > > Thanks :) > > > Best regards, > Yangbo Lu >
RE: [v10, 7/7] mmc: sdhci-of-esdhc: fix host version for T4240-R1.0-R2.0
Hi Uffe, Could we merge this patchset? ... It has been a long time to wait for Arnd's response... Thanks a lot. Best regards, Yangbo Lu > -Original Message- > From: Yangbo Lu > Sent: Friday, May 20, 2016 2:06 PM > To: 'Scott Wood'; Arnd Bergmann; linux-arm-ker...@lists.infradead.org > Cc: linuxppc-...@lists.ozlabs.org; Mark Rutland; > devicet...@vger.kernel.org; ulf.hans...@linaro.org; Russell King; Bhupesh > Sharma; net...@vger.kernel.org; Joerg Roedel; Kumar Gala; linux- > m...@vger.kernel.org; linux-kernel@vger.kernel.org; Yang-Leo Li; > io...@lists.linux-foundation.org; Rob Herring; linux-...@vger.kernel.org; > Claudiu Manoil; Santosh Shilimkar; Xiaobo Xie; linux-...@vger.kernel.org; > Qiang Zhao > Subject: RE: [v10, 7/7] mmc: sdhci-of-esdhc: fix host version for T4240- > R1.0-R2.0 > > Hi Arnd, > > Any comments? > Please reply when you see the email since we want this eSDHC issue to be > fixed soon. > > All the patches are Freescale-specific and is to fix the eSDHC driver. > Could we let them merged first if you were talking about a new way of > abstracting getting SoC version. > > > Thanks :) > > > Best regards, > Yangbo Lu >
Re: [PATCH 1/2] arm: dra7: Add hwmod entry for i2c6
On Wednesday 25 May 2016 06:23 PM, Ravikumar Kattekola wrote: > dra72x device has i2c6 controller. > Adding hwmod definition for the same. > > Reference DRA72x TRM [ SPRUHP2Q ] > > Signed-off-by: Ravikumar Kattekola> --- > arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 23 +++ > 1 file changed, 23 insertions(+) > > diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c > b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c > index d0e7e525..b84c0f7 100644 > --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c > +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c > @@ -1127,6 +1127,20 @@ static struct omap_hwmod dra7xx_i2c5_hwmod = { > .dev_attr = _dev_attr, > }; > > +/* i2c6 */ > +static struct omap_hwmod dra7xx_i2c6_hwmod = { > + .name = "i2c6", > + .class = _i2c_hwmod_class, > + .clkdm_name = "l4per2_clkdm", > + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, > + .main_clk = "func_96m_fclk", > + .prcm = { > + .omap4 = { > + }, > + }, > + .dev_attr = _dev_attr, > +}; > + > /* > * 'mailbox' class > * > @@ -3186,6 +3200,14 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c5 = > { > .user = OCP_USER_MPU | OCP_USER_SDMA, > }; > > +/* l4_per2 -> i2c6 */ > +static struct omap_hwmod_ocp_if dra7xx_l4_per2__i2c6 = { > + .master = _l4_per2_hwmod, > + .slave = _i2c6_hwmod, > + .clk= "l3_iclk_div", > + .user = OCP_USER_MPU | OCP_USER_SDMA, > +}; > + > /* l4_cfg -> mailbox1 */ > static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mailbox1 = { > .master = _l4_cfg_hwmod, > @@ -3857,6 +3879,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] > __initdata = { > _l4_per1__i2c3, > _l4_per1__i2c4, > _l4_per1__i2c5, > + _l4_per2__i2c6, If it is available only on dra72x, register the hwmod under dra72x_hwmod_ocp_ifs. Also in $subject use dra72x to make things clear. Thanks and regards, Lokesh > _l4_cfg__mailbox1, > _l4_per3__mailbox2, > _l4_per3__mailbox3, >
Re: [PATCH 1/2] arm: dra7: Add hwmod entry for i2c6
On Wednesday 25 May 2016 06:23 PM, Ravikumar Kattekola wrote: > dra72x device has i2c6 controller. > Adding hwmod definition for the same. > > Reference DRA72x TRM [ SPRUHP2Q ] > > Signed-off-by: Ravikumar Kattekola > --- > arch/arm/mach-omap2/omap_hwmod_7xx_data.c | 23 +++ > 1 file changed, 23 insertions(+) > > diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c > b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c > index d0e7e525..b84c0f7 100644 > --- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c > +++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c > @@ -1127,6 +1127,20 @@ static struct omap_hwmod dra7xx_i2c5_hwmod = { > .dev_attr = _dev_attr, > }; > > +/* i2c6 */ > +static struct omap_hwmod dra7xx_i2c6_hwmod = { > + .name = "i2c6", > + .class = _i2c_hwmod_class, > + .clkdm_name = "l4per2_clkdm", > + .flags = HWMOD_16BIT_REG | HWMOD_SET_DEFAULT_CLOCKACT, > + .main_clk = "func_96m_fclk", > + .prcm = { > + .omap4 = { > + }, > + }, > + .dev_attr = _dev_attr, > +}; > + > /* > * 'mailbox' class > * > @@ -3186,6 +3200,14 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per1__i2c5 = > { > .user = OCP_USER_MPU | OCP_USER_SDMA, > }; > > +/* l4_per2 -> i2c6 */ > +static struct omap_hwmod_ocp_if dra7xx_l4_per2__i2c6 = { > + .master = _l4_per2_hwmod, > + .slave = _i2c6_hwmod, > + .clk= "l3_iclk_div", > + .user = OCP_USER_MPU | OCP_USER_SDMA, > +}; > + > /* l4_cfg -> mailbox1 */ > static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mailbox1 = { > .master = _l4_cfg_hwmod, > @@ -3857,6 +3879,7 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] > __initdata = { > _l4_per1__i2c3, > _l4_per1__i2c4, > _l4_per1__i2c5, > + _l4_per2__i2c6, If it is available only on dra72x, register the hwmod under dra72x_hwmod_ocp_ifs. Also in $subject use dra72x to make things clear. Thanks and regards, Lokesh > _l4_cfg__mailbox1, > _l4_per3__mailbox2, > _l4_per3__mailbox3, >
Re: [PATCH] mmc: dw_mmc: Consider HLE errors to be data and command errors
On 05/26/2016 11:23 AM, Shawn Lin wrote: > Hi Jaehoon, > > On 2016/5/19 21:07, Jaehoon Chung wrote: >> On 05/19/2016 08:31 PM, Shawn Lin wrote: >>> Hi, >>> >>> On 2016/5/19 1:37, Doug Anderson wrote: Hi, On Wed, May 18, 2016 at 2:14 AM, Shawn Linwrote: > Hi > > > On 2016-5-18 12:12, Doug Anderson wrote: >> >> Hi, >> >> On Tue, May 17, 2016 at 6:59 PM, Shawn Lin >> wrote: >>> >>> Could you try this patch to see if you can still find HLE? >>> >>> @@ -2356,12 +2356,22 @@ static void dw_mci_cmd_interrupt(struct dw_mci >>> *host, u32 status) >>> static void dw_mci_handle_cd(struct dw_mci *host) >>> { >>> int i; >>> + int present; >>> >>> for (i = 0; i < host->num_slots; i++) { >>> struct dw_mci_slot *slot = host->slot[i]; >>> >>> if (!slot) >>> continue; >>> >>> + present = !(mci_readl(slot->host, CDETECT) & (1 << >>> slot->id)); >>> + if (present) >>> + set_bit(DW_MMC_CARD_PRESENT, >flags); >>> + else >>> + clear_bit(DW_MMC_CARD_PRESENT, >flags); >> >> >> No, because we don't use the builtin card detect on veyron. ;) >> >> We use GPIO card detect because we didn't like the way JTAG and SD >> interacted. Also on rk3288 the builtin card detect line had the wrong >> voltage domain (you couldn't detect a card when the IO lines were >> powered off). The builtin card detect line is always driven low on >> veyron. > > > Okay, I see. > >> >> >> I'm nearly certain that the root cause of my HLE errors is actually >> related to the same problem addressed by the commit 7c5209c315ea >> ("mmc: core: Increase delay for voltage to stabilize from 3.3V to >> 1.8V"). I think that on minnie we're still on the hairy edge and >> sometimes the line doesn't transition fast enough. > > > Things are not so simple from your details. > > I was not enabling SD3.0 support, then I also found HLE sometimes. > So it seems commit 7c5209c315ea does not contibute to this phenomenon. Just to clarify, in my case commit 7c5209c315ea didn't make the problem worse, but made it better. Just not better enough. ;) > The scenario looks like: > remove sd-card -> mmc_sd_detect -> send status(CMD13) ->power_off -> > set_ios -> setup_bus -> disabled clk , then HLE irq storm coming > > From the code of dw_mci_prepare_command: > SDMMC_CMD_PRV_DAT_WAIT will not be used for CMD13, so we don't > wait_busy here, then cmd code is loding into queue of dw_mmc but > still failing send out because it's in busy? > > With my patch, things go well: > remove sd-card -> clear bit of DW_MMC_CARD_PRESENT -> send > status(CMD13) return directly -> power_off -> set_ios -> setup_bus -> > disable clk > > So why should we allow inquiry of card status if we sure the card is > removed? I mean no any further cmds should be delivered. Quite honestly just dealing with the HLE error (my patch or equivalent) might be a sane solution for the problem you describe. >>> >>> Yes, your patch looks good to me, so it should be merged firstly. :) >>> Then let's push it a bit further more that when HLEs are coming, >>> somethings must be wrong(currently I don't see a obvious clue from >>> the code itself although, I'm prone to think it belongs to the >>> software issue). >> >> We don't know what's main cause for HLE..But i also think it's relevant to >> SW issue. >> But we need to consider all possibilities.. >> >>> >>> dw_mmc needs to be able to work with an external card detect GPIO. It's been part of the dw_mmc driver for a long time and is (in fact) in use upstream at least by rk3288-veyron. Any solution that only works for internal card detect is not enough. Just handling the HLE error to deal with the interrupt storm and then letting Linux remove the card (because of the card detect interrupt) seems totally OK to me. >>> >>> Sure, some of rockchip Socs use gpio for CD because they don't >>> have a internal CD, such as RK3036, right? >>> Note: I'd be very curious if your problems get better if you disable >>> >>> Not at all. >>> the "grf_force_jtag" bit in the GRF. If you're using the builtin card detect and you use the boot default of "grf_force_jtag" then your pins will be unmuxed behind your back when the card is ejected. This could be causing the dw_mmc controller to get confused. >>> >>> Right, grf_force_jtag is also not a friend of mine. :) >>> So I had disabled this function before I was debugging it. >>> > And
Re: [PATCH] mmc: dw_mmc: Consider HLE errors to be data and command errors
On 05/26/2016 11:23 AM, Shawn Lin wrote: > Hi Jaehoon, > > On 2016/5/19 21:07, Jaehoon Chung wrote: >> On 05/19/2016 08:31 PM, Shawn Lin wrote: >>> Hi, >>> >>> On 2016/5/19 1:37, Doug Anderson wrote: Hi, On Wed, May 18, 2016 at 2:14 AM, Shawn Lin wrote: > Hi > > > On 2016-5-18 12:12, Doug Anderson wrote: >> >> Hi, >> >> On Tue, May 17, 2016 at 6:59 PM, Shawn Lin >> wrote: >>> >>> Could you try this patch to see if you can still find HLE? >>> >>> @@ -2356,12 +2356,22 @@ static void dw_mci_cmd_interrupt(struct dw_mci >>> *host, u32 status) >>> static void dw_mci_handle_cd(struct dw_mci *host) >>> { >>> int i; >>> + int present; >>> >>> for (i = 0; i < host->num_slots; i++) { >>> struct dw_mci_slot *slot = host->slot[i]; >>> >>> if (!slot) >>> continue; >>> >>> + present = !(mci_readl(slot->host, CDETECT) & (1 << >>> slot->id)); >>> + if (present) >>> + set_bit(DW_MMC_CARD_PRESENT, >flags); >>> + else >>> + clear_bit(DW_MMC_CARD_PRESENT, >flags); >> >> >> No, because we don't use the builtin card detect on veyron. ;) >> >> We use GPIO card detect because we didn't like the way JTAG and SD >> interacted. Also on rk3288 the builtin card detect line had the wrong >> voltage domain (you couldn't detect a card when the IO lines were >> powered off). The builtin card detect line is always driven low on >> veyron. > > > Okay, I see. > >> >> >> I'm nearly certain that the root cause of my HLE errors is actually >> related to the same problem addressed by the commit 7c5209c315ea >> ("mmc: core: Increase delay for voltage to stabilize from 3.3V to >> 1.8V"). I think that on minnie we're still on the hairy edge and >> sometimes the line doesn't transition fast enough. > > > Things are not so simple from your details. > > I was not enabling SD3.0 support, then I also found HLE sometimes. > So it seems commit 7c5209c315ea does not contibute to this phenomenon. Just to clarify, in my case commit 7c5209c315ea didn't make the problem worse, but made it better. Just not better enough. ;) > The scenario looks like: > remove sd-card -> mmc_sd_detect -> send status(CMD13) ->power_off -> > set_ios -> setup_bus -> disabled clk , then HLE irq storm coming > > From the code of dw_mci_prepare_command: > SDMMC_CMD_PRV_DAT_WAIT will not be used for CMD13, so we don't > wait_busy here, then cmd code is loding into queue of dw_mmc but > still failing send out because it's in busy? > > With my patch, things go well: > remove sd-card -> clear bit of DW_MMC_CARD_PRESENT -> send > status(CMD13) return directly -> power_off -> set_ios -> setup_bus -> > disable clk > > So why should we allow inquiry of card status if we sure the card is > removed? I mean no any further cmds should be delivered. Quite honestly just dealing with the HLE error (my patch or equivalent) might be a sane solution for the problem you describe. >>> >>> Yes, your patch looks good to me, so it should be merged firstly. :) >>> Then let's push it a bit further more that when HLEs are coming, >>> somethings must be wrong(currently I don't see a obvious clue from >>> the code itself although, I'm prone to think it belongs to the >>> software issue). >> >> We don't know what's main cause for HLE..But i also think it's relevant to >> SW issue. >> But we need to consider all possibilities.. >> >>> >>> dw_mmc needs to be able to work with an external card detect GPIO. It's been part of the dw_mmc driver for a long time and is (in fact) in use upstream at least by rk3288-veyron. Any solution that only works for internal card detect is not enough. Just handling the HLE error to deal with the interrupt storm and then letting Linux remove the card (because of the card detect interrupt) seems totally OK to me. >>> >>> Sure, some of rockchip Socs use gpio for CD because they don't >>> have a internal CD, such as RK3036, right? >>> Note: I'd be very curious if your problems get better if you disable >>> >>> Not at all. >>> the "grf_force_jtag" bit in the GRF. If you're using the builtin card detect and you use the boot default of "grf_force_jtag" then your pins will be unmuxed behind your back when the card is ejected. This could be causing the dw_mmc controller to get confused. >>> >>> Right, grf_force_jtag is also not a friend of mine. :) >>> So I had disabled this function before I was debugging it. >>> > And another question: should we wait busy for cmd13? I
Re: [PATCH 2/5] iommu: Set PCI_BUS_FLAGS_MSI_REMAP if IOMMU have capability of IRQ remapping
On Wed, May 25, 2016 at 01:54:23PM +0800, Yongji Xie wrote: > On 2016/5/25 5:11, Bjorn Helgaas wrote: > >On Wed, Apr 27, 2016 at 08:43:27PM +0800, Yongji Xie wrote: > >>The capability of IRQ remapping is abstracted on IOMMU side on > >>some archs. There is a existing flag IOMMU_CAP_INTR_REMAP for this. > >> > >>To have a universal flag to test this capability for different > >>archs on PCI side, we set PCI_BUS_FLAGS_MSI_REMAP for PCI buses > >>when IOMMU_CAP_INTR_REMAP is set. > >> > >>Signed-off-by: Yongji Xie> >>--- > >> drivers/iommu/iommu.c | 15 +++ > >> 1 file changed, 15 insertions(+) > >> > >>diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c > >>index 0e3b009..5d2b6f6 100644 > >>--- a/drivers/iommu/iommu.c > >>+++ b/drivers/iommu/iommu.c > >>@@ -813,6 +813,16 @@ struct iommu_group *pci_device_group(struct device > >>*dev) > >>return group; > >> } > >>+static void pci_check_msi_remapping(struct pci_dev *pdev, > >>+ const struct iommu_ops *ops) > >>+{ > >>+ struct pci_bus *bus = pdev->bus; > >>+ > >>+ if (ops->capable(IOMMU_CAP_INTR_REMAP) && > >>+ !(bus->bus_flags & PCI_BUS_FLAGS_MSI_REMAP)) > >>+ bus->bus_flags |= PCI_BUS_FLAGS_MSI_REMAP; > >>+} > >This looks an awful lot like the pci_bus_check_msi_remapping() you add > >elsewhere. Why do we need both? > > I will modify this function as you suggested. And we add this function > here because some iommu drivers would be initialed after PCI probing. > > >> /** > >> * iommu_group_get_for_dev - Find or create the IOMMU group for a device > >> * @dev: target device > >>@@ -871,6 +881,9 @@ static int add_iommu_group(struct device *dev, void > >>*data) > >>const struct iommu_ops *ops = cb->ops; > >>int ret; > >>+ if (dev_is_pci(dev) && ops->capable) > >>+ pci_check_msi_remapping(to_pci_dev(dev), ops); > >>+ > >>if (!ops->add_device) > >>return 0; > >>@@ -913,6 +926,8 @@ static int iommu_bus_notifier(struct notifier_block *nb, > >> * result in ADD/DEL notifiers to group->notifier > >> */ > >>if (action == BUS_NOTIFY_ADD_DEVICE) { > >>+ if (dev_is_pci(dev) && ops->capable) > >>+ pci_check_msi_remapping(to_pci_dev(dev), ops); > >These calls don't smell right either. Why do we need dev_is_pci() > >checks here? > > Some platform devices may also call this. > > >Can't this be done in the PCI probe path somehow, e.g., > >in pci_set_bus_msi_domain() or something? > > Yes, this can be done in pci_create_root_bus(). But it could only > handle the case that iommu drivers are initialed before PCI probing. Hmm, that's sort of what I expected, but I don't like it. I don't think initializing IOMMU drivers after probing PCI devices is the optimal design. As soon as we add a PCI device, a driver can bind to it and start using it. If we set up an IOMMU after a driver has claimed the device, something is going to break. The driver may have already made DMA mappings that would now be invalid. IOMMU drivers are logically between the CPU and the device, so they should be initialized before the device is enumerated. I know there are probably some legacy issues behind this design, and I know it has nothing to do with your patch, so this is not a very constructive comment. I just want to be on record that I'm not a fan of this out-of-order initialization, and I don't like the notification scheme for handling device hotplug either. Notifiers make the code hard to read, and you can't tell what order things happen in. It just seems like a hack to connect things together when they should really have been designed to be more tightly integrated from the beginning. Bjorn
Re: [PATCH 2/5] iommu: Set PCI_BUS_FLAGS_MSI_REMAP if IOMMU have capability of IRQ remapping
On Wed, May 25, 2016 at 01:54:23PM +0800, Yongji Xie wrote: > On 2016/5/25 5:11, Bjorn Helgaas wrote: > >On Wed, Apr 27, 2016 at 08:43:27PM +0800, Yongji Xie wrote: > >>The capability of IRQ remapping is abstracted on IOMMU side on > >>some archs. There is a existing flag IOMMU_CAP_INTR_REMAP for this. > >> > >>To have a universal flag to test this capability for different > >>archs on PCI side, we set PCI_BUS_FLAGS_MSI_REMAP for PCI buses > >>when IOMMU_CAP_INTR_REMAP is set. > >> > >>Signed-off-by: Yongji Xie > >>--- > >> drivers/iommu/iommu.c | 15 +++ > >> 1 file changed, 15 insertions(+) > >> > >>diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c > >>index 0e3b009..5d2b6f6 100644 > >>--- a/drivers/iommu/iommu.c > >>+++ b/drivers/iommu/iommu.c > >>@@ -813,6 +813,16 @@ struct iommu_group *pci_device_group(struct device > >>*dev) > >>return group; > >> } > >>+static void pci_check_msi_remapping(struct pci_dev *pdev, > >>+ const struct iommu_ops *ops) > >>+{ > >>+ struct pci_bus *bus = pdev->bus; > >>+ > >>+ if (ops->capable(IOMMU_CAP_INTR_REMAP) && > >>+ !(bus->bus_flags & PCI_BUS_FLAGS_MSI_REMAP)) > >>+ bus->bus_flags |= PCI_BUS_FLAGS_MSI_REMAP; > >>+} > >This looks an awful lot like the pci_bus_check_msi_remapping() you add > >elsewhere. Why do we need both? > > I will modify this function as you suggested. And we add this function > here because some iommu drivers would be initialed after PCI probing. > > >> /** > >> * iommu_group_get_for_dev - Find or create the IOMMU group for a device > >> * @dev: target device > >>@@ -871,6 +881,9 @@ static int add_iommu_group(struct device *dev, void > >>*data) > >>const struct iommu_ops *ops = cb->ops; > >>int ret; > >>+ if (dev_is_pci(dev) && ops->capable) > >>+ pci_check_msi_remapping(to_pci_dev(dev), ops); > >>+ > >>if (!ops->add_device) > >>return 0; > >>@@ -913,6 +926,8 @@ static int iommu_bus_notifier(struct notifier_block *nb, > >> * result in ADD/DEL notifiers to group->notifier > >> */ > >>if (action == BUS_NOTIFY_ADD_DEVICE) { > >>+ if (dev_is_pci(dev) && ops->capable) > >>+ pci_check_msi_remapping(to_pci_dev(dev), ops); > >These calls don't smell right either. Why do we need dev_is_pci() > >checks here? > > Some platform devices may also call this. > > >Can't this be done in the PCI probe path somehow, e.g., > >in pci_set_bus_msi_domain() or something? > > Yes, this can be done in pci_create_root_bus(). But it could only > handle the case that iommu drivers are initialed before PCI probing. Hmm, that's sort of what I expected, but I don't like it. I don't think initializing IOMMU drivers after probing PCI devices is the optimal design. As soon as we add a PCI device, a driver can bind to it and start using it. If we set up an IOMMU after a driver has claimed the device, something is going to break. The driver may have already made DMA mappings that would now be invalid. IOMMU drivers are logically between the CPU and the device, so they should be initialized before the device is enumerated. I know there are probably some legacy issues behind this design, and I know it has nothing to do with your patch, so this is not a very constructive comment. I just want to be on record that I'm not a fan of this out-of-order initialization, and I don't like the notification scheme for handling device hotplug either. Notifiers make the code hard to read, and you can't tell what order things happen in. It just seems like a hack to connect things together when they should really have been designed to be more tightly integrated from the beginning. Bjorn
Re: [PATCHv3] support for AD5820 camera auto-focus coil
On 24.05.2016 23:20, Pavel Machek wrote: Hi! devm_regulator_get()? I'd rather avoid devm_ here. Driver is simple enough to allow it. Now thinking about it, what would happen here if regulator_get() returns -EPROBE_DEFER? Wouldn't it be better to move regulator_get to the probe() function, something like: Ok, I can do it. Oh, and don't try to complain about newlines before returns. It looks better this way. All I complain about is missing empty line before a final return at the end of a function :). I guess it is a matter of preference though. static int ad5820_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct ad5820_device *coil; int ret = 0; coil = devm_kzalloc(sizeof(*coil), GFP_KERNEL); if (coil == NULL) return -ENOMEM; coil->vana = devm_regulator_get(>dev, NULL); if (IS_ERR(coil->vana)) { ret = PTR_ERR(coil->vana); if (ret != -EPROBE_DEFER) dev_err(>dev, "could not get regulator for vana\n"); return ret; } mutex_init(>power_lock); ... with the appropriate changes to remove() because of the devm API usage. Something like this? Didn't try to apply it, but yes, looks right. Besides the missing mutex_destroy(>power_lock); pointed out by Sakari. diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c index f956bd3..f871366 100644 --- a/drivers/media/i2c/ad5820.c +++ b/drivers/media/i2c/ad5820.c @@ -8,7 +8,7 @@ * Copyright (C) 2016 Pavel Machek* * Contact: Tuukka Toivonen - * Sakari Ailus + * Sakari Ailus * * Based on af_d88.c by Texas Instruments. * @@ -263,13 +263,6 @@ static int ad5820_init_controls(struct ad5820_device *coil) static int ad5820_registered(struct v4l2_subdev *subdev) { struct ad5820_device *coil = to_ad5820_device(subdev); - struct i2c_client *client = v4l2_get_subdevdata(subdev); - - coil->vana = regulator_get(>dev, "VANA"); - if (IS_ERR(coil->vana)) { - dev_err(>dev, "could not get regulator for vana\n"); - return -ENODEV; - } return ad5820_init_controls(coil); } @@ -367,10 +360,18 @@ static int ad5820_probe(struct i2c_client *client, struct ad5820_device *coil; int ret = 0; - coil = kzalloc(sizeof(*coil), GFP_KERNEL); + coil = devm_kzalloc(sizeof(*coil), GFP_KERNEL); if (!coil) return -ENOMEM; + coil->vana = devm_regulator_get(>dev, NULL); + if (IS_ERR(coil->vana)) { + ret = PTR_ERR(coil->vana); + if (ret != -EPROBE_DEFER) + dev_err(>dev, "could not get regulator for vana\n"); + return ret; + } + mutex_init(>power_lock); v4l2_i2c_subdev_init(>subdev, client, _ops); @@ -390,10 +391,6 @@ static int ad5820_probe(struct i2c_client *client, cleanup: media_entity_cleanup(>subdev.entity); - -free: - kfree(coil); - return ret; } @@ -405,11 +402,6 @@ static int __exit ad5820_remove(struct i2c_client *client) v4l2_device_unregister_subdev(>subdev); v4l2_ctrl_handler_free(>ctrls); media_entity_cleanup(>subdev.entity); - if (coil->vana) - regulator_put(coil->vana); - - kfree(coil); - return 0; }
Re: [PATCHv3] support for AD5820 camera auto-focus coil
On 24.05.2016 23:20, Pavel Machek wrote: Hi! devm_regulator_get()? I'd rather avoid devm_ here. Driver is simple enough to allow it. Now thinking about it, what would happen here if regulator_get() returns -EPROBE_DEFER? Wouldn't it be better to move regulator_get to the probe() function, something like: Ok, I can do it. Oh, and don't try to complain about newlines before returns. It looks better this way. All I complain about is missing empty line before a final return at the end of a function :). I guess it is a matter of preference though. static int ad5820_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct ad5820_device *coil; int ret = 0; coil = devm_kzalloc(sizeof(*coil), GFP_KERNEL); if (coil == NULL) return -ENOMEM; coil->vana = devm_regulator_get(>dev, NULL); if (IS_ERR(coil->vana)) { ret = PTR_ERR(coil->vana); if (ret != -EPROBE_DEFER) dev_err(>dev, "could not get regulator for vana\n"); return ret; } mutex_init(>power_lock); ... with the appropriate changes to remove() because of the devm API usage. Something like this? Didn't try to apply it, but yes, looks right. Besides the missing mutex_destroy(>power_lock); pointed out by Sakari. diff --git a/drivers/media/i2c/ad5820.c b/drivers/media/i2c/ad5820.c index f956bd3..f871366 100644 --- a/drivers/media/i2c/ad5820.c +++ b/drivers/media/i2c/ad5820.c @@ -8,7 +8,7 @@ * Copyright (C) 2016 Pavel Machek * * Contact: Tuukka Toivonen - * Sakari Ailus + * Sakari Ailus * * Based on af_d88.c by Texas Instruments. * @@ -263,13 +263,6 @@ static int ad5820_init_controls(struct ad5820_device *coil) static int ad5820_registered(struct v4l2_subdev *subdev) { struct ad5820_device *coil = to_ad5820_device(subdev); - struct i2c_client *client = v4l2_get_subdevdata(subdev); - - coil->vana = regulator_get(>dev, "VANA"); - if (IS_ERR(coil->vana)) { - dev_err(>dev, "could not get regulator for vana\n"); - return -ENODEV; - } return ad5820_init_controls(coil); } @@ -367,10 +360,18 @@ static int ad5820_probe(struct i2c_client *client, struct ad5820_device *coil; int ret = 0; - coil = kzalloc(sizeof(*coil), GFP_KERNEL); + coil = devm_kzalloc(sizeof(*coil), GFP_KERNEL); if (!coil) return -ENOMEM; + coil->vana = devm_regulator_get(>dev, NULL); + if (IS_ERR(coil->vana)) { + ret = PTR_ERR(coil->vana); + if (ret != -EPROBE_DEFER) + dev_err(>dev, "could not get regulator for vana\n"); + return ret; + } + mutex_init(>power_lock); v4l2_i2c_subdev_init(>subdev, client, _ops); @@ -390,10 +391,6 @@ static int ad5820_probe(struct i2c_client *client, cleanup: media_entity_cleanup(>subdev.entity); - -free: - kfree(coil); - return ret; } @@ -405,11 +402,6 @@ static int __exit ad5820_remove(struct i2c_client *client) v4l2_device_unregister_subdev(>subdev); v4l2_ctrl_handler_free(>ctrls); media_entity_cleanup(>subdev.entity); - if (coil->vana) - regulator_put(coil->vana); - - kfree(coil); - return 0; }
Re: [PATCH 1/1] arm64: fix flush_cache_range
On 2016/5/25 18:50, Catalin Marinas wrote: > On Wed, May 25, 2016 at 11:36:38AM +0800, Leizhen (ThunderTown) wrote: >> On 2016/5/25 9:20, Leizhen (ThunderTown) wrote: >>> On 2016/5/24 21:02, Catalin Marinas wrote: On Tue, May 24, 2016 at 08:19:05PM +0800, Leizhen (ThunderTown) wrote: > On 2016/5/24 19:37, Mark Rutland wrote: >> It looks like the test may be missing I-cache maintenance regardless of >> the semantics of mprotect in this case. >> >> I have not yet devled into flush_cache_range and how it is called. > > SYSCALL_DEFINE3(mprotect ---> mprotect_fixup ---> change_protection ---> > change_protection_range --> flush_cache_range The change_protection() shouldn't need to flush the caches in flush_cache_range(). The change_pte_range() function eventually ends up calling set_pte_at() which calls __sync_icache_dcache() if the mapping is executable. >>> >>> OK, I see. >>> But I'm afraid it entered the "if (pte_present(oldpte))" branch in >>> function change_pte_range. Because the test case called mmap to >>> create pte first, then called pte_modify. I will check it later. >> >> I have checked that it entered "if (pte_present(oldpte))" branch. > > This path eventually calls set_pte_at() via ptep_modify_prot_commit(). OK, I see. > >> But I don't known why I add flush_icache_range is OK, but add >> __sync_icache_dcache have no effect. > > Do you mean you modified set_pte_at() to use flush_icache_range() Just about. I added in change_pte_range after below statement. ptent = pte_modify(ptent, newprot); > instead of __sync_icache_dcache() and it works? Yes. > > What happens is that __sync_icache_dcache() only takes care of the first > time a page is mapped in user space and flushes the caches, marking it > as "clean" (PG_dcache_clean) afterwards. Subsequent changes to this > mapping or writes to it are entirely the responsibility of the user. So > if the user plans to execute instructions, it better explicitly flush > the caches (as Mark Rutland already stated in a previous reply). > > I ran our internal LTP version yesterday and it was fine but didn't > realise that we actually patched mprotect04.c to include: > > __clear_cache((char *)func, (char *)func + page_sz); > > just after memcpy(). Yes, I aslo tried this before I sent this patch. Flush dcache in userspace or kernel can both fixs this problem. > > (we still need to investigate whether the I-cache invalidation is > actually needed in flush_cache_range() or it's just something we forgot > to remove) >
Re: [PATCH 1/1] arm64: fix flush_cache_range
On 2016/5/25 18:50, Catalin Marinas wrote: > On Wed, May 25, 2016 at 11:36:38AM +0800, Leizhen (ThunderTown) wrote: >> On 2016/5/25 9:20, Leizhen (ThunderTown) wrote: >>> On 2016/5/24 21:02, Catalin Marinas wrote: On Tue, May 24, 2016 at 08:19:05PM +0800, Leizhen (ThunderTown) wrote: > On 2016/5/24 19:37, Mark Rutland wrote: >> It looks like the test may be missing I-cache maintenance regardless of >> the semantics of mprotect in this case. >> >> I have not yet devled into flush_cache_range and how it is called. > > SYSCALL_DEFINE3(mprotect ---> mprotect_fixup ---> change_protection ---> > change_protection_range --> flush_cache_range The change_protection() shouldn't need to flush the caches in flush_cache_range(). The change_pte_range() function eventually ends up calling set_pte_at() which calls __sync_icache_dcache() if the mapping is executable. >>> >>> OK, I see. >>> But I'm afraid it entered the "if (pte_present(oldpte))" branch in >>> function change_pte_range. Because the test case called mmap to >>> create pte first, then called pte_modify. I will check it later. >> >> I have checked that it entered "if (pte_present(oldpte))" branch. > > This path eventually calls set_pte_at() via ptep_modify_prot_commit(). OK, I see. > >> But I don't known why I add flush_icache_range is OK, but add >> __sync_icache_dcache have no effect. > > Do you mean you modified set_pte_at() to use flush_icache_range() Just about. I added in change_pte_range after below statement. ptent = pte_modify(ptent, newprot); > instead of __sync_icache_dcache() and it works? Yes. > > What happens is that __sync_icache_dcache() only takes care of the first > time a page is mapped in user space and flushes the caches, marking it > as "clean" (PG_dcache_clean) afterwards. Subsequent changes to this > mapping or writes to it are entirely the responsibility of the user. So > if the user plans to execute instructions, it better explicitly flush > the caches (as Mark Rutland already stated in a previous reply). > > I ran our internal LTP version yesterday and it was fine but didn't > realise that we actually patched mprotect04.c to include: > > __clear_cache((char *)func, (char *)func + page_sz); > > just after memcpy(). Yes, I aslo tried this before I sent this patch. Flush dcache in userspace or kernel can both fixs this problem. > > (we still need to investigate whether the I-cache invalidation is > actually needed in flush_cache_range() or it's just something we forgot > to remove) >
Re: ARM: dts: exynos: Add MFC memory banks for Peach boards
Hi Javier, On Wednesday 25 May 2016 08:32 PM, Javier Martinez Canillas wrote: > Hello Pankaj, > > On 05/25/2016 04:33 AM, pankaj.dubey wrote: >> Hi Javier, >> >>> Signed-off-by: Javier Martinez Canillas>> >> Just noticed that, current krzk/for-next failed to boot on Exynos5880 >> based Chromebook device. Git bisect is showing culprit as this patch. > > Strange, krzk/for-next boots correctly on my Exynos5800 Peach Pi: > > $ git log --pretty=oneline --abbrev-commit HEAD > 35e691cf5165 Merge branch 'fixes-v4.7' into for-next > This is same as mine. My other build parameters are: defconfig: exynos_defconfig CROSS_COMPILE: gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux rootfs: small cramfs > $ uname -r > 4.6.0-00073-g35e691cf5165 > >> When I reverted this patch, its able to boot normally. >> Is there any missing patches that we need to take on krzk/for-next to >> boot on Chromebook. >> > Further I checked that, either I revert this patch OR do not reserve memory for MFC in exynos_reserve using following changes, both cases I am able to boot kernel on Chromebook (Exynos5800). diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index f977eea..e615e24 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -268,7 +268,7 @@ static char const *const exynos_dt_compat[] __initconst = { static void __init exynos_reserve(void) { -#ifdef CONFIG_S5P_DEV_MFC +#ifndef CONFIG_S5P_DEV_MFC int i; char *mfc_mem[] = { "samsung,mfc-v5", @@ -280,6 +280,8 @@ static void __init exynos_reserve(void) for (i = 0; i < ARRAY_SIZE(mfc_mem); i++) if (of_scan_flat_dt(s5p_fdt_alloc_mfc_mem, mfc_mem[i])) break; +#else + pr_err("*exynos_reserve Bypassing Memory Reservation for MFC \n"); #endif } > No that I'm aware of. I wonder why it boots for me but fails for > you. Can you please share your complete boot log to see if there > are any hints there? > Following is failed boot log: U-Boot 2013.04-g8e3e5ef (May 26 2015 - 16:11:36) for Peach CPU:Exynos5422@900MHz Board: Google Peach Pi, rev 11.6 I2C: ready DRAM: 3.5 GiB Relocation Offset dbd54000, base at ffb54000 SPL stack at 2072c00, used 3f0, free 10 PMIC max77802-pmic initialized CPU:Exynos5422@1800MHz TPS65090 PMIC EC init MMC: EXYNOS DWMMC: 0, EXYNOS DWMMC: 1 SF: Detected W25Q32DW with page size 4 KiB, total 32 MiB In:cros-ec-keyb Out: lcd Err: lcd SF: Detected W25Q32DW with page size 4 KiB, total 32 MiB ELOG: Event(17) added with size 13 Net: No ethernet found. Hit any key to stop autoboot: 0 mmc1 is current device 4586144 bytes read in 242 ms (18.1 MiB/s) 26583040 bytes read in 1166 ms (21.7 MiB/s) ## Loading kernel from FIT Image at 20008000 ... Using 'conf@2' configuration Trying 'kernel@1' kernel subimage Description: unavailable Type: Kernel Image (no loading done) Compression: uncompressed Data Start: 0x200080c8 Data Size:4459024 Bytes = 4.3 MiB Verifying Hash Integrity ... OK ## Loading fdt from FIT Image at 20008000 ... Using 'conf@2' configuration Trying 'fdt@2' fdt subimage Description: exynos5800-peach-pi.dtb Type: Flat Device Tree Compression: uncompressed Data Start: 0x20458148 Data Size:63002 Bytes = 61.5 KiB Architecture: ARM Hash algo:sha1 Hash value: cd1c1703f744b44b1833ca61ec36b625665548de Verifying Hash Integrity ... sha1+ OK Booting using the fdt blob at 0x20458148 XIP Kernel Image (no loading done) ... OK Loading Device Tree to 3ffe1000, end 3b49 ... OK boot_kernel.c: ft_board_setup: warning: Must pass exactly one of vboot or cdata Starting kernel ... Timer summary in microseconds: MarkElapsed Stage 0 0 reset 122,793122,793 board_init_f 143,214 20,421 board_init_r 238,069 94,855 id=64 240,278 2,209 main_loop 4,841,682 4,601,404 bootm_start 4,841,683 1 id=1 4,846,604 4,921 id=100 4,846,607 3 id=101 4,846,607 0 id=102 4,850,208 3,601 id=110 4,877,729 27,521 id=105 4,877,731 2 id=106 4,877,734 3 id=107 4,877,735 1 id=108 4,877,736 1 id=109 4,882,406 4,670 id=90 4,882,408 2 id=92 4,882,408 0 id=91 4,927,272 44,864 id=95 4,927,274 2 id=96 4,927,276 2 id=97 4,927,277 1 id=98 4,927,279 2 id=99 4,937,617 10,338 id=7 4,951,899 14,282 id=15 4,955,112 3,213 start_kernel Accumulated time: 6,948 SPI read Uncompressing Linux... done, booting the kernel. [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 4.6.0-00073-g35e691c (pankaj@chromebld-server) (gcc version 4.9.2 20140904 (prerelease)
Re: ARM: dts: exynos: Add MFC memory banks for Peach boards
Hi Javier, On Wednesday 25 May 2016 08:32 PM, Javier Martinez Canillas wrote: > Hello Pankaj, > > On 05/25/2016 04:33 AM, pankaj.dubey wrote: >> Hi Javier, >> >>> Signed-off-by: Javier Martinez Canillas >> >> Just noticed that, current krzk/for-next failed to boot on Exynos5880 >> based Chromebook device. Git bisect is showing culprit as this patch. > > Strange, krzk/for-next boots correctly on my Exynos5800 Peach Pi: > > $ git log --pretty=oneline --abbrev-commit HEAD > 35e691cf5165 Merge branch 'fixes-v4.7' into for-next > This is same as mine. My other build parameters are: defconfig: exynos_defconfig CROSS_COMPILE: gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux rootfs: small cramfs > $ uname -r > 4.6.0-00073-g35e691cf5165 > >> When I reverted this patch, its able to boot normally. >> Is there any missing patches that we need to take on krzk/for-next to >> boot on Chromebook. >> > Further I checked that, either I revert this patch OR do not reserve memory for MFC in exynos_reserve using following changes, both cases I am able to boot kernel on Chromebook (Exynos5800). diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c index f977eea..e615e24 100644 --- a/arch/arm/mach-exynos/exynos.c +++ b/arch/arm/mach-exynos/exynos.c @@ -268,7 +268,7 @@ static char const *const exynos_dt_compat[] __initconst = { static void __init exynos_reserve(void) { -#ifdef CONFIG_S5P_DEV_MFC +#ifndef CONFIG_S5P_DEV_MFC int i; char *mfc_mem[] = { "samsung,mfc-v5", @@ -280,6 +280,8 @@ static void __init exynos_reserve(void) for (i = 0; i < ARRAY_SIZE(mfc_mem); i++) if (of_scan_flat_dt(s5p_fdt_alloc_mfc_mem, mfc_mem[i])) break; +#else + pr_err("*exynos_reserve Bypassing Memory Reservation for MFC \n"); #endif } > No that I'm aware of. I wonder why it boots for me but fails for > you. Can you please share your complete boot log to see if there > are any hints there? > Following is failed boot log: U-Boot 2013.04-g8e3e5ef (May 26 2015 - 16:11:36) for Peach CPU:Exynos5422@900MHz Board: Google Peach Pi, rev 11.6 I2C: ready DRAM: 3.5 GiB Relocation Offset dbd54000, base at ffb54000 SPL stack at 2072c00, used 3f0, free 10 PMIC max77802-pmic initialized CPU:Exynos5422@1800MHz TPS65090 PMIC EC init MMC: EXYNOS DWMMC: 0, EXYNOS DWMMC: 1 SF: Detected W25Q32DW with page size 4 KiB, total 32 MiB In:cros-ec-keyb Out: lcd Err: lcd SF: Detected W25Q32DW with page size 4 KiB, total 32 MiB ELOG: Event(17) added with size 13 Net: No ethernet found. Hit any key to stop autoboot: 0 mmc1 is current device 4586144 bytes read in 242 ms (18.1 MiB/s) 26583040 bytes read in 1166 ms (21.7 MiB/s) ## Loading kernel from FIT Image at 20008000 ... Using 'conf@2' configuration Trying 'kernel@1' kernel subimage Description: unavailable Type: Kernel Image (no loading done) Compression: uncompressed Data Start: 0x200080c8 Data Size:4459024 Bytes = 4.3 MiB Verifying Hash Integrity ... OK ## Loading fdt from FIT Image at 20008000 ... Using 'conf@2' configuration Trying 'fdt@2' fdt subimage Description: exynos5800-peach-pi.dtb Type: Flat Device Tree Compression: uncompressed Data Start: 0x20458148 Data Size:63002 Bytes = 61.5 KiB Architecture: ARM Hash algo:sha1 Hash value: cd1c1703f744b44b1833ca61ec36b625665548de Verifying Hash Integrity ... sha1+ OK Booting using the fdt blob at 0x20458148 XIP Kernel Image (no loading done) ... OK Loading Device Tree to 3ffe1000, end 3b49 ... OK boot_kernel.c: ft_board_setup: warning: Must pass exactly one of vboot or cdata Starting kernel ... Timer summary in microseconds: MarkElapsed Stage 0 0 reset 122,793122,793 board_init_f 143,214 20,421 board_init_r 238,069 94,855 id=64 240,278 2,209 main_loop 4,841,682 4,601,404 bootm_start 4,841,683 1 id=1 4,846,604 4,921 id=100 4,846,607 3 id=101 4,846,607 0 id=102 4,850,208 3,601 id=110 4,877,729 27,521 id=105 4,877,731 2 id=106 4,877,734 3 id=107 4,877,735 1 id=108 4,877,736 1 id=109 4,882,406 4,670 id=90 4,882,408 2 id=92 4,882,408 0 id=91 4,927,272 44,864 id=95 4,927,274 2 id=96 4,927,276 2 id=97 4,927,277 1 id=98 4,927,279 2 id=99 4,937,617 10,338 id=7 4,951,899 14,282 id=15 4,955,112 3,213 start_kernel Accumulated time: 6,948 SPI read Uncompressing Linux... done, booting the kernel. [0.00] Booting Linux on physical CPU 0x0 [0.00] Linux version 4.6.0-00073-g35e691c (pankaj@chromebld-server) (gcc version 4.9.2 20140904 (prerelease) (crosstool-NG
[PATCH] fs: Do not check for valid page->mapping in page_cache_pipe_buf_confirm
If the page is truncated after being spliced into the pipe, it's probably not invalid. For filesystems that invalidate pages, we used to return -ENODATA even though the data is there, it's just possibly different from what was spliced into the pipe. We shouldn't have to throw away the buffer or return error in this case. Signed-off-by: Abhi DasCC: Miklos Szeredi CC: Jens Axboe CC: Al Viro --- fs/splice.c | 9 - 1 file changed, 9 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index dd9bf7e..b9899b99 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -106,15 +106,6 @@ static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe, lock_page(page); /* -* Page got truncated/unhashed. This will cause a 0-byte -* splice, if this is the first page. -*/ - if (!page->mapping) { - err = -ENODATA; - goto error; - } - - /* * Uh oh, read-error from disk. */ if (!PageUptodate(page)) { -- 2.4.3
[PATCH] fs: Do not check for valid page->mapping in page_cache_pipe_buf_confirm
If the page is truncated after being spliced into the pipe, it's probably not invalid. For filesystems that invalidate pages, we used to return -ENODATA even though the data is there, it's just possibly different from what was spliced into the pipe. We shouldn't have to throw away the buffer or return error in this case. Signed-off-by: Abhi Das CC: Miklos Szeredi CC: Jens Axboe CC: Al Viro --- fs/splice.c | 9 - 1 file changed, 9 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index dd9bf7e..b9899b99 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -106,15 +106,6 @@ static int page_cache_pipe_buf_confirm(struct pipe_inode_info *pipe, lock_page(page); /* -* Page got truncated/unhashed. This will cause a 0-byte -* splice, if this is the first page. -*/ - if (!page->mapping) { - err = -ENODATA; - goto error; - } - - /* * Uh oh, read-error from disk. */ if (!PageUptodate(page)) { -- 2.4.3
Re: [PATCH 1/2] Revert "mtd: atmel_nand: Support variable RB_EDGE interrupts"
Hi, On Mon, May 09, 2016 at 02:51:18PM +0800, Wenyou Yang wrote: > This reverts commit 5ddc7bd43ccc ("mtd: atmel_nand: Support variable > RB_EDGE interrupts") > > Because for current SoCs, the RB_EDGE3(i.e. bit 27) of HSMC_SR > register does not exist, the RB_EDGE0 (i.e. bit 24) is the ready/busy > line edge status bit. It is a datasheet bug. > > Signed-off-by: Wenyou Yang> --- > > .../devicetree/bindings/mtd/atmel-nand.txt | 2 +- > drivers/mtd/nand/atmel_nand.c | 35 > +- > drivers/mtd/nand/atmel_nand_nfc.h | 3 +- > 3 files changed, 10 insertions(+), 30 deletions(-) > > diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt > b/Documentation/devicetree/bindings/mtd/atmel-nand.txt > index d53aba9..3e7ee99 100644 > --- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt > +++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt > @@ -39,7 +39,7 @@ Optional properties: > > Nand Flash Controller(NFC) is an optional sub-node > Required properties: > -- compatible : "atmel,sama5d3-nfc" or "atmel,sama5d4-nfc". > +- compatible : "atmel,sama5d3-nfc". > - reg : should specify the address and size used for NFC command registers, > NFC registers and NFC SRAM. NFC SRAM address and size can be absent > if don't want to use it. > diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c > index efc8ea2..68b9160 100644 > --- a/drivers/mtd/nand/atmel_nand.c > +++ b/drivers/mtd/nand/atmel_nand.c [...] > static const struct of_device_id atmel_nand_nfc_match[] = { > - { .compatible = "atmel,sama5d3-nfc", .data = _nfc_caps }, > - { .compatible = "atmel,sama5d4-nfc", .data = _nfc_caps }, > + { .compatible = "atmel,sama5d3-nfc" }, Hmm, wait. Didn't Rob and Alexandre suggest that we should *not* drop the compatible property? We could have easily supported both here, and just not listed any different capabilities. But I see that Nicholas took the patch anyway, so I guess it's not a big deal... > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, atmel_nand_nfc_match); Brian
Re: [PATCH 1/2] Revert "mtd: atmel_nand: Support variable RB_EDGE interrupts"
Hi, On Mon, May 09, 2016 at 02:51:18PM +0800, Wenyou Yang wrote: > This reverts commit 5ddc7bd43ccc ("mtd: atmel_nand: Support variable > RB_EDGE interrupts") > > Because for current SoCs, the RB_EDGE3(i.e. bit 27) of HSMC_SR > register does not exist, the RB_EDGE0 (i.e. bit 24) is the ready/busy > line edge status bit. It is a datasheet bug. > > Signed-off-by: Wenyou Yang > --- > > .../devicetree/bindings/mtd/atmel-nand.txt | 2 +- > drivers/mtd/nand/atmel_nand.c | 35 > +- > drivers/mtd/nand/atmel_nand_nfc.h | 3 +- > 3 files changed, 10 insertions(+), 30 deletions(-) > > diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt > b/Documentation/devicetree/bindings/mtd/atmel-nand.txt > index d53aba9..3e7ee99 100644 > --- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt > +++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt > @@ -39,7 +39,7 @@ Optional properties: > > Nand Flash Controller(NFC) is an optional sub-node > Required properties: > -- compatible : "atmel,sama5d3-nfc" or "atmel,sama5d4-nfc". > +- compatible : "atmel,sama5d3-nfc". > - reg : should specify the address and size used for NFC command registers, > NFC registers and NFC SRAM. NFC SRAM address and size can be absent > if don't want to use it. > diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c > index efc8ea2..68b9160 100644 > --- a/drivers/mtd/nand/atmel_nand.c > +++ b/drivers/mtd/nand/atmel_nand.c [...] > static const struct of_device_id atmel_nand_nfc_match[] = { > - { .compatible = "atmel,sama5d3-nfc", .data = _nfc_caps }, > - { .compatible = "atmel,sama5d4-nfc", .data = _nfc_caps }, > + { .compatible = "atmel,sama5d3-nfc" }, Hmm, wait. Didn't Rob and Alexandre suggest that we should *not* drop the compatible property? We could have easily supported both here, and just not listed any different capabilities. But I see that Nicholas took the patch anyway, so I guess it's not a big deal... > { /* sentinel */ } > }; > MODULE_DEVICE_TABLE(of, atmel_nand_nfc_match); Brian
Re: [PATCH 1/2] Revert "mtd: atmel_nand: Support variable RB_EDGE interrupts"
Hi, On Mon, May 23, 2016 at 09:55:57AM +0200, Boris Brezillon wrote: > On Mon, 9 May 2016 14:51:18 +0800 > Wenyou Yangwrote: > > > This reverts commit 5ddc7bd43ccc ("mtd: atmel_nand: Support variable > > RB_EDGE interrupts") > > > > Because for current SoCs, the RB_EDGE3(i.e. bit 27) of HSMC_SR > > register does not exist, the RB_EDGE0 (i.e. bit 24) is the ready/busy > > line edge status bit. It is a datasheet bug. > > > > Signed-off-by: Wenyou Yang > > Wenyou, I know you sent it before v4.6 was released, but now we should > probably add Sorry for the delay... > Cc: Added that and a Fixes: tag. > Brian, can you apply this patch directly in your tree (as previously > discussed, I'm not sure creating a nand/fixes branch is really useful)? Pushed to linux-mtd.git. I'll probably send it to Linus in the next day or two. Brian
Re: [PATCH 1/2] Revert "mtd: atmel_nand: Support variable RB_EDGE interrupts"
Hi, On Mon, May 23, 2016 at 09:55:57AM +0200, Boris Brezillon wrote: > On Mon, 9 May 2016 14:51:18 +0800 > Wenyou Yang wrote: > > > This reverts commit 5ddc7bd43ccc ("mtd: atmel_nand: Support variable > > RB_EDGE interrupts") > > > > Because for current SoCs, the RB_EDGE3(i.e. bit 27) of HSMC_SR > > register does not exist, the RB_EDGE0 (i.e. bit 24) is the ready/busy > > line edge status bit. It is a datasheet bug. > > > > Signed-off-by: Wenyou Yang > > Wenyou, I know you sent it before v4.6 was released, but now we should > probably add Sorry for the delay... > Cc: Added that and a Fixes: tag. > Brian, can you apply this patch directly in your tree (as previously > discussed, I'm not sure creating a nand/fixes branch is really useful)? Pushed to linux-mtd.git. I'll probably send it to Linus in the next day or two. Brian
[RFC PATCH 1/2] mmc: dw_mmc: remove redundant of set_bit and clear_bit
dw_mci_get_cd have already dealed with these for both of internal card-detect and gpio card-detect. Signed-off-by: Shawn Lin--- drivers/mmc/host/dw_mmc.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 829a6ee..cb30e91 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2616,10 +2616,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) mmc->max_seg_size = mmc->max_req_size; } - if (dw_mci_get_cd(mmc)) - set_bit(DW_MMC_CARD_PRESENT, >flags); - else - clear_bit(DW_MMC_CARD_PRESENT, >flags); + dw_mci_get_cd(mmc); ret = mmc_add_host(mmc); if (ret) -- 2.3.7
[RFC PATCH 2/2] mmc: dw_mmc: check card present before starting request
The main reason to add this check is to avoid unnecessary mmc_request if the card is removed. Although we have already check this in dw_mci_handle_cd for runtime usage of sd card and dw_mci_init_slot for noremovable devices, but there is a timing gap before it really calls dw_mci_get_cd as mmc_detect_change needs some delay here. Another gain here is that we could save some checkings of card status after sd card been removed. Signed-off-by: Shawn Lin--- drivers/mmc/host/dw_mmc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index cb30e91..2940d24 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -105,6 +105,7 @@ struct idmac_desc { static bool dw_mci_reset(struct dw_mci *host); static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset); static int dw_mci_card_busy(struct mmc_host *mmc); +static int dw_mci_get_cd(struct mmc_host *mmc); #if defined(CONFIG_DEBUG_FS) static int dw_mci_req_show(struct seq_file *s, void *v) @@ -1248,6 +1249,8 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) WARN_ON(slot->mrq); + dw_mci_get_cd(mmc); + /* * The check for card presence and queueing of the request must be * atomic, otherwise the card could be removed in between and the -- 2.3.7
[RFC PATCH 1/2] mmc: dw_mmc: remove redundant of set_bit and clear_bit
dw_mci_get_cd have already dealed with these for both of internal card-detect and gpio card-detect. Signed-off-by: Shawn Lin --- drivers/mmc/host/dw_mmc.c | 5 + 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 829a6ee..cb30e91 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2616,10 +2616,7 @@ static int dw_mci_init_slot(struct dw_mci *host, unsigned int id) mmc->max_seg_size = mmc->max_req_size; } - if (dw_mci_get_cd(mmc)) - set_bit(DW_MMC_CARD_PRESENT, >flags); - else - clear_bit(DW_MMC_CARD_PRESENT, >flags); + dw_mci_get_cd(mmc); ret = mmc_add_host(mmc); if (ret) -- 2.3.7
[RFC PATCH 2/2] mmc: dw_mmc: check card present before starting request
The main reason to add this check is to avoid unnecessary mmc_request if the card is removed. Although we have already check this in dw_mci_handle_cd for runtime usage of sd card and dw_mci_init_slot for noremovable devices, but there is a timing gap before it really calls dw_mci_get_cd as mmc_detect_change needs some delay here. Another gain here is that we could save some checkings of card status after sd card been removed. Signed-off-by: Shawn Lin --- drivers/mmc/host/dw_mmc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index cb30e91..2940d24 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -105,6 +105,7 @@ struct idmac_desc { static bool dw_mci_reset(struct dw_mci *host); static bool dw_mci_ctrl_reset(struct dw_mci *host, u32 reset); static int dw_mci_card_busy(struct mmc_host *mmc); +static int dw_mci_get_cd(struct mmc_host *mmc); #if defined(CONFIG_DEBUG_FS) static int dw_mci_req_show(struct seq_file *s, void *v) @@ -1248,6 +1249,8 @@ static void dw_mci_request(struct mmc_host *mmc, struct mmc_request *mrq) WARN_ON(slot->mrq); + dw_mci_get_cd(mmc); + /* * The check for card presence and queueing of the request must be * atomic, otherwise the card could be removed in between and the -- 2.3.7
[PATCH v2 1/3] cpufreq: add resolve_freq driver callback
Cpufreq governors may need to know what a particular target frequency maps to in the driver without necessarily wanting to set the frequency. Support this operation via a new cpufreq API, cpufreq_driver_resolve_freq(). The above API will call a new cpufreq driver callback, resolve_freq(), if it has been registered by the driver. If that callback has not been registered and a frequency table is available then the frequency table is walked using cpufreq_frequency_table_target(). UINT_MAX is returned if no driver callback or frequency table is available. Suggested-by: Rafael J. WysockiSigned-off-by: Steve Muckle --- drivers/cpufreq/cpufreq.c | 25 + include/linux/cpufreq.h | 11 +++ 2 files changed, 36 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 77d77a4e3b74..3b44f4bdc071 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1849,6 +1849,31 @@ unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy, } EXPORT_SYMBOL_GPL(cpufreq_driver_fast_switch); +unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, +unsigned int target_freq) +{ + struct cpufreq_frequency_table *freq_table; + int index, retval; + + clamp_val(target_freq, policy->min, policy->max); + + if (cpufreq_driver->resolve_freq) + return cpufreq_driver->resolve_freq(policy, target_freq); + + freq_table = cpufreq_frequency_get_table(policy->cpu); + if (!freq_table) + return UINT_MAX; + + retval = cpufreq_frequency_table_target(policy, freq_table, + target_freq, CPUFREQ_RELATION_L, + ); + if (retval) + return UINT_MAX; + + return freq_table[index].frequency; +} +EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq); + /* Must set freqs->new to intermediate frequency */ static int __target_intermediate(struct cpufreq_policy *policy, struct cpufreq_freqs *freqs, int index) diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 4e81e08db752..675f17f98e75 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -271,6 +271,13 @@ struct cpufreq_driver { int (*target_intermediate)(struct cpufreq_policy *policy, unsigned int index); + /* +* Return the driver-supported frequency that a particular target +* frequency maps to (does not set the new frequency). +*/ + unsigned int(*resolve_freq)(struct cpufreq_policy *policy, + unsigned int target_freq); + /* should be defined, if possible */ unsigned int(*get)(unsigned int cpu); @@ -487,6 +494,10 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation); + +unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, +unsigned int target_freq); + int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); -- 2.4.10
[PATCH v2 1/3] cpufreq: add resolve_freq driver callback
Cpufreq governors may need to know what a particular target frequency maps to in the driver without necessarily wanting to set the frequency. Support this operation via a new cpufreq API, cpufreq_driver_resolve_freq(). The above API will call a new cpufreq driver callback, resolve_freq(), if it has been registered by the driver. If that callback has not been registered and a frequency table is available then the frequency table is walked using cpufreq_frequency_table_target(). UINT_MAX is returned if no driver callback or frequency table is available. Suggested-by: Rafael J. Wysocki Signed-off-by: Steve Muckle --- drivers/cpufreq/cpufreq.c | 25 + include/linux/cpufreq.h | 11 +++ 2 files changed, 36 insertions(+) diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 77d77a4e3b74..3b44f4bdc071 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1849,6 +1849,31 @@ unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy, } EXPORT_SYMBOL_GPL(cpufreq_driver_fast_switch); +unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, +unsigned int target_freq) +{ + struct cpufreq_frequency_table *freq_table; + int index, retval; + + clamp_val(target_freq, policy->min, policy->max); + + if (cpufreq_driver->resolve_freq) + return cpufreq_driver->resolve_freq(policy, target_freq); + + freq_table = cpufreq_frequency_get_table(policy->cpu); + if (!freq_table) + return UINT_MAX; + + retval = cpufreq_frequency_table_target(policy, freq_table, + target_freq, CPUFREQ_RELATION_L, + ); + if (retval) + return UINT_MAX; + + return freq_table[index].frequency; +} +EXPORT_SYMBOL_GPL(cpufreq_driver_resolve_freq); + /* Must set freqs->new to intermediate frequency */ static int __target_intermediate(struct cpufreq_policy *policy, struct cpufreq_freqs *freqs, int index) diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 4e81e08db752..675f17f98e75 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -271,6 +271,13 @@ struct cpufreq_driver { int (*target_intermediate)(struct cpufreq_policy *policy, unsigned int index); + /* +* Return the driver-supported frequency that a particular target +* frequency maps to (does not set the new frequency). +*/ + unsigned int(*resolve_freq)(struct cpufreq_policy *policy, + unsigned int target_freq); + /* should be defined, if possible */ unsigned int(*get)(unsigned int cpu); @@ -487,6 +494,10 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation); + +unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy, +unsigned int target_freq); + int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); -- 2.4.10
[PATCH v2 0/3] cpufreq: avoid redundant driver calls in schedutil
In the series [0] I included a patch which attempted to avoid redundant driver calls in the schedutil governor by mapping the raw required CPU frequencies to driver frequencies. This vastly increases the likelihood of detecting a redundant cpufreq driver call, i.e. one which will end up attempting to set the CPU frequency to the frequency it is already running at. The redundant call can be avoided. This is especially valuable in the case of drivers which do not support fast path updates or if remote CPU cpufreq callbacks are implemented. Unfortunately the implementation of this in [0] walked the frequency table directly in schedutil. Rafael pointed out that not all drivers may have a frequency table and that a driver callback might be implemented to return the driver frequency associated with a particular target frequency. The driver could then also cache this lookup and possibly use it on an ensuing fast_switch. This series implements that approach. Given that this change is beneficial on its own I've split it out into its own series from the remote callback support. [0] https://lkml.org/lkml/2016/5/9/853 Steve Muckle (3): cpufreq: add resolve_freq driver callback cpufreq: acpi-cpufreq: add resolve_freq callback cpufreq: schedutil: map raw required frequency to driver frequency drivers/cpufreq/acpi-cpufreq.c | 56 ++-- drivers/cpufreq/cpufreq.c| 25 ++ include/linux/cpufreq.h | 11 kernel/sched/cpufreq_schedutil.c | 30 +++-- 4 files changed, 101 insertions(+), 21 deletions(-) -- 2.4.10
[PATCH v2 2/3] cpufreq: acpi-cpufreq: add resolve_freq callback
Support the new resolve_freq cpufreq callback which resolves a target frequency to a driver-supported frequency without actually setting it. The target frequency and resolved frequency table entry are cached so that a subsequent fast_switch operation may avoid the frequency table walk assuming the requested target frequency is the same. Suggested-by: Rafael J. WysockiSigned-off-by: Steve Muckle --- drivers/cpufreq/acpi-cpufreq.c | 56 -- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 7f38fb55f223..d87962eda1ed 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -66,6 +66,8 @@ enum { struct acpi_cpufreq_data { struct cpufreq_frequency_table *freq_table; + unsigned int cached_lookup_freq; + struct cpufreq_frequency_table *cached_lookup_entry; unsigned int resume; unsigned int cpu_feature; unsigned int acpi_perf_cpu; @@ -458,26 +460,53 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, return result; } -unsigned int acpi_cpufreq_fast_switch(struct cpufreq_policy *policy, - unsigned int target_freq) +/* + * Find the closest frequency above target_freq. + * + * The table is sorted in the reverse order with respect to the + * frequency and all of the entries are valid (see the initialization). + */ +static inline struct cpufreq_frequency_table +*lookup_freq(struct cpufreq_frequency_table *table, unsigned int target_freq) { - struct acpi_cpufreq_data *data = policy->driver_data; - struct acpi_processor_performance *perf; - struct cpufreq_frequency_table *entry; - unsigned int next_perf_state, next_freq, freq; + struct cpufreq_frequency_table *entry = table; + unsigned int freq; - /* -* Find the closest frequency above target_freq. -* -* The table is sorted in the reverse order with respect to the -* frequency and all of the entries are valid (see the initialization). -*/ - entry = data->freq_table; do { entry++; freq = entry->frequency; } while (freq >= target_freq && freq != CPUFREQ_TABLE_END); entry--; + + return entry; +} + +unsigned int acpi_cpufreq_resolve_freq(struct cpufreq_policy *policy, + unsigned int target_freq) +{ + struct acpi_cpufreq_data *data = policy->driver_data; + struct cpufreq_frequency_table *entry; + + data->cached_lookup_freq = target_freq; + entry = lookup_freq(data->freq_table, target_freq); + data->cached_lookup_entry = entry; + + return entry->frequency; +} + +unsigned int acpi_cpufreq_fast_switch(struct cpufreq_policy *policy, + unsigned int target_freq) +{ + struct acpi_cpufreq_data *data = policy->driver_data; + struct acpi_processor_performance *perf; + struct cpufreq_frequency_table *entry; + unsigned int next_perf_state, next_freq; + + if (data->cached_lookup_entry && + data->cached_lookup_freq == target_freq) + entry = data->cached_lookup_entry; + else + entry = lookup_freq(data->freq_table, target_freq); next_freq = entry->frequency; next_perf_state = entry->driver_data; @@ -918,6 +947,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = acpi_cpufreq_target, .fast_switch= acpi_cpufreq_fast_switch, + .resolve_freq = acpi_cpufreq_resolve_freq, .bios_limit = acpi_processor_get_bios_limit, .init = acpi_cpufreq_cpu_init, .exit = acpi_cpufreq_cpu_exit, -- 2.4.10
[PATCH v2 3/3] cpufreq: schedutil: map raw required frequency to driver frequency
The slow-path frequency transition path is relatively expensive as it requires waking up a thread to do work. Should support be added for remote CPU cpufreq updates that is also expensive since it requires an IPI. These activities should be avoided if they are not necessary. To that end, calculate the actual driver-supported frequency required by the new utilization value in schedutil by using the recently added cpufreq_driver_resolve_freq callback. If it is the same as the previously requested driver frequency then there is no need to continue with the update assuming the cpu frequency limits have not changed. This will have additional benefits should the semantics of the rate limit be changed to apply solely to frequency transitions rather than to frequency calculations in schedutil. The last raw required frequency is cached. This allows the driver frequency lookup to be skipped in the event that the new raw required frequency matches the last one, assuming a frequency update has not been forced due to limits changing (indicated by a next_freq value of UINT_MAX, see sugov_should_update_freq). Signed-off-by: Steve Muckle--- kernel/sched/cpufreq_schedutil.c | 30 ++ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 154ae3a51e86..ef73ca4d8d78 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -45,6 +45,8 @@ struct sugov_cpu { struct update_util_data update_util; struct sugov_policy *sg_policy; + unsigned int cached_raw_freq; + /* The fields below are only needed when sharing a policy. */ unsigned long util; unsigned long max; @@ -104,7 +106,7 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time, /** * get_next_freq - Compute a new frequency for a given cpufreq policy. - * @policy: cpufreq policy object to compute the new frequency for. + * @sg_cpu: schedutil cpu object to compute the new frequency for. * @util: Current CPU utilization. * @max: CPU capacity. * @@ -119,14 +121,24 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time, * next_freq = C * curr_freq * util_raw / max * * Take C = 1.25 for the frequency tipping point at (util / max) = 0.8. + * + * The lowest driver-supported frequency which is equal or greater than the raw + * next_freq (as calculated above) is returned. */ -static unsigned int get_next_freq(struct cpufreq_policy *policy, - unsigned long util, unsigned long max) +static unsigned int get_next_freq(struct sugov_cpu *sg_cpu, unsigned long util, + unsigned long max) { + struct sugov_policy *sg_policy = sg_cpu->sg_policy; + struct cpufreq_policy *policy = sg_policy->policy; unsigned int freq = arch_scale_freq_invariant() ? policy->cpuinfo.max_freq : policy->cur; - return (freq + (freq >> 2)) * util / max; + freq = (freq + (freq >> 2)) * util / max; + + if (freq == sg_cpu->cached_raw_freq && sg_policy->next_freq != UINT_MAX) + return sg_policy->next_freq; + sg_cpu->cached_raw_freq = freq; + return cpufreq_driver_resolve_freq(policy, freq); } static void sugov_update_single(struct update_util_data *hook, u64 time, @@ -141,13 +153,14 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, return; next_f = util == ULONG_MAX ? policy->cpuinfo.max_freq : - get_next_freq(policy, util, max); + get_next_freq(sg_cpu, util, max); sugov_update_commit(sg_policy, time, next_f); } -static unsigned int sugov_next_freq_shared(struct sugov_policy *sg_policy, +static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, unsigned long util, unsigned long max) { + struct sugov_policy *sg_policy = sg_cpu->sg_policy; struct cpufreq_policy *policy = sg_policy->policy; unsigned int max_f = policy->cpuinfo.max_freq; u64 last_freq_update_time = sg_policy->last_freq_update_time; @@ -187,7 +200,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_policy *sg_policy, } } - return get_next_freq(policy, util, max); + return get_next_freq(sg_cpu, util, max); } static void sugov_update_shared(struct update_util_data *hook, u64 time, @@ -204,7 +217,7 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time, sg_cpu->last_update = time; if (sugov_should_update_freq(sg_policy, time)) { - next_f = sugov_next_freq_shared(sg_policy, util, max); + next_f = sugov_next_freq_shared(sg_cpu, util, max); sugov_update_commit(sg_policy, time, next_f); } @@ -432,6
[PATCH v2 0/3] cpufreq: avoid redundant driver calls in schedutil
In the series [0] I included a patch which attempted to avoid redundant driver calls in the schedutil governor by mapping the raw required CPU frequencies to driver frequencies. This vastly increases the likelihood of detecting a redundant cpufreq driver call, i.e. one which will end up attempting to set the CPU frequency to the frequency it is already running at. The redundant call can be avoided. This is especially valuable in the case of drivers which do not support fast path updates or if remote CPU cpufreq callbacks are implemented. Unfortunately the implementation of this in [0] walked the frequency table directly in schedutil. Rafael pointed out that not all drivers may have a frequency table and that a driver callback might be implemented to return the driver frequency associated with a particular target frequency. The driver could then also cache this lookup and possibly use it on an ensuing fast_switch. This series implements that approach. Given that this change is beneficial on its own I've split it out into its own series from the remote callback support. [0] https://lkml.org/lkml/2016/5/9/853 Steve Muckle (3): cpufreq: add resolve_freq driver callback cpufreq: acpi-cpufreq: add resolve_freq callback cpufreq: schedutil: map raw required frequency to driver frequency drivers/cpufreq/acpi-cpufreq.c | 56 ++-- drivers/cpufreq/cpufreq.c| 25 ++ include/linux/cpufreq.h | 11 kernel/sched/cpufreq_schedutil.c | 30 +++-- 4 files changed, 101 insertions(+), 21 deletions(-) -- 2.4.10
[PATCH v2 2/3] cpufreq: acpi-cpufreq: add resolve_freq callback
Support the new resolve_freq cpufreq callback which resolves a target frequency to a driver-supported frequency without actually setting it. The target frequency and resolved frequency table entry are cached so that a subsequent fast_switch operation may avoid the frequency table walk assuming the requested target frequency is the same. Suggested-by: Rafael J. Wysocki Signed-off-by: Steve Muckle --- drivers/cpufreq/acpi-cpufreq.c | 56 -- 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 7f38fb55f223..d87962eda1ed 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -66,6 +66,8 @@ enum { struct acpi_cpufreq_data { struct cpufreq_frequency_table *freq_table; + unsigned int cached_lookup_freq; + struct cpufreq_frequency_table *cached_lookup_entry; unsigned int resume; unsigned int cpu_feature; unsigned int acpi_perf_cpu; @@ -458,26 +460,53 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, return result; } -unsigned int acpi_cpufreq_fast_switch(struct cpufreq_policy *policy, - unsigned int target_freq) +/* + * Find the closest frequency above target_freq. + * + * The table is sorted in the reverse order with respect to the + * frequency and all of the entries are valid (see the initialization). + */ +static inline struct cpufreq_frequency_table +*lookup_freq(struct cpufreq_frequency_table *table, unsigned int target_freq) { - struct acpi_cpufreq_data *data = policy->driver_data; - struct acpi_processor_performance *perf; - struct cpufreq_frequency_table *entry; - unsigned int next_perf_state, next_freq, freq; + struct cpufreq_frequency_table *entry = table; + unsigned int freq; - /* -* Find the closest frequency above target_freq. -* -* The table is sorted in the reverse order with respect to the -* frequency and all of the entries are valid (see the initialization). -*/ - entry = data->freq_table; do { entry++; freq = entry->frequency; } while (freq >= target_freq && freq != CPUFREQ_TABLE_END); entry--; + + return entry; +} + +unsigned int acpi_cpufreq_resolve_freq(struct cpufreq_policy *policy, + unsigned int target_freq) +{ + struct acpi_cpufreq_data *data = policy->driver_data; + struct cpufreq_frequency_table *entry; + + data->cached_lookup_freq = target_freq; + entry = lookup_freq(data->freq_table, target_freq); + data->cached_lookup_entry = entry; + + return entry->frequency; +} + +unsigned int acpi_cpufreq_fast_switch(struct cpufreq_policy *policy, + unsigned int target_freq) +{ + struct acpi_cpufreq_data *data = policy->driver_data; + struct acpi_processor_performance *perf; + struct cpufreq_frequency_table *entry; + unsigned int next_perf_state, next_freq; + + if (data->cached_lookup_entry && + data->cached_lookup_freq == target_freq) + entry = data->cached_lookup_entry; + else + entry = lookup_freq(data->freq_table, target_freq); next_freq = entry->frequency; next_perf_state = entry->driver_data; @@ -918,6 +947,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = { .verify = cpufreq_generic_frequency_table_verify, .target_index = acpi_cpufreq_target, .fast_switch= acpi_cpufreq_fast_switch, + .resolve_freq = acpi_cpufreq_resolve_freq, .bios_limit = acpi_processor_get_bios_limit, .init = acpi_cpufreq_cpu_init, .exit = acpi_cpufreq_cpu_exit, -- 2.4.10
[PATCH v2 3/3] cpufreq: schedutil: map raw required frequency to driver frequency
The slow-path frequency transition path is relatively expensive as it requires waking up a thread to do work. Should support be added for remote CPU cpufreq updates that is also expensive since it requires an IPI. These activities should be avoided if they are not necessary. To that end, calculate the actual driver-supported frequency required by the new utilization value in schedutil by using the recently added cpufreq_driver_resolve_freq callback. If it is the same as the previously requested driver frequency then there is no need to continue with the update assuming the cpu frequency limits have not changed. This will have additional benefits should the semantics of the rate limit be changed to apply solely to frequency transitions rather than to frequency calculations in schedutil. The last raw required frequency is cached. This allows the driver frequency lookup to be skipped in the event that the new raw required frequency matches the last one, assuming a frequency update has not been forced due to limits changing (indicated by a next_freq value of UINT_MAX, see sugov_should_update_freq). Signed-off-by: Steve Muckle --- kernel/sched/cpufreq_schedutil.c | 30 ++ 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 154ae3a51e86..ef73ca4d8d78 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -45,6 +45,8 @@ struct sugov_cpu { struct update_util_data update_util; struct sugov_policy *sg_policy; + unsigned int cached_raw_freq; + /* The fields below are only needed when sharing a policy. */ unsigned long util; unsigned long max; @@ -104,7 +106,7 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time, /** * get_next_freq - Compute a new frequency for a given cpufreq policy. - * @policy: cpufreq policy object to compute the new frequency for. + * @sg_cpu: schedutil cpu object to compute the new frequency for. * @util: Current CPU utilization. * @max: CPU capacity. * @@ -119,14 +121,24 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time, * next_freq = C * curr_freq * util_raw / max * * Take C = 1.25 for the frequency tipping point at (util / max) = 0.8. + * + * The lowest driver-supported frequency which is equal or greater than the raw + * next_freq (as calculated above) is returned. */ -static unsigned int get_next_freq(struct cpufreq_policy *policy, - unsigned long util, unsigned long max) +static unsigned int get_next_freq(struct sugov_cpu *sg_cpu, unsigned long util, + unsigned long max) { + struct sugov_policy *sg_policy = sg_cpu->sg_policy; + struct cpufreq_policy *policy = sg_policy->policy; unsigned int freq = arch_scale_freq_invariant() ? policy->cpuinfo.max_freq : policy->cur; - return (freq + (freq >> 2)) * util / max; + freq = (freq + (freq >> 2)) * util / max; + + if (freq == sg_cpu->cached_raw_freq && sg_policy->next_freq != UINT_MAX) + return sg_policy->next_freq; + sg_cpu->cached_raw_freq = freq; + return cpufreq_driver_resolve_freq(policy, freq); } static void sugov_update_single(struct update_util_data *hook, u64 time, @@ -141,13 +153,14 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, return; next_f = util == ULONG_MAX ? policy->cpuinfo.max_freq : - get_next_freq(policy, util, max); + get_next_freq(sg_cpu, util, max); sugov_update_commit(sg_policy, time, next_f); } -static unsigned int sugov_next_freq_shared(struct sugov_policy *sg_policy, +static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, unsigned long util, unsigned long max) { + struct sugov_policy *sg_policy = sg_cpu->sg_policy; struct cpufreq_policy *policy = sg_policy->policy; unsigned int max_f = policy->cpuinfo.max_freq; u64 last_freq_update_time = sg_policy->last_freq_update_time; @@ -187,7 +200,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_policy *sg_policy, } } - return get_next_freq(policy, util, max); + return get_next_freq(sg_cpu, util, max); } static void sugov_update_shared(struct update_util_data *hook, u64 time, @@ -204,7 +217,7 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time, sg_cpu->last_update = time; if (sugov_should_update_freq(sg_policy, time)) { - next_f = sugov_next_freq_shared(sg_policy, util, max); + next_f = sugov_next_freq_shared(sg_cpu, util, max); sugov_update_commit(sg_policy, time, next_f); } @@ -432,6 +445,7 @@ static int
[PATCH 1/3] of/numa: remove a duplicated pr_debug information
This information will be printed in the subfunction numa_add_memblk. They are not the same, but very similar. Signed-off-by: Zhen Lei--- drivers/of/of_numa.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index 0f2784b..21d831f 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c @@ -88,9 +88,6 @@ static int __init of_numa_parse_memory_nodes(void) break; } - pr_debug("NUMA: base = %llx len = %llx, node = %u\n", -rsrc.start, rsrc.end - rsrc.start + 1, nid); - r = numa_add_memblk(nid, rsrc.start, rsrc.end - rsrc.start + 1); if (r) -- 2.5.0
[PATCH 1/3] of/numa: remove a duplicated pr_debug information
This information will be printed in the subfunction numa_add_memblk. They are not the same, but very similar. Signed-off-by: Zhen Lei --- drivers/of/of_numa.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index 0f2784b..21d831f 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c @@ -88,9 +88,6 @@ static int __init of_numa_parse_memory_nodes(void) break; } - pr_debug("NUMA: base = %llx len = %llx, node = %u\n", -rsrc.start, rsrc.end - rsrc.start + 1, nid); - r = numa_add_memblk(nid, rsrc.start, rsrc.end - rsrc.start + 1); if (r) -- 2.5.0
[PATCH 3/3] arm64/numa: fix type info
numa_init(of_numa_init) may returned error because of numa configuration error. So "No NUMA configuration found" is inaccurate. In fact, specific configuration error information can be immediately printed by the testing branch. So "No NUMA..." only needs to be printed when numa_off. Signed-off-by: Zhen Lei--- arch/arm64/mm/numa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c index 98dc104..9937cc1 100644 --- a/arch/arm64/mm/numa.c +++ b/arch/arm64/mm/numa.c @@ -362,7 +362,8 @@ static int __init dummy_numa_init(void) int ret; struct memblock_region *mblk; - pr_info("%s\n", "No NUMA configuration found"); + if (numa_off) + pr_info("%s\n", "No NUMA configuration found"); pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n", 0LLU, PFN_PHYS(max_pfn) - 1); -- 2.5.0
[PATCH 2/3] of/numa: fix a memory@ dt node can only contains one memory block
For a normal memory@ devicetree node, its reg property can contains more memory blocks. Because we don't known how many memory blocks maybe contained, so we try from index=0, increase 1 until error returned(the end). Signed-off-by: Zhen Lei--- drivers/of/of_numa.c | 30 -- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index 21d831f..2c5f249 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c @@ -63,7 +63,7 @@ static int __init of_numa_parse_memory_nodes(void) struct device_node *np = NULL; struct resource rsrc; u32 nid; - int r = 0; + int i, r = 0; for (;;) { np = of_find_node_by_type(np, "memory"); @@ -82,17 +82,27 @@ static int __init of_numa_parse_memory_nodes(void) /* some other error */ break; - r = of_address_to_resource(np, 0, ); - if (r) { - pr_err("NUMA: bad reg property in memory node\n"); - break; + for (i = 0; ; i++) { + r = of_address_to_resource(np, i, ); + if (r) { + /* reached the end of of_address */ + if (i > 0) { + r = 0; + break; + } + + pr_err("NUMA: bad reg property in memory node\n"); + goto finished; + } + + r = numa_add_memblk(nid, rsrc.start, + rsrc.end - rsrc.start + 1); + if (r) + goto finished; } - - r = numa_add_memblk(nid, rsrc.start, - rsrc.end - rsrc.start + 1); - if (r) - break; } + +finished: of_node_put(np); return r; -- 2.5.0
[PATCH 3/3] arm64/numa: fix type info
numa_init(of_numa_init) may returned error because of numa configuration error. So "No NUMA configuration found" is inaccurate. In fact, specific configuration error information can be immediately printed by the testing branch. So "No NUMA..." only needs to be printed when numa_off. Signed-off-by: Zhen Lei --- arch/arm64/mm/numa.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/mm/numa.c b/arch/arm64/mm/numa.c index 98dc104..9937cc1 100644 --- a/arch/arm64/mm/numa.c +++ b/arch/arm64/mm/numa.c @@ -362,7 +362,8 @@ static int __init dummy_numa_init(void) int ret; struct memblock_region *mblk; - pr_info("%s\n", "No NUMA configuration found"); + if (numa_off) + pr_info("%s\n", "No NUMA configuration found"); pr_info("NUMA: Faking a node at [mem %#018Lx-%#018Lx]\n", 0LLU, PFN_PHYS(max_pfn) - 1); -- 2.5.0
[PATCH 2/3] of/numa: fix a memory@ dt node can only contains one memory block
For a normal memory@ devicetree node, its reg property can contains more memory blocks. Because we don't known how many memory blocks maybe contained, so we try from index=0, increase 1 until error returned(the end). Signed-off-by: Zhen Lei --- drivers/of/of_numa.c | 30 -- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index 21d831f..2c5f249 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c @@ -63,7 +63,7 @@ static int __init of_numa_parse_memory_nodes(void) struct device_node *np = NULL; struct resource rsrc; u32 nid; - int r = 0; + int i, r = 0; for (;;) { np = of_find_node_by_type(np, "memory"); @@ -82,17 +82,27 @@ static int __init of_numa_parse_memory_nodes(void) /* some other error */ break; - r = of_address_to_resource(np, 0, ); - if (r) { - pr_err("NUMA: bad reg property in memory node\n"); - break; + for (i = 0; ; i++) { + r = of_address_to_resource(np, i, ); + if (r) { + /* reached the end of of_address */ + if (i > 0) { + r = 0; + break; + } + + pr_err("NUMA: bad reg property in memory node\n"); + goto finished; + } + + r = numa_add_memblk(nid, rsrc.start, + rsrc.end - rsrc.start + 1); + if (r) + goto finished; } - - r = numa_add_memblk(nid, rsrc.start, - rsrc.end - rsrc.start + 1); - if (r) - break; } + +finished: of_node_put(np); return r; -- 2.5.0
Re: dma-buf/sync_file: de-stage sync_file
On Sat, May 21, 2016 at 05:31:53AM +, Linux Kernel wrote: > dma-buf/sync_file: de-stage sync_file > > sync_file is useful to connect one or more fences to the file. The file > is > used by userspace to track fences between drivers that share DMA bufs. > > Signed-off-by: Gustavo Padovan> Reviewed-by: Daniel Vetter > Signed-off-by: Greg Kroah-Hartman ... > +config SYNC_FILE > +bool "sync_file support for fences" > +default n > +select ANON_INODES > +select DMA_SHARED_BUFFER > +---help--- > + This option enables the fence framework synchronization to export > + sync_files to userspace that can represent one or more fences. For such a generic sounding CONFIG_ item, this is one of the more obtuse descriptions in a kconfig we've had in a while, and the commit message doesn't give any more clues as to why anyone might want to enable this. I'm guessing this is some graphics thing given that Daniel reviewed it. >From skimming the other commits, it seems to be some Android thing ? Are there depends missing perhaps that might make this more obvious ? Could you elaborate in the help text why someone might want to enable this ? As is, it's just a bunch of words with no context for anyone who isn't close to whatever domain this came from. Dave
Re: dma-buf/sync_file: de-stage sync_file
On Sat, May 21, 2016 at 05:31:53AM +, Linux Kernel wrote: > dma-buf/sync_file: de-stage sync_file > > sync_file is useful to connect one or more fences to the file. The file > is > used by userspace to track fences between drivers that share DMA bufs. > > Signed-off-by: Gustavo Padovan > Reviewed-by: Daniel Vetter > Signed-off-by: Greg Kroah-Hartman ... > +config SYNC_FILE > +bool "sync_file support for fences" > +default n > +select ANON_INODES > +select DMA_SHARED_BUFFER > +---help--- > + This option enables the fence framework synchronization to export > + sync_files to userspace that can represent one or more fences. For such a generic sounding CONFIG_ item, this is one of the more obtuse descriptions in a kconfig we've had in a while, and the commit message doesn't give any more clues as to why anyone might want to enable this. I'm guessing this is some graphics thing given that Daniel reviewed it. >From skimming the other commits, it seems to be some Android thing ? Are there depends missing perhaps that might make this more obvious ? Could you elaborate in the help text why someone might want to enable this ? As is, it's just a bunch of words with no context for anyone who isn't close to whatever domain this came from. Dave
[PATCH v2 2/7] mm/page_owner: initialize page owner without holding the zone lock
From: Joonsoo KimIt's not necessary to initialized page_owner with holding the zone lock. It would cause more contention on the zone lock although it's not a big problem since it is just debug feature. But, it is better than before so do it. This is also preparation step to use stackdepot in page owner feature. Stackdepot allocates new pages when there is no reserved space and holding the zone lock in this case will cause deadlock. Signed-off-by: Joonsoo Kim --- mm/compaction.c | 3 +++ mm/page_alloc.c | 2 -- mm/page_isolation.c | 9 ++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mm/compaction.c b/mm/compaction.c index 8e013eb..6043ef8 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "internal.h" #ifdef CONFIG_COMPACTION @@ -80,6 +81,8 @@ static void map_pages(struct list_head *list) arch_alloc_page(page, order); kernel_map_pages(page, nr_pages, 1); kasan_alloc_pages(page, order); + + set_page_owner(page, order, __GFP_MOVABLE); if (order) split_page(page, order); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5134f46..1b1ca57 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2507,8 +2507,6 @@ int __isolate_free_page(struct page *page, unsigned int order) zone->free_area[order].nr_free--; rmv_page_order(page); - set_page_owner(page, order, __GFP_MOVABLE); - /* Set the pageblock if the isolated page is at least a pageblock */ if (order >= pageblock_order - 1) { struct page *endpage = page + (1 << order) - 1; diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 612122b..927f5ee 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "internal.h" #define CREATE_TRACE_POINTS @@ -108,8 +109,6 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype) if (pfn_valid_within(page_to_pfn(buddy)) && !is_migrate_isolate_page(buddy)) { __isolate_free_page(page, order); - kernel_map_pages(page, (1 << order), 1); - set_page_refcounted(page); isolated_page = page; } } @@ -128,8 +127,12 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype) zone->nr_isolate_pageblock--; out: spin_unlock_irqrestore(>lock, flags); - if (isolated_page) + if (isolated_page) { + kernel_map_pages(page, (1 << order), 1); + set_page_refcounted(page); + set_page_owner(page, order, __GFP_MOVABLE); __free_pages(isolated_page, order); + } } static inline struct page * -- 1.9.1
[PATCH v2 4/7] mm/page_owner: introduce split_page_owner and replace manual handling
From: Joonsoo Kimsplit_page() calls set_page_owner() to set up page_owner to each pages. But, it has a drawback that head page and the others have different stacktrace because callsite of set_page_owner() is slightly differnt. To avoid this problem, this patch copies head page's page_owner to the others. It needs to introduce new function, split_page_owner() but it also remove the other function, get_page_owner_gfp() so looks good to do. Acked-by: Vlastimil Babka Signed-off-by: Joonsoo Kim --- include/linux/page_owner.h | 12 +--- mm/page_alloc.c| 8 ++-- mm/page_owner.c| 14 +++--- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h index 46f1b93..30583ab 100644 --- a/include/linux/page_owner.h +++ b/include/linux/page_owner.h @@ -10,7 +10,7 @@ extern struct page_ext_operations page_owner_ops; extern void __reset_page_owner(struct page *page, unsigned int order); extern void __set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask); -extern gfp_t __get_page_owner_gfp(struct page *page); +extern void __split_page_owner(struct page *page, unsigned int order); extern void __copy_page_owner(struct page *oldpage, struct page *newpage); extern void __set_page_owner_migrate_reason(struct page *page, int reason); extern void __dump_page_owner(struct page *page); @@ -28,12 +28,10 @@ static inline void set_page_owner(struct page *page, __set_page_owner(page, order, gfp_mask); } -static inline gfp_t get_page_owner_gfp(struct page *page) +static inline void split_page_owner(struct page *page, unsigned int order) { if (static_branch_unlikely(_owner_inited)) - return __get_page_owner_gfp(page); - else - return 0; + __split_page_owner(page, order); } static inline void copy_page_owner(struct page *oldpage, struct page *newpage) { @@ -58,9 +56,9 @@ static inline void set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask) { } -static inline gfp_t get_page_owner_gfp(struct page *page) +static inline void split_page_owner(struct page *page, + unsigned int order) { - return 0; } static inline void copy_page_owner(struct page *oldpage, struct page *newpage) { diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1b1ca57..616ada9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2459,7 +2459,6 @@ void free_hot_cold_page_list(struct list_head *list, bool cold) void split_page(struct page *page, unsigned int order) { int i; - gfp_t gfp_mask; VM_BUG_ON_PAGE(PageCompound(page), page); VM_BUG_ON_PAGE(!page_count(page), page); @@ -2473,12 +2472,9 @@ void split_page(struct page *page, unsigned int order) split_page(virt_to_page(page[0].shadow), order); #endif - gfp_mask = get_page_owner_gfp(page); - set_page_owner(page, 0, gfp_mask); - for (i = 1; i < (1 << order); i++) { + for (i = 1; i < (1 << order); i++) set_page_refcounted(page + i); - set_page_owner(page + i, 0, gfp_mask); - } + split_page_owner(page, order); } EXPORT_SYMBOL_GPL(split_page); diff --git a/mm/page_owner.c b/mm/page_owner.c index 73e202f..499ad26 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -94,17 +94,17 @@ void __set_page_owner_migrate_reason(struct page *page, int reason) page_ext->last_migrate_reason = reason; } -gfp_t __get_page_owner_gfp(struct page *page) +void __split_page_owner(struct page *page, unsigned int order) { + int i; struct page_ext *page_ext = lookup_page_ext(page); + if (unlikely(!page_ext)) - /* -* The caller just returns 0 if no valid gfp -* So return 0 here too. -*/ - return 0; + return; - return page_ext->gfp_mask; + page_ext->order = 0; + for (i = 1; i < (1 << order); i++) + __copy_page_owner(page, page + i); } void __copy_page_owner(struct page *oldpage, struct page *newpage) -- 1.9.1
[PATCH v2 2/7] mm/page_owner: initialize page owner without holding the zone lock
From: Joonsoo Kim It's not necessary to initialized page_owner with holding the zone lock. It would cause more contention on the zone lock although it's not a big problem since it is just debug feature. But, it is better than before so do it. This is also preparation step to use stackdepot in page owner feature. Stackdepot allocates new pages when there is no reserved space and holding the zone lock in this case will cause deadlock. Signed-off-by: Joonsoo Kim --- mm/compaction.c | 3 +++ mm/page_alloc.c | 2 -- mm/page_isolation.c | 9 ++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/mm/compaction.c b/mm/compaction.c index 8e013eb..6043ef8 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "internal.h" #ifdef CONFIG_COMPACTION @@ -80,6 +81,8 @@ static void map_pages(struct list_head *list) arch_alloc_page(page, order); kernel_map_pages(page, nr_pages, 1); kasan_alloc_pages(page, order); + + set_page_owner(page, order, __GFP_MOVABLE); if (order) split_page(page, order); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 5134f46..1b1ca57 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2507,8 +2507,6 @@ int __isolate_free_page(struct page *page, unsigned int order) zone->free_area[order].nr_free--; rmv_page_order(page); - set_page_owner(page, order, __GFP_MOVABLE); - /* Set the pageblock if the isolated page is at least a pageblock */ if (order >= pageblock_order - 1) { struct page *endpage = page + (1 << order) - 1; diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 612122b..927f5ee 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "internal.h" #define CREATE_TRACE_POINTS @@ -108,8 +109,6 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype) if (pfn_valid_within(page_to_pfn(buddy)) && !is_migrate_isolate_page(buddy)) { __isolate_free_page(page, order); - kernel_map_pages(page, (1 << order), 1); - set_page_refcounted(page); isolated_page = page; } } @@ -128,8 +127,12 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype) zone->nr_isolate_pageblock--; out: spin_unlock_irqrestore(>lock, flags); - if (isolated_page) + if (isolated_page) { + kernel_map_pages(page, (1 << order), 1); + set_page_refcounted(page); + set_page_owner(page, order, __GFP_MOVABLE); __free_pages(isolated_page, order); + } } static inline struct page * -- 1.9.1
[PATCH v2 4/7] mm/page_owner: introduce split_page_owner and replace manual handling
From: Joonsoo Kim split_page() calls set_page_owner() to set up page_owner to each pages. But, it has a drawback that head page and the others have different stacktrace because callsite of set_page_owner() is slightly differnt. To avoid this problem, this patch copies head page's page_owner to the others. It needs to introduce new function, split_page_owner() but it also remove the other function, get_page_owner_gfp() so looks good to do. Acked-by: Vlastimil Babka Signed-off-by: Joonsoo Kim --- include/linux/page_owner.h | 12 +--- mm/page_alloc.c| 8 ++-- mm/page_owner.c| 14 +++--- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h index 46f1b93..30583ab 100644 --- a/include/linux/page_owner.h +++ b/include/linux/page_owner.h @@ -10,7 +10,7 @@ extern struct page_ext_operations page_owner_ops; extern void __reset_page_owner(struct page *page, unsigned int order); extern void __set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask); -extern gfp_t __get_page_owner_gfp(struct page *page); +extern void __split_page_owner(struct page *page, unsigned int order); extern void __copy_page_owner(struct page *oldpage, struct page *newpage); extern void __set_page_owner_migrate_reason(struct page *page, int reason); extern void __dump_page_owner(struct page *page); @@ -28,12 +28,10 @@ static inline void set_page_owner(struct page *page, __set_page_owner(page, order, gfp_mask); } -static inline gfp_t get_page_owner_gfp(struct page *page) +static inline void split_page_owner(struct page *page, unsigned int order) { if (static_branch_unlikely(_owner_inited)) - return __get_page_owner_gfp(page); - else - return 0; + __split_page_owner(page, order); } static inline void copy_page_owner(struct page *oldpage, struct page *newpage) { @@ -58,9 +56,9 @@ static inline void set_page_owner(struct page *page, unsigned int order, gfp_t gfp_mask) { } -static inline gfp_t get_page_owner_gfp(struct page *page) +static inline void split_page_owner(struct page *page, + unsigned int order) { - return 0; } static inline void copy_page_owner(struct page *oldpage, struct page *newpage) { diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1b1ca57..616ada9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2459,7 +2459,6 @@ void free_hot_cold_page_list(struct list_head *list, bool cold) void split_page(struct page *page, unsigned int order) { int i; - gfp_t gfp_mask; VM_BUG_ON_PAGE(PageCompound(page), page); VM_BUG_ON_PAGE(!page_count(page), page); @@ -2473,12 +2472,9 @@ void split_page(struct page *page, unsigned int order) split_page(virt_to_page(page[0].shadow), order); #endif - gfp_mask = get_page_owner_gfp(page); - set_page_owner(page, 0, gfp_mask); - for (i = 1; i < (1 << order); i++) { + for (i = 1; i < (1 << order); i++) set_page_refcounted(page + i); - set_page_owner(page + i, 0, gfp_mask); - } + split_page_owner(page, order); } EXPORT_SYMBOL_GPL(split_page); diff --git a/mm/page_owner.c b/mm/page_owner.c index 73e202f..499ad26 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -94,17 +94,17 @@ void __set_page_owner_migrate_reason(struct page *page, int reason) page_ext->last_migrate_reason = reason; } -gfp_t __get_page_owner_gfp(struct page *page) +void __split_page_owner(struct page *page, unsigned int order) { + int i; struct page_ext *page_ext = lookup_page_ext(page); + if (unlikely(!page_ext)) - /* -* The caller just returns 0 if no valid gfp -* So return 0 here too. -*/ - return 0; + return; - return page_ext->gfp_mask; + page_ext->order = 0; + for (i = 1; i < (1 << order); i++) + __copy_page_owner(page, page + i); } void __copy_page_owner(struct page *oldpage, struct page *newpage) -- 1.9.1
[PATCH v2 6/7] mm/page_owner: use stackdepot to store stacktrace
From: Joonsoo KimCurrently, we store each page's allocation stacktrace on corresponding page_ext structure and it requires a lot of memory. This causes the problem that memory tight system doesn't work well if page_owner is enabled. Moreover, even with this large memory consumption, we cannot get full stacktrace because we allocate memory at boot time and just maintain 8 stacktrace slots to balance memory consumption. We could increase it to more but it would make system unusable or change system behaviour. To solve the problem, this patch uses stackdepot to store stacktrace. It obviously provides memory saving but there is a drawback that stackdepot could fail. stackdepot allocates memory at runtime so it could fail if system has not enough memory. But, most of allocation stack are generated at very early time and there are much memory at this time. So, failure would not happen easily. And, one failure means that we miss just one page's allocation stacktrace so it would not be a big problem. In this patch, when memory allocation failure happens, we store special stracktrace handle to the page that is failed to save stacktrace. With it, user can guess memory usage properly even if failure happens. Memory saving looks as following. (4GB memory system with page_owner) static allocation: 92274688 bytes -> 25165824 bytes dynamic allocation after kernel build: 0 bytes -> 327680 bytes total: 92274688 bytes -> 25493504 bytes 72% reduction in total. Note that implementation looks complex than someone would imagine because there is recursion issue. stackdepot uses page allocator and page_owner is called at page allocation. Using stackdepot in page_owner could re-call page allcator and then page_owner. That is a recursion. To detect and avoid it, whenever we obtain stacktrace, recursion is checked and page_owner is set to dummy information if found. Dummy information means that this page is allocated for page_owner feature itself (such as stackdepot) and it's understandable behavior for user. v2: o calculate memory saving with including dynamic allocation after kernel build o change maximum stacktrace entry size due to possible stack overflow Signed-off-by: Joonsoo Kim --- include/linux/page_ext.h | 4 +- lib/Kconfig.debug| 1 + mm/page_owner.c | 138 --- 3 files changed, 122 insertions(+), 21 deletions(-) diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index e1fe7cf..03f2a3e 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -3,6 +3,7 @@ #include #include +#include struct pglist_data; struct page_ext_operations { @@ -44,9 +45,8 @@ struct page_ext { #ifdef CONFIG_PAGE_OWNER unsigned int order; gfp_t gfp_mask; - unsigned int nr_entries; int last_migrate_reason; - unsigned long trace_entries[8]; + depot_stack_handle_t handle; #endif }; diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 930bf8e..fc37c66 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -248,6 +248,7 @@ config PAGE_OWNER depends on DEBUG_KERNEL && STACKTRACE_SUPPORT select DEBUG_FS select STACKTRACE + select STACKDEPOT select PAGE_EXTENSION help This keeps track of what call chain is the owner of a page, may diff --git a/mm/page_owner.c b/mm/page_owner.c index 499ad26..587dcca 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -7,11 +7,18 @@ #include #include #include +#include + #include "internal.h" +#define PAGE_OWNER_STACK_DEPTH (16) + static bool page_owner_disabled = true; DEFINE_STATIC_KEY_FALSE(page_owner_inited); +static depot_stack_handle_t dummy_handle; +static depot_stack_handle_t failure_handle; + static void init_early_allocated_pages(void); static int early_page_owner_param(char *buf) @@ -34,11 +41,41 @@ static bool need_page_owner(void) return true; } +static noinline void register_dummy_stack(void) +{ + unsigned long entries[4]; + struct stack_trace dummy; + + dummy.nr_entries = 0; + dummy.max_entries = ARRAY_SIZE(entries); + dummy.entries = [0]; + dummy.skip = 0; + + save_stack_trace(); + dummy_handle = depot_save_stack(, GFP_KERNEL); +} + +static noinline void register_failure_stack(void) +{ + unsigned long entries[4]; + struct stack_trace failure; + + failure.nr_entries = 0; + failure.max_entries = ARRAY_SIZE(entries); + failure.entries = [0]; + failure.skip = 0; + + save_stack_trace(); + failure_handle = depot_save_stack(, GFP_KERNEL); +} + static void init_page_owner(void) { if (page_owner_disabled) return; + register_dummy_stack(); + register_failure_stack(); static_branch_enable(_owner_inited); init_early_allocated_pages(); } @@ -61,25 +98,66 @@ void
[PATCH v2 7/7] mm/page_alloc: introduce post allocation processing on page allocator
From: Joonsoo KimThis patch is motivated from Hugh and Vlastimil's concern [1]. There are two ways to get freepage from the allocator. One is using normal memory allocation API and the other is __isolate_free_page() which is internally used for compaction and pageblock isolation. Later usage is rather tricky since it doesn't do whole post allocation processing done by normal API. One problematic thing I already know is that poisoned page would not be checked if it is allocated by __isolate_free_page(). Perhaps, there would be more. We could add more debug logic for allocated page in the future and this separation would cause more problem. I'd like to fix this situation at this time. Solution is simple. This patch commonize some logic for newly allocated page and uses it on all sites. This will solve the problem. [1] http://marc.info/?i=alpine.LSU.2.11.1604270029350.7066%40eggly.anvils%3E Signed-off-by: Joonsoo Kim --- mm/compaction.c | 8 +--- mm/internal.h | 2 ++ mm/page_alloc.c | 22 +- mm/page_isolation.c | 4 +--- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/mm/compaction.c b/mm/compaction.c index 6043ef8..e15d350 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -75,14 +75,8 @@ static void map_pages(struct list_head *list) order = page_private(page); nr_pages = 1 << order; - set_page_private(page, 0); - set_page_refcounted(page); - arch_alloc_page(page, order); - kernel_map_pages(page, nr_pages, 1); - kasan_alloc_pages(page, order); - - set_page_owner(page, order, __GFP_MOVABLE); + post_alloc_hook(page, order, __GFP_MOVABLE); if (order) split_page(page, order); diff --git a/mm/internal.h b/mm/internal.h index b6ead95..420bbe3 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -153,6 +153,8 @@ extern int __isolate_free_page(struct page *page, unsigned int order); extern void __free_pages_bootmem(struct page *page, unsigned long pfn, unsigned int order); extern void prep_compound_page(struct page *page, unsigned int order); +extern void post_alloc_hook(struct page *page, unsigned int order, + gfp_t gfp_flags); extern int user_min_free_kbytes; #if defined CONFIG_COMPACTION || defined CONFIG_CMA diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 616ada9..baa5999 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1722,6 +1722,18 @@ static bool check_new_pages(struct page *page, unsigned int order) return false; } +void post_alloc_hook(struct page *page, unsigned int order, gfp_t gfp_flags) +{ + set_page_private(page, 0); + set_page_refcounted(page); + + arch_alloc_page(page, order); + kernel_map_pages(page, 1 << order, 1); + kernel_poison_pages(page, 1 << order, 1); + kasan_alloc_pages(page, order); + set_page_owner(page, order, gfp_flags); +} + static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags, unsigned int alloc_flags) { @@ -1734,13 +1746,7 @@ static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags poisoned &= page_is_poisoned(p); } - set_page_private(page, 0); - set_page_refcounted(page); - - arch_alloc_page(page, order); - kernel_map_pages(page, 1 << order, 1); - kernel_poison_pages(page, 1 << order, 1); - kasan_alloc_pages(page, order); + post_alloc_hook(page, order, gfp_flags); if (!free_pages_prezeroed(poisoned) && (gfp_flags & __GFP_ZERO)) for (i = 0; i < (1 << order); i++) @@ -1749,8 +1755,6 @@ static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags if (order && (gfp_flags & __GFP_COMP)) prep_compound_page(page, order); - set_page_owner(page, order, gfp_flags); - /* * page is set pfmemalloc when ALLOC_NO_WATERMARKS was necessary to * allocate the page. The expectation is that the caller is taking diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 927f5ee..4639163 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -128,9 +128,7 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype) out: spin_unlock_irqrestore(>lock, flags); if (isolated_page) { - kernel_map_pages(page, (1 << order), 1); - set_page_refcounted(page); - set_page_owner(page, order, __GFP_MOVABLE); + post_alloc_hook(page, order, __GFP_MOVABLE); __free_pages(isolated_page, order); } } -- 1.9.1
[PATCH v2 3/7] mm/page_owner: copy last_migrate_reason in copy_page_owner()
From: Joonsoo KimCurrently, copy_page_owner() doesn't copy all the owner information. It skips last_migrate_reason because copy_page_owner() is used for migration and it will be properly set soon. But, following patch will use copy_page_owner() and this skip will cause the problem that allocated page has uninitialied last_migrate_reason. To prevent it, this patch also copy last_migrate_reason in copy_page_owner(). Signed-off-by: Joonsoo Kim --- mm/page_owner.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/page_owner.c b/mm/page_owner.c index c6cda3e..73e202f 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -118,6 +118,7 @@ void __copy_page_owner(struct page *oldpage, struct page *newpage) new_ext->order = old_ext->order; new_ext->gfp_mask = old_ext->gfp_mask; + new_ext->last_migrate_reason = old_ext->last_migrate_reason; new_ext->nr_entries = old_ext->nr_entries; for (i = 0; i < ARRAY_SIZE(new_ext->trace_entries); i++) -- 1.9.1
[PATCH v2 6/7] mm/page_owner: use stackdepot to store stacktrace
From: Joonsoo Kim Currently, we store each page's allocation stacktrace on corresponding page_ext structure and it requires a lot of memory. This causes the problem that memory tight system doesn't work well if page_owner is enabled. Moreover, even with this large memory consumption, we cannot get full stacktrace because we allocate memory at boot time and just maintain 8 stacktrace slots to balance memory consumption. We could increase it to more but it would make system unusable or change system behaviour. To solve the problem, this patch uses stackdepot to store stacktrace. It obviously provides memory saving but there is a drawback that stackdepot could fail. stackdepot allocates memory at runtime so it could fail if system has not enough memory. But, most of allocation stack are generated at very early time and there are much memory at this time. So, failure would not happen easily. And, one failure means that we miss just one page's allocation stacktrace so it would not be a big problem. In this patch, when memory allocation failure happens, we store special stracktrace handle to the page that is failed to save stacktrace. With it, user can guess memory usage properly even if failure happens. Memory saving looks as following. (4GB memory system with page_owner) static allocation: 92274688 bytes -> 25165824 bytes dynamic allocation after kernel build: 0 bytes -> 327680 bytes total: 92274688 bytes -> 25493504 bytes 72% reduction in total. Note that implementation looks complex than someone would imagine because there is recursion issue. stackdepot uses page allocator and page_owner is called at page allocation. Using stackdepot in page_owner could re-call page allcator and then page_owner. That is a recursion. To detect and avoid it, whenever we obtain stacktrace, recursion is checked and page_owner is set to dummy information if found. Dummy information means that this page is allocated for page_owner feature itself (such as stackdepot) and it's understandable behavior for user. v2: o calculate memory saving with including dynamic allocation after kernel build o change maximum stacktrace entry size due to possible stack overflow Signed-off-by: Joonsoo Kim --- include/linux/page_ext.h | 4 +- lib/Kconfig.debug| 1 + mm/page_owner.c | 138 --- 3 files changed, 122 insertions(+), 21 deletions(-) diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h index e1fe7cf..03f2a3e 100644 --- a/include/linux/page_ext.h +++ b/include/linux/page_ext.h @@ -3,6 +3,7 @@ #include #include +#include struct pglist_data; struct page_ext_operations { @@ -44,9 +45,8 @@ struct page_ext { #ifdef CONFIG_PAGE_OWNER unsigned int order; gfp_t gfp_mask; - unsigned int nr_entries; int last_migrate_reason; - unsigned long trace_entries[8]; + depot_stack_handle_t handle; #endif }; diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 930bf8e..fc37c66 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -248,6 +248,7 @@ config PAGE_OWNER depends on DEBUG_KERNEL && STACKTRACE_SUPPORT select DEBUG_FS select STACKTRACE + select STACKDEPOT select PAGE_EXTENSION help This keeps track of what call chain is the owner of a page, may diff --git a/mm/page_owner.c b/mm/page_owner.c index 499ad26..587dcca 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -7,11 +7,18 @@ #include #include #include +#include + #include "internal.h" +#define PAGE_OWNER_STACK_DEPTH (16) + static bool page_owner_disabled = true; DEFINE_STATIC_KEY_FALSE(page_owner_inited); +static depot_stack_handle_t dummy_handle; +static depot_stack_handle_t failure_handle; + static void init_early_allocated_pages(void); static int early_page_owner_param(char *buf) @@ -34,11 +41,41 @@ static bool need_page_owner(void) return true; } +static noinline void register_dummy_stack(void) +{ + unsigned long entries[4]; + struct stack_trace dummy; + + dummy.nr_entries = 0; + dummy.max_entries = ARRAY_SIZE(entries); + dummy.entries = [0]; + dummy.skip = 0; + + save_stack_trace(); + dummy_handle = depot_save_stack(, GFP_KERNEL); +} + +static noinline void register_failure_stack(void) +{ + unsigned long entries[4]; + struct stack_trace failure; + + failure.nr_entries = 0; + failure.max_entries = ARRAY_SIZE(entries); + failure.entries = [0]; + failure.skip = 0; + + save_stack_trace(); + failure_handle = depot_save_stack(, GFP_KERNEL); +} + static void init_page_owner(void) { if (page_owner_disabled) return; + register_dummy_stack(); + register_failure_stack(); static_branch_enable(_owner_inited); init_early_allocated_pages(); } @@ -61,25 +98,66 @@ void __reset_page_owner(struct page *page, unsigned int
[PATCH v2 7/7] mm/page_alloc: introduce post allocation processing on page allocator
From: Joonsoo Kim This patch is motivated from Hugh and Vlastimil's concern [1]. There are two ways to get freepage from the allocator. One is using normal memory allocation API and the other is __isolate_free_page() which is internally used for compaction and pageblock isolation. Later usage is rather tricky since it doesn't do whole post allocation processing done by normal API. One problematic thing I already know is that poisoned page would not be checked if it is allocated by __isolate_free_page(). Perhaps, there would be more. We could add more debug logic for allocated page in the future and this separation would cause more problem. I'd like to fix this situation at this time. Solution is simple. This patch commonize some logic for newly allocated page and uses it on all sites. This will solve the problem. [1] http://marc.info/?i=alpine.LSU.2.11.1604270029350.7066%40eggly.anvils%3E Signed-off-by: Joonsoo Kim --- mm/compaction.c | 8 +--- mm/internal.h | 2 ++ mm/page_alloc.c | 22 +- mm/page_isolation.c | 4 +--- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/mm/compaction.c b/mm/compaction.c index 6043ef8..e15d350 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -75,14 +75,8 @@ static void map_pages(struct list_head *list) order = page_private(page); nr_pages = 1 << order; - set_page_private(page, 0); - set_page_refcounted(page); - arch_alloc_page(page, order); - kernel_map_pages(page, nr_pages, 1); - kasan_alloc_pages(page, order); - - set_page_owner(page, order, __GFP_MOVABLE); + post_alloc_hook(page, order, __GFP_MOVABLE); if (order) split_page(page, order); diff --git a/mm/internal.h b/mm/internal.h index b6ead95..420bbe3 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -153,6 +153,8 @@ extern int __isolate_free_page(struct page *page, unsigned int order); extern void __free_pages_bootmem(struct page *page, unsigned long pfn, unsigned int order); extern void prep_compound_page(struct page *page, unsigned int order); +extern void post_alloc_hook(struct page *page, unsigned int order, + gfp_t gfp_flags); extern int user_min_free_kbytes; #if defined CONFIG_COMPACTION || defined CONFIG_CMA diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 616ada9..baa5999 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1722,6 +1722,18 @@ static bool check_new_pages(struct page *page, unsigned int order) return false; } +void post_alloc_hook(struct page *page, unsigned int order, gfp_t gfp_flags) +{ + set_page_private(page, 0); + set_page_refcounted(page); + + arch_alloc_page(page, order); + kernel_map_pages(page, 1 << order, 1); + kernel_poison_pages(page, 1 << order, 1); + kasan_alloc_pages(page, order); + set_page_owner(page, order, gfp_flags); +} + static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags, unsigned int alloc_flags) { @@ -1734,13 +1746,7 @@ static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags poisoned &= page_is_poisoned(p); } - set_page_private(page, 0); - set_page_refcounted(page); - - arch_alloc_page(page, order); - kernel_map_pages(page, 1 << order, 1); - kernel_poison_pages(page, 1 << order, 1); - kasan_alloc_pages(page, order); + post_alloc_hook(page, order, gfp_flags); if (!free_pages_prezeroed(poisoned) && (gfp_flags & __GFP_ZERO)) for (i = 0; i < (1 << order); i++) @@ -1749,8 +1755,6 @@ static void prep_new_page(struct page *page, unsigned int order, gfp_t gfp_flags if (order && (gfp_flags & __GFP_COMP)) prep_compound_page(page, order); - set_page_owner(page, order, gfp_flags); - /* * page is set pfmemalloc when ALLOC_NO_WATERMARKS was necessary to * allocate the page. The expectation is that the caller is taking diff --git a/mm/page_isolation.c b/mm/page_isolation.c index 927f5ee..4639163 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -128,9 +128,7 @@ static void unset_migratetype_isolate(struct page *page, unsigned migratetype) out: spin_unlock_irqrestore(>lock, flags); if (isolated_page) { - kernel_map_pages(page, (1 << order), 1); - set_page_refcounted(page); - set_page_owner(page, order, __GFP_MOVABLE); + post_alloc_hook(page, order, __GFP_MOVABLE); __free_pages(isolated_page, order); } } -- 1.9.1
[PATCH v2 3/7] mm/page_owner: copy last_migrate_reason in copy_page_owner()
From: Joonsoo Kim Currently, copy_page_owner() doesn't copy all the owner information. It skips last_migrate_reason because copy_page_owner() is used for migration and it will be properly set soon. But, following patch will use copy_page_owner() and this skip will cause the problem that allocated page has uninitialied last_migrate_reason. To prevent it, this patch also copy last_migrate_reason in copy_page_owner(). Signed-off-by: Joonsoo Kim --- mm/page_owner.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/page_owner.c b/mm/page_owner.c index c6cda3e..73e202f 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -118,6 +118,7 @@ void __copy_page_owner(struct page *oldpage, struct page *newpage) new_ext->order = old_ext->order; new_ext->gfp_mask = old_ext->gfp_mask; + new_ext->last_migrate_reason = old_ext->last_migrate_reason; new_ext->nr_entries = old_ext->nr_entries; for (i = 0; i < ARRAY_SIZE(new_ext->trace_entries); i++) -- 1.9.1
[PATCH v2 1/7] mm/compaction: split freepages without holding the zone lock
From: Joonsoo KimWe don't need to split freepages with holding the zone lock. It will cause more contention on zone lock so not desirable. Signed-off-by: Joonsoo Kim --- include/linux/mm.h | 1 - mm/compaction.c| 42 ++ mm/page_alloc.c| 27 --- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index a00ec81..1a1782c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -537,7 +537,6 @@ void __put_page(struct page *page); void put_pages_list(struct list_head *pages); void split_page(struct page *page, unsigned int order); -int split_free_page(struct page *page); /* * Compound pages have a destructor function. Provide a diff --git a/mm/compaction.c b/mm/compaction.c index 1427366..8e013eb 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -65,13 +65,31 @@ static unsigned long release_freepages(struct list_head *freelist) static void map_pages(struct list_head *list) { - struct page *page; + unsigned int i, order, nr_pages; + struct page *page, *next; + LIST_HEAD(tmp_list); + + list_for_each_entry_safe(page, next, list, lru) { + list_del(>lru); + + order = page_private(page); + nr_pages = 1 << order; + set_page_private(page, 0); + set_page_refcounted(page); + + arch_alloc_page(page, order); + kernel_map_pages(page, nr_pages, 1); + kasan_alloc_pages(page, order); + if (order) + split_page(page, order); - list_for_each_entry(page, list, lru) { - arch_alloc_page(page, 0); - kernel_map_pages(page, 1, 1); - kasan_alloc_pages(page, 0); + for (i = 0; i < nr_pages; i++) { + list_add(>lru, _list); + page++; + } } + + list_splice(_list, list); } static inline bool migrate_async_suitable(int migratetype) @@ -368,12 +386,13 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, unsigned long flags = 0; bool locked = false; unsigned long blockpfn = *start_pfn; + unsigned int order; cursor = pfn_to_page(blockpfn); /* Isolate free pages. */ for (; blockpfn < end_pfn; blockpfn++, cursor++) { - int isolated, i; + int isolated; struct page *page = cursor; /* @@ -439,13 +458,12 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, goto isolate_fail; } - /* Found a free page, break it into order-0 pages */ - isolated = split_free_page(page); + /* Found a free page, will break it into order-0 pages */ + order = page_order(page); + isolated = __isolate_free_page(page, page_order(page)); + set_page_private(page, order); total_isolated += isolated; - for (i = 0; i < isolated; i++) { - list_add(>lru, freelist); - page++; - } + list_add_tail(>lru, freelist); /* If a page was split, advance to the end of it */ if (isolated) { diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d27e8b9..5134f46 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2525,33 +2525,6 @@ int __isolate_free_page(struct page *page, unsigned int order) } /* - * Similar to split_page except the page is already free. As this is only - * being used for migration, the migratetype of the block also changes. - * As this is called with interrupts disabled, the caller is responsible - * for calling arch_alloc_page() and kernel_map_page() after interrupts - * are enabled. - * - * Note: this is probably too low level an operation for use in drivers. - * Please consult with lkml before using this in your driver. - */ -int split_free_page(struct page *page) -{ - unsigned int order; - int nr_pages; - - order = page_order(page); - - nr_pages = __isolate_free_page(page, order); - if (!nr_pages) - return 0; - - /* Split into individual pages */ - set_page_refcounted(page); - split_page(page, order); - return nr_pages; -} - -/* * Update NUMA hit/miss statistics * * Must be called with interrupts disabled. -- 1.9.1
[PATCH v2 5/7] tools/vm/page_owner: increase temporary buffer size
From: Joonsoo KimPage owner will be changed to store more deep stacktrace so current temporary buffer size isn't enough. Increase it. Signed-off-by: Joonsoo Kim --- tools/vm/page_owner_sort.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/vm/page_owner_sort.c b/tools/vm/page_owner_sort.c index 77147b4..f1c055f 100644 --- a/tools/vm/page_owner_sort.c +++ b/tools/vm/page_owner_sort.c @@ -79,12 +79,12 @@ static void add_list(char *buf, int len) } } -#define BUF_SIZE 1024 +#define BUF_SIZE (128 * 1024) int main(int argc, char **argv) { FILE *fin, *fout; - char buf[BUF_SIZE]; + char *buf; int ret, i, count; struct block_list *list2; struct stat st; @@ -107,6 +107,11 @@ int main(int argc, char **argv) max_size = st.st_size / 100; /* hack ... */ list = malloc(max_size * sizeof(*list)); + buf = malloc(BUF_SIZE); + if (!list || !buf) { + printf("Out of memory\n"); + exit(1); + } for ( ; ; ) { ret = read_block(buf, BUF_SIZE, fin); -- 1.9.1
[PATCH v2 1/7] mm/compaction: split freepages without holding the zone lock
From: Joonsoo Kim We don't need to split freepages with holding the zone lock. It will cause more contention on zone lock so not desirable. Signed-off-by: Joonsoo Kim --- include/linux/mm.h | 1 - mm/compaction.c| 42 ++ mm/page_alloc.c| 27 --- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index a00ec81..1a1782c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -537,7 +537,6 @@ void __put_page(struct page *page); void put_pages_list(struct list_head *pages); void split_page(struct page *page, unsigned int order); -int split_free_page(struct page *page); /* * Compound pages have a destructor function. Provide a diff --git a/mm/compaction.c b/mm/compaction.c index 1427366..8e013eb 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -65,13 +65,31 @@ static unsigned long release_freepages(struct list_head *freelist) static void map_pages(struct list_head *list) { - struct page *page; + unsigned int i, order, nr_pages; + struct page *page, *next; + LIST_HEAD(tmp_list); + + list_for_each_entry_safe(page, next, list, lru) { + list_del(>lru); + + order = page_private(page); + nr_pages = 1 << order; + set_page_private(page, 0); + set_page_refcounted(page); + + arch_alloc_page(page, order); + kernel_map_pages(page, nr_pages, 1); + kasan_alloc_pages(page, order); + if (order) + split_page(page, order); - list_for_each_entry(page, list, lru) { - arch_alloc_page(page, 0); - kernel_map_pages(page, 1, 1); - kasan_alloc_pages(page, 0); + for (i = 0; i < nr_pages; i++) { + list_add(>lru, _list); + page++; + } } + + list_splice(_list, list); } static inline bool migrate_async_suitable(int migratetype) @@ -368,12 +386,13 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, unsigned long flags = 0; bool locked = false; unsigned long blockpfn = *start_pfn; + unsigned int order; cursor = pfn_to_page(blockpfn); /* Isolate free pages. */ for (; blockpfn < end_pfn; blockpfn++, cursor++) { - int isolated, i; + int isolated; struct page *page = cursor; /* @@ -439,13 +458,12 @@ static unsigned long isolate_freepages_block(struct compact_control *cc, goto isolate_fail; } - /* Found a free page, break it into order-0 pages */ - isolated = split_free_page(page); + /* Found a free page, will break it into order-0 pages */ + order = page_order(page); + isolated = __isolate_free_page(page, page_order(page)); + set_page_private(page, order); total_isolated += isolated; - for (i = 0; i < isolated; i++) { - list_add(>lru, freelist); - page++; - } + list_add_tail(>lru, freelist); /* If a page was split, advance to the end of it */ if (isolated) { diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d27e8b9..5134f46 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -2525,33 +2525,6 @@ int __isolate_free_page(struct page *page, unsigned int order) } /* - * Similar to split_page except the page is already free. As this is only - * being used for migration, the migratetype of the block also changes. - * As this is called with interrupts disabled, the caller is responsible - * for calling arch_alloc_page() and kernel_map_page() after interrupts - * are enabled. - * - * Note: this is probably too low level an operation for use in drivers. - * Please consult with lkml before using this in your driver. - */ -int split_free_page(struct page *page) -{ - unsigned int order; - int nr_pages; - - order = page_order(page); - - nr_pages = __isolate_free_page(page, order); - if (!nr_pages) - return 0; - - /* Split into individual pages */ - set_page_refcounted(page); - split_page(page, order); - return nr_pages; -} - -/* * Update NUMA hit/miss statistics * * Must be called with interrupts disabled. -- 1.9.1
[PATCH v2 5/7] tools/vm/page_owner: increase temporary buffer size
From: Joonsoo Kim Page owner will be changed to store more deep stacktrace so current temporary buffer size isn't enough. Increase it. Signed-off-by: Joonsoo Kim --- tools/vm/page_owner_sort.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/vm/page_owner_sort.c b/tools/vm/page_owner_sort.c index 77147b4..f1c055f 100644 --- a/tools/vm/page_owner_sort.c +++ b/tools/vm/page_owner_sort.c @@ -79,12 +79,12 @@ static void add_list(char *buf, int len) } } -#define BUF_SIZE 1024 +#define BUF_SIZE (128 * 1024) int main(int argc, char **argv) { FILE *fin, *fout; - char buf[BUF_SIZE]; + char *buf; int ret, i, count; struct block_list *list2; struct stat st; @@ -107,6 +107,11 @@ int main(int argc, char **argv) max_size = st.st_size / 100; /* hack ... */ list = malloc(max_size * sizeof(*list)); + buf = malloc(BUF_SIZE); + if (!list || !buf) { + printf("Out of memory\n"); + exit(1); + } for ( ; ; ) { ret = read_block(buf, BUF_SIZE, fin); -- 1.9.1
Re: [PATCH] MAINTAINERS: Kdump maintainers update
Hi, Vivek On 05/25/16 at 09:37am, Vivek Goyal wrote: > On Wed, May 25, 2016 at 06:24:10AM -0700, Joe Perches wrote: > > On Wed, 2016-05-25 at 09:16 -0400, Vivek Goyal wrote: > > > I am proposing following updates to kdump maintainership. I have got > > > busy in other things and not getting time to spend on kdump. > > > > > > Removed Haren Myneni as he has not participated in kdump development for > > > a long time now. > > > > > > Proposing adding the names of Dave and Baoquan as kdump maintainers as > > > they have been contributing to kdump for a long time now and they are in > > > a much better position to spend time on this than me. > > [] > > > diff --git a/MAINTAINERS b/MAINTAINERS > > [] > > > @@ -6189,8 +6189,9 @@ F: Documentation/kbuild/kconfig-language.txt > > > F: scripts/kconfig/ > > > > > > KDUMP > > > +M: Dave Young> > > +M: Baoquan He > > > M: Vivek Goyal > > > > You could mark yourself as an "R:" reviewer > > instead of an "M:" maintainer. > > That's a good idea. I updated the patch and marked myself reviewer. > > Removed Haren Myneni as he has not participated in kdump development for > a long time now. > > Proposing adding the names of Dave and Baoquan as kdump maintainers as > they have been working on it for quite some time on it upstream and > they are in a much better position to spend time on this than me. Thanks a lot for the patch! I will do my best to work with Baoquan to maintain it. Very appreciated for your guidiance before and in the future. > > Signed-off-by: Vivek Goyal > --- > MAINTAINERS | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 9c567a4..5792ec2 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6189,8 +6189,9 @@ F: Documentation/kbuild/kconfig-language.txt > F: scripts/kconfig/ > > KDUMP > -M: Vivek Goyal > -M: Haren Myneni > +M: Dave Young > +M: Baoquan He > +R: Vivek Goyal > L: ke...@lists.infradead.org > W: http://lse.sourceforge.net/kdump/ It is not related to this patch, just to be curious, who is maintain the above page? Seems some links are outdated. > S: Maintained > -- > 2.7.4 > Thanks Dave
Re: [PATCH] MAINTAINERS: Kdump maintainers update
Hi, Vivek On 05/25/16 at 09:37am, Vivek Goyal wrote: > On Wed, May 25, 2016 at 06:24:10AM -0700, Joe Perches wrote: > > On Wed, 2016-05-25 at 09:16 -0400, Vivek Goyal wrote: > > > I am proposing following updates to kdump maintainership. I have got > > > busy in other things and not getting time to spend on kdump. > > > > > > Removed Haren Myneni as he has not participated in kdump development for > > > a long time now. > > > > > > Proposing adding the names of Dave and Baoquan as kdump maintainers as > > > they have been contributing to kdump for a long time now and they are in > > > a much better position to spend time on this than me. > > [] > > > diff --git a/MAINTAINERS b/MAINTAINERS > > [] > > > @@ -6189,8 +6189,9 @@ F: Documentation/kbuild/kconfig-language.txt > > > F: scripts/kconfig/ > > > > > > KDUMP > > > +M: Dave Young > > > +M: Baoquan He > > > M: Vivek Goyal > > > > You could mark yourself as an "R:" reviewer > > instead of an "M:" maintainer. > > That's a good idea. I updated the patch and marked myself reviewer. > > Removed Haren Myneni as he has not participated in kdump development for > a long time now. > > Proposing adding the names of Dave and Baoquan as kdump maintainers as > they have been working on it for quite some time on it upstream and > they are in a much better position to spend time on this than me. Thanks a lot for the patch! I will do my best to work with Baoquan to maintain it. Very appreciated for your guidiance before and in the future. > > Signed-off-by: Vivek Goyal > --- > MAINTAINERS | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 9c567a4..5792ec2 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6189,8 +6189,9 @@ F: Documentation/kbuild/kconfig-language.txt > F: scripts/kconfig/ > > KDUMP > -M: Vivek Goyal > -M: Haren Myneni > +M: Dave Young > +M: Baoquan He > +R: Vivek Goyal > L: ke...@lists.infradead.org > W: http://lse.sourceforge.net/kdump/ It is not related to this patch, just to be curious, who is maintain the above page? Seems some links are outdated. > S: Maintained > -- > 2.7.4 > Thanks Dave
Re: [PATCH] mmc: dw_mmc: Consider HLE errors to be data and command errors
Hi Jaehoon, On 2016/5/19 21:07, Jaehoon Chung wrote: On 05/19/2016 08:31 PM, Shawn Lin wrote: Hi, On 2016/5/19 1:37, Doug Anderson wrote: Hi, On Wed, May 18, 2016 at 2:14 AM, Shawn Linwrote: Hi On 2016-5-18 12:12, Doug Anderson wrote: Hi, On Tue, May 17, 2016 at 6:59 PM, Shawn Lin wrote: Could you try this patch to see if you can still find HLE? @@ -2356,12 +2356,22 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) static void dw_mci_handle_cd(struct dw_mci *host) { int i; + int present; for (i = 0; i < host->num_slots; i++) { struct dw_mci_slot *slot = host->slot[i]; if (!slot) continue; + present = !(mci_readl(slot->host, CDETECT) & (1 << slot->id)); + if (present) + set_bit(DW_MMC_CARD_PRESENT, >flags); + else + clear_bit(DW_MMC_CARD_PRESENT, >flags); No, because we don't use the builtin card detect on veyron. ;) We use GPIO card detect because we didn't like the way JTAG and SD interacted. Also on rk3288 the builtin card detect line had the wrong voltage domain (you couldn't detect a card when the IO lines were powered off). The builtin card detect line is always driven low on veyron. Okay, I see. I'm nearly certain that the root cause of my HLE errors is actually related to the same problem addressed by the commit 7c5209c315ea ("mmc: core: Increase delay for voltage to stabilize from 3.3V to 1.8V"). I think that on minnie we're still on the hairy edge and sometimes the line doesn't transition fast enough. Things are not so simple from your details. I was not enabling SD3.0 support, then I also found HLE sometimes. So it seems commit 7c5209c315ea does not contibute to this phenomenon. Just to clarify, in my case commit 7c5209c315ea didn't make the problem worse, but made it better. Just not better enough. ;) The scenario looks like: remove sd-card -> mmc_sd_detect -> send status(CMD13) ->power_off -> set_ios -> setup_bus -> disabled clk , then HLE irq storm coming From the code of dw_mci_prepare_command: SDMMC_CMD_PRV_DAT_WAIT will not be used for CMD13, so we don't wait_busy here, then cmd code is loding into queue of dw_mmc but still failing send out because it's in busy? With my patch, things go well: remove sd-card -> clear bit of DW_MMC_CARD_PRESENT -> send status(CMD13) return directly -> power_off -> set_ios -> setup_bus -> disable clk So why should we allow inquiry of card status if we sure the card is removed? I mean no any further cmds should be delivered. Quite honestly just dealing with the HLE error (my patch or equivalent) might be a sane solution for the problem you describe. Yes, your patch looks good to me, so it should be merged firstly. :) Then let's push it a bit further more that when HLEs are coming, somethings must be wrong(currently I don't see a obvious clue from the code itself although, I'm prone to think it belongs to the software issue). We don't know what's main cause for HLE..But i also think it's relevant to SW issue. But we need to consider all possibilities.. dw_mmc needs to be able to work with an external card detect GPIO. It's been part of the dw_mmc driver for a long time and is (in fact) in use upstream at least by rk3288-veyron. Any solution that only works for internal card detect is not enough. Just handling the HLE error to deal with the interrupt storm and then letting Linux remove the card (because of the card detect interrupt) seems totally OK to me. Sure, some of rockchip Socs use gpio for CD because they don't have a internal CD, such as RK3036, right? Note: I'd be very curious if your problems get better if you disable Not at all. the "grf_force_jtag" bit in the GRF. If you're using the builtin card detect and you use the boot default of "grf_force_jtag" then your pins will be unmuxed behind your back when the card is ejected. This could be causing the dw_mmc controller to get confused. Right, grf_force_jtag is also not a friend of mine. :) So I had disabled this function before I was debugging it. And another question: should we wait busy for cmd13? I don't think so. As I understand it CMD13 uses only the CMD line for communication and it should be appropriate to send this when the bus is "busy" (which means that the DATA lines are low). Ahh... take back my question.. I was just considering a wired situation that pins are unmuxed on the background(cmd line as well) when cmd13 is delivering Also: it seems odd that the HLE IRQ storm didn't come right after the CMD 13 in your description above. Are you sure it was the CMD 13 that caused the HLEs, or could it has been something else? Actually no. Any cmds be issued can trigger HLEs, I think, after sd card is removed When I hacked mmc_sd_detecd to send other cmds
Re: [PATCH] mmc: dw_mmc: Consider HLE errors to be data and command errors
Hi Jaehoon, On 2016/5/19 21:07, Jaehoon Chung wrote: On 05/19/2016 08:31 PM, Shawn Lin wrote: Hi, On 2016/5/19 1:37, Doug Anderson wrote: Hi, On Wed, May 18, 2016 at 2:14 AM, Shawn Lin wrote: Hi On 2016-5-18 12:12, Doug Anderson wrote: Hi, On Tue, May 17, 2016 at 6:59 PM, Shawn Lin wrote: Could you try this patch to see if you can still find HLE? @@ -2356,12 +2356,22 @@ static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) static void dw_mci_handle_cd(struct dw_mci *host) { int i; + int present; for (i = 0; i < host->num_slots; i++) { struct dw_mci_slot *slot = host->slot[i]; if (!slot) continue; + present = !(mci_readl(slot->host, CDETECT) & (1 << slot->id)); + if (present) + set_bit(DW_MMC_CARD_PRESENT, >flags); + else + clear_bit(DW_MMC_CARD_PRESENT, >flags); No, because we don't use the builtin card detect on veyron. ;) We use GPIO card detect because we didn't like the way JTAG and SD interacted. Also on rk3288 the builtin card detect line had the wrong voltage domain (you couldn't detect a card when the IO lines were powered off). The builtin card detect line is always driven low on veyron. Okay, I see. I'm nearly certain that the root cause of my HLE errors is actually related to the same problem addressed by the commit 7c5209c315ea ("mmc: core: Increase delay for voltage to stabilize from 3.3V to 1.8V"). I think that on minnie we're still on the hairy edge and sometimes the line doesn't transition fast enough. Things are not so simple from your details. I was not enabling SD3.0 support, then I also found HLE sometimes. So it seems commit 7c5209c315ea does not contibute to this phenomenon. Just to clarify, in my case commit 7c5209c315ea didn't make the problem worse, but made it better. Just not better enough. ;) The scenario looks like: remove sd-card -> mmc_sd_detect -> send status(CMD13) ->power_off -> set_ios -> setup_bus -> disabled clk , then HLE irq storm coming From the code of dw_mci_prepare_command: SDMMC_CMD_PRV_DAT_WAIT will not be used for CMD13, so we don't wait_busy here, then cmd code is loding into queue of dw_mmc but still failing send out because it's in busy? With my patch, things go well: remove sd-card -> clear bit of DW_MMC_CARD_PRESENT -> send status(CMD13) return directly -> power_off -> set_ios -> setup_bus -> disable clk So why should we allow inquiry of card status if we sure the card is removed? I mean no any further cmds should be delivered. Quite honestly just dealing with the HLE error (my patch or equivalent) might be a sane solution for the problem you describe. Yes, your patch looks good to me, so it should be merged firstly. :) Then let's push it a bit further more that when HLEs are coming, somethings must be wrong(currently I don't see a obvious clue from the code itself although, I'm prone to think it belongs to the software issue). We don't know what's main cause for HLE..But i also think it's relevant to SW issue. But we need to consider all possibilities.. dw_mmc needs to be able to work with an external card detect GPIO. It's been part of the dw_mmc driver for a long time and is (in fact) in use upstream at least by rk3288-veyron. Any solution that only works for internal card detect is not enough. Just handling the HLE error to deal with the interrupt storm and then letting Linux remove the card (because of the card detect interrupt) seems totally OK to me. Sure, some of rockchip Socs use gpio for CD because they don't have a internal CD, such as RK3036, right? Note: I'd be very curious if your problems get better if you disable Not at all. the "grf_force_jtag" bit in the GRF. If you're using the builtin card detect and you use the boot default of "grf_force_jtag" then your pins will be unmuxed behind your back when the card is ejected. This could be causing the dw_mmc controller to get confused. Right, grf_force_jtag is also not a friend of mine. :) So I had disabled this function before I was debugging it. And another question: should we wait busy for cmd13? I don't think so. As I understand it CMD13 uses only the CMD line for communication and it should be appropriate to send this when the bus is "busy" (which means that the DATA lines are low). Ahh... take back my question.. I was just considering a wired situation that pins are unmuxed on the background(cmd line as well) when cmd13 is delivering Also: it seems odd that the HLE IRQ storm didn't come right after the CMD 13 in your description above. Are you sure it was the CMD 13 that caused the HLEs, or could it has been something else? Actually no. Any cmds be issued can trigger HLEs, I think, after sd card is removed When I hacked mmc_sd_detecd to send other cmds intead of cmd13. From dw_mmc databook v270a(7.2.3 Clock
RE: [PATCH] usb: core: add debugobjects support for urb object
> On Tue, May 24, 2016 at 03:53:53PM +0800, changbin...@intel.com wrote: > > From: "Du, Changbin"> > > > Add debugobject support to track the life time of struct urb. > > This feature help us detect violation of urb operations by > > generating a warning message from debugobject core. And we fix > > the possible issues at runtime to avoid oops if we can. > > > > I have done some tests with some class drivers, no violation > > found in them which is good. Expect this feature can be used > > for debugging future problems. > > > > Signed-off-by: Du, Changbin > > I agree with Alan, what use is this code? Existing drivers all work > properly because the reference counting of urbs is already present, why > add duplicate counters? That actually leads to bugs. I don't see the > need for this code, please explain it better if you wish for it to be > accepted. What has it found/fixed that we have not found yet? What > does it allow you to do that you can't do today with the existing code? > > thanks, > > greg k-h > I agree with you two now after checking all urb code. I am sorry to disturb you. I did have an object lifetime issue, but it is of usb_request. I expect the cause is usb_request is freed but still pending in udc core. Then I cannot reproduce it, I even cannot know which function driver the usb_request came from. I originally want to use debugojects to debug that issue, then I though this can also help urb debugging. Obviously I am wrong. As you said reference counting of urbs is already present. :) I may add debugojects for device mode usb_request farther. Sometimes it helps. Thank you, Du, Changbin
RE: [PATCH] usb: core: add debugobjects support for urb object
> On Tue, May 24, 2016 at 03:53:53PM +0800, changbin...@intel.com wrote: > > From: "Du, Changbin" > > > > Add debugobject support to track the life time of struct urb. > > This feature help us detect violation of urb operations by > > generating a warning message from debugobject core. And we fix > > the possible issues at runtime to avoid oops if we can. > > > > I have done some tests with some class drivers, no violation > > found in them which is good. Expect this feature can be used > > for debugging future problems. > > > > Signed-off-by: Du, Changbin > > I agree with Alan, what use is this code? Existing drivers all work > properly because the reference counting of urbs is already present, why > add duplicate counters? That actually leads to bugs. I don't see the > need for this code, please explain it better if you wish for it to be > accepted. What has it found/fixed that we have not found yet? What > does it allow you to do that you can't do today with the existing code? > > thanks, > > greg k-h > I agree with you two now after checking all urb code. I am sorry to disturb you. I did have an object lifetime issue, but it is of usb_request. I expect the cause is usb_request is freed but still pending in udc core. Then I cannot reproduce it, I even cannot know which function driver the usb_request came from. I originally want to use debugojects to debug that issue, then I though this can also help urb debugging. Obviously I am wrong. As you said reference counting of urbs is already present. :) I may add debugojects for device mode usb_request farther. Sometimes it helps. Thank you, Du, Changbin
Re: [PATCH] MAINTAINERS: Kdump maintainers update
On Wed, May 25, 2016 at 09:37:13AM -0400, Vivek Goyal wrote: > On Wed, May 25, 2016 at 06:24:10AM -0700, Joe Perches wrote: > > On Wed, 2016-05-25 at 09:16 -0400, Vivek Goyal wrote: > > > I am proposing following updates to kdump maintainership. I have got > > > busy in other things and not getting time to spend on kdump. > > > > > > Removed Haren Myneni as he has not participated in kdump development for > > > a long time now. > > > > > > Proposing adding the names of Dave and Baoquan as kdump maintainers as > > > they have been contributing to kdump for a long time now and they are in > > > a much better position to spend time on this than me. > > [] > > > diff --git a/MAINTAINERS b/MAINTAINERS > > [] > > > @@ -6189,8 +6189,9 @@ F: Documentation/kbuild/kconfig-language.txt > > > F: scripts/kconfig/ > > > > > > KDUMP > > > +M: Dave Young> > > +M: Baoquan He > > > M: Vivek Goyal > > > > You could mark yourself as an "R:" reviewer > > instead of an "M:" maintainer. > > That's a good idea. I updated the patch and marked myself reviewer. > > Removed Haren Myneni as he has not participated in kdump development for > a long time now. > > Proposing adding the names of Dave and Baoquan as kdump maintainers as > they have been working on it for quite some time on it upstream and > they are in a much better position to spend time on this than me. > > Signed-off-by: Vivek Goyal FWIW I am fine with this change. Acked-by: Simon Horman > --- > MAINTAINERS | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 9c567a4..5792ec2 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6189,8 +6189,9 @@ F: Documentation/kbuild/kconfig-language.txt > F: scripts/kconfig/ > > KDUMP > -M: Vivek Goyal > -M: Haren Myneni > +M: Dave Young > +M: Baoquan He > +R: Vivek Goyal > L: ke...@lists.infradead.org > W: http://lse.sourceforge.net/kdump/ > S: Maintained > -- > 2.7.4 >
Re: [PATCH] MAINTAINERS: Kdump maintainers update
On Wed, May 25, 2016 at 09:37:13AM -0400, Vivek Goyal wrote: > On Wed, May 25, 2016 at 06:24:10AM -0700, Joe Perches wrote: > > On Wed, 2016-05-25 at 09:16 -0400, Vivek Goyal wrote: > > > I am proposing following updates to kdump maintainership. I have got > > > busy in other things and not getting time to spend on kdump. > > > > > > Removed Haren Myneni as he has not participated in kdump development for > > > a long time now. > > > > > > Proposing adding the names of Dave and Baoquan as kdump maintainers as > > > they have been contributing to kdump for a long time now and they are in > > > a much better position to spend time on this than me. > > [] > > > diff --git a/MAINTAINERS b/MAINTAINERS > > [] > > > @@ -6189,8 +6189,9 @@ F: Documentation/kbuild/kconfig-language.txt > > > F: scripts/kconfig/ > > > > > > KDUMP > > > +M: Dave Young > > > +M: Baoquan He > > > M: Vivek Goyal > > > > You could mark yourself as an "R:" reviewer > > instead of an "M:" maintainer. > > That's a good idea. I updated the patch and marked myself reviewer. > > Removed Haren Myneni as he has not participated in kdump development for > a long time now. > > Proposing adding the names of Dave and Baoquan as kdump maintainers as > they have been working on it for quite some time on it upstream and > they are in a much better position to spend time on this than me. > > Signed-off-by: Vivek Goyal FWIW I am fine with this change. Acked-by: Simon Horman > --- > MAINTAINERS | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/MAINTAINERS b/MAINTAINERS > index 9c567a4..5792ec2 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6189,8 +6189,9 @@ F: Documentation/kbuild/kconfig-language.txt > F: scripts/kconfig/ > > KDUMP > -M: Vivek Goyal > -M: Haren Myneni > +M: Dave Young > +M: Baoquan He > +R: Vivek Goyal > L: ke...@lists.infradead.org > W: http://lse.sourceforge.net/kdump/ > S: Maintained > -- > 2.7.4 >
[PATCH] brcmfmac: rework function picking free BSS index
The old implementation was overcomplicated and slightly bugged in some corner cases. Consider following state of BSS-es (limited to 6 for simplification): drvr->iflist[0]: { bsscfgidx:0, ndev->name:wlan1, } drvr->iflist[1]: (null) drvr->iflist[2]: { bsscfgidx:2, ndev->name:wlan1-1, } drvr->iflist[3]: { bsscfgidx:3, ndev->name:wlan1-2, } drvr->iflist[4]: (null) drvr->iflist[5]: (null) In such case the next AP interface should bsscfgidx 4 (we don't use 1 as it's reserved for P2P). With old code the loop iterations were following: [ifidx = 0] [bsscfgidx = 2] [highest = 2] [ifidx = 1] [bsscfgidx = 2] [highest = 2] available = true [ifidx = 2] [bsscfgidx = 2] [highest = 2] bsscfgidx = highest + 1 [ifidx = 3] [bsscfgidx = 3] [highest = 2] bsscfgidx = highest + 1 [ifidx = 4] [bsscfgidx = 3] [highest = 2] available = true [ifidx = 5] [bsscfgidx = 3] [highest = 2] available = true There were 2 obvious problems: 1) Having empty BSS at index 1 was resulting in available being always set to true, even if we would run out of BSS-es. 2) Calculated bsscfgidx was invalid (3 instead of 4) resulting in driver not being able to create the 4th AP interface. New code is simpler, placed in file where it's really used, handles running out of free BSS-es and allows using 4 interfaces at the same time. It also looks for the first free BSS instead of one after the last in use. It works well with current driver (which doesn't allow deleting interfaces) and should be future proof (if we ever allow deleting). Signed-off-by: Rafał Miłecki--- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 17 ++- .../wireless/broadcom/brcm80211/brcmfmac/core.c| 24 -- .../wireless/broadcom/brcm80211/brcmfmac/core.h| 1 - 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 3d09d23..d00eef8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -541,6 +541,21 @@ brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev) ADDR_INDIRECT); } +static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr) +{ + int bsscfgidx; + + for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) { + /* bsscfgidx 1 is reserved for legacy P2P */ + if (bsscfgidx == 1) + continue; + if (!drvr->iflist[bsscfgidx]) + return bsscfgidx; + } + + return -ENOMEM; +} + static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) { struct brcmf_mbss_ssid_le mbss_ssid_le; @@ -548,7 +563,7 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) int err; memset(_ssid_le, 0, sizeof(mbss_ssid_le)); - bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr); + bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr); if (bsscfgidx < 0) return bsscfgidx; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index b590499..6a76480 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -753,30 +753,6 @@ void brcmf_remove_interface(struct brcmf_if *ifp) brcmf_del_if(ifp->drvr, ifp->bsscfgidx); } -int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr) -{ - int ifidx; - int bsscfgidx; - bool available; - int highest; - - available = false; - bsscfgidx = 2; - highest = 2; - for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) { - if (drvr->iflist[ifidx]) { - if (drvr->iflist[ifidx]->bsscfgidx == bsscfgidx) - bsscfgidx = highest + 1; - else if (drvr->iflist[ifidx]->bsscfgidx > highest) - highest = drvr->iflist[ifidx]->bsscfgidx; - } else { - available = true; - } - } - - return available ? bsscfgidx : -ENOMEM; -} - #ifdef CONFIG_INET #define ARPOL_MAX_ENTRIES 8 static int brcmf_inetaddr_changed(struct notifier_block *nb, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index 647d3cc..2a075c5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -217,7 +217,6 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, bool is_p2pdev, char *name, u8 *mac_addr); void
[PATCH] brcmfmac: rework function picking free BSS index
The old implementation was overcomplicated and slightly bugged in some corner cases. Consider following state of BSS-es (limited to 6 for simplification): drvr->iflist[0]: { bsscfgidx:0, ndev->name:wlan1, } drvr->iflist[1]: (null) drvr->iflist[2]: { bsscfgidx:2, ndev->name:wlan1-1, } drvr->iflist[3]: { bsscfgidx:3, ndev->name:wlan1-2, } drvr->iflist[4]: (null) drvr->iflist[5]: (null) In such case the next AP interface should bsscfgidx 4 (we don't use 1 as it's reserved for P2P). With old code the loop iterations were following: [ifidx = 0] [bsscfgidx = 2] [highest = 2] [ifidx = 1] [bsscfgidx = 2] [highest = 2] available = true [ifidx = 2] [bsscfgidx = 2] [highest = 2] bsscfgidx = highest + 1 [ifidx = 3] [bsscfgidx = 3] [highest = 2] bsscfgidx = highest + 1 [ifidx = 4] [bsscfgidx = 3] [highest = 2] available = true [ifidx = 5] [bsscfgidx = 3] [highest = 2] available = true There were 2 obvious problems: 1) Having empty BSS at index 1 was resulting in available being always set to true, even if we would run out of BSS-es. 2) Calculated bsscfgidx was invalid (3 instead of 4) resulting in driver not being able to create the 4th AP interface. New code is simpler, placed in file where it's really used, handles running out of free BSS-es and allows using 4 interfaces at the same time. It also looks for the first free BSS instead of one after the last in use. It works well with current driver (which doesn't allow deleting interfaces) and should be future proof (if we ever allow deleting). Signed-off-by: Rafał Miłecki --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 17 ++- .../wireless/broadcom/brcm80211/brcmfmac/core.c| 24 -- .../wireless/broadcom/brcm80211/brcmfmac/core.h| 1 - 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 3d09d23..d00eef8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -541,6 +541,21 @@ brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev) ADDR_INDIRECT); } +static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr) +{ + int bsscfgidx; + + for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) { + /* bsscfgidx 1 is reserved for legacy P2P */ + if (bsscfgidx == 1) + continue; + if (!drvr->iflist[bsscfgidx]) + return bsscfgidx; + } + + return -ENOMEM; +} + static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) { struct brcmf_mbss_ssid_le mbss_ssid_le; @@ -548,7 +563,7 @@ static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) int err; memset(_ssid_le, 0, sizeof(mbss_ssid_le)); - bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr); + bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr); if (bsscfgidx < 0) return bsscfgidx; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index b590499..6a76480 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -753,30 +753,6 @@ void brcmf_remove_interface(struct brcmf_if *ifp) brcmf_del_if(ifp->drvr, ifp->bsscfgidx); } -int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr) -{ - int ifidx; - int bsscfgidx; - bool available; - int highest; - - available = false; - bsscfgidx = 2; - highest = 2; - for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) { - if (drvr->iflist[ifidx]) { - if (drvr->iflist[ifidx]->bsscfgidx == bsscfgidx) - bsscfgidx = highest + 1; - else if (drvr->iflist[ifidx]->bsscfgidx > highest) - highest = drvr->iflist[ifidx]->bsscfgidx; - } else { - available = true; - } - } - - return available ? bsscfgidx : -ENOMEM; -} - #ifdef CONFIG_INET #define ARPOL_MAX_ENTRIES 8 static int brcmf_inetaddr_changed(struct notifier_block *nb, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index 647d3cc..2a075c5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -217,7 +217,6 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, bool is_p2pdev, char *name, u8 *mac_addr); void brcmf_remove_interface(struct brcmf_if *ifp);
[PATCH] Revert "platform/chrome: chromeos_laptop: Add Leon Touch"
This reverts commit bff3c624dc7261a084a4d25a0b09c3fb0fec872a. Board "Leon" is otherwise known as "Toshiba CB35" and we already have the entry that supports that board as of this commit : 963cb6f platform/chrome: chromeos_laptop - Add Toshiba CB35 Touch Remove this duplicate. Signed-off-by: Benson Leung--- drivers/platform/chrome/chromeos_laptop.c | 15 --- 1 file changed, 15 deletions(-) diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 8398a7d..e8a44a9 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -514,13 +514,6 @@ static struct chromeos_laptop cr48 = { }, }; -static struct chromeos_laptop leon = { - .i2c_peripherals = { - /* Touchpad. */ - { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, - }, -}; - #define _CBDD(board_) \ .callback = chromeos_laptop_dmi_matched, \ .driver_data = (void *)_ @@ -608,14 +601,6 @@ static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = { }, _CBDD(cr48), }, - { - .ident = "Leon", - .matches = { - DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), - DMI_MATCH(DMI_PRODUCT_NAME, "Leon"), - }, - _CBDD(leon), - }, { } }; MODULE_DEVICE_TABLE(dmi, chromeos_laptop_dmi_table); -- 2.8.0.rc3.226.g39d4020
[PATCH] Revert "platform/chrome: chromeos_laptop: Add Leon Touch"
This reverts commit bff3c624dc7261a084a4d25a0b09c3fb0fec872a. Board "Leon" is otherwise known as "Toshiba CB35" and we already have the entry that supports that board as of this commit : 963cb6f platform/chrome: chromeos_laptop - Add Toshiba CB35 Touch Remove this duplicate. Signed-off-by: Benson Leung --- drivers/platform/chrome/chromeos_laptop.c | 15 --- 1 file changed, 15 deletions(-) diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 8398a7d..e8a44a9 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -514,13 +514,6 @@ static struct chromeos_laptop cr48 = { }, }; -static struct chromeos_laptop leon = { - .i2c_peripherals = { - /* Touchpad. */ - { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, - }, -}; - #define _CBDD(board_) \ .callback = chromeos_laptop_dmi_matched, \ .driver_data = (void *)_ @@ -608,14 +601,6 @@ static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = { }, _CBDD(cr48), }, - { - .ident = "Leon", - .matches = { - DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"), - DMI_MATCH(DMI_PRODUCT_NAME, "Leon"), - }, - _CBDD(leon), - }, { } }; MODULE_DEVICE_TABLE(dmi, chromeos_laptop_dmi_table); -- 2.8.0.rc3.226.g39d4020