Tree/Branch: v3.18-rt
Git describe: v3.18.17-rt14-198-g1094c21
Commit: 1094c21471 Linux 3.18.18-rt15
Build Time: 111 min 27 sec
Passed: 9 / 9 (100.00 %)
Failed: 0 / 9 ( 0.00 %)
Errors: 0
Warnings: 39
Section Mismatches: 0
-------------------------------------------------------------------------------
defconfigs with issues (other than build errors):
18 warnings 0 mismatches : arm64-allmodconfig
2 warnings 0 mismatches : arm-multi_v5_defconfig
6 warnings 0 mismatches : arm-multi_v7_defconfig
6 warnings 0 mismatches : x86_64-defconfig
32 warnings 0 mismatches : arm-allmodconfig
4 warnings 0 mismatches : arm64-defconfig
-------------------------------------------------------------------------------
Warnings Summary: 39
8 ../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
6 ../net/core/sysctl_net_core.c:26:12: warning: 'one' defined but not used [-Wunused-variable]
6 ../arch/arm/include/asm/kmap_types.h:7:0: warning: "KM_TYPE_NR" redefined [enabled by default]
5 ../drivers/input/mouse/synaptics.c:152:3: warning: missing braces around initializer [-Wmissing-braces]
5 ../drivers/input/mouse/synaptics.c:152:3: warning: (near initialization for 'min_max_pnpid_table[3].board_id') [-Wmissing-braces]
3 ../drivers/media/v4l2-core/videobuf2-core.c:3224:26: warning: unused variable 'fileio' [-Wunused-variable]
2 ../drivers/scsi/ips.c:210:2: warning: #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" [-Wcpp]
2 ../drivers/net/ethernet/dec/tulip/winbond-840.c:910:2: warning: #warning Processor architecture undefined [-Wcpp]
1 ../include/linux/spinlock.h:372:2: warning: 'flags' may be used uninitialized in this function [-Wmaybe-uninitialized]
1 ../fs/btrfs/extent_io.c:2166:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/usb/renesas_usbhs/common.c:469:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1 ../drivers/usb/gadget/udc/udc-xilinx.c:2136:34: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1 ../drivers/usb/gadget/function/f_ncm.c:203:0: warning: "NCAPS" redefined
1 ../drivers/tty/isicom.c:1058:2: warning: integer overflow in expression [-Woverflow]
1 ../drivers/thermal/x86_pkg_temp_thermal.c:414:1: warning: no return statement in function returning non-void [-Wreturn-type]
1 ../drivers/staging/vt6655/device_main.c:2997:1: warning: the frame size of 1296 bytes is larger than 1024 bytes [-Wframe-larger-than=]
1 ../drivers/staging/bcm/CmHost.c:1564:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/staging/bcm/CmHost.c:1546:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/staging/bcm/CmHost.c:1503:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/pci/host/pcie-xilinx.c:154:3: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat]
1 ../drivers/net/ethernet/mellanox/mlx5/core/debugfs.c:467:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/net/ethernet/mellanox/mlx5/core/debugfs.c:307:11: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1 ../drivers/net/ethernet/mellanox/mlx5/core/debugfs.c:303:11: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1 ../drivers/net/ethernet/dec/tulip/tulip_core.c:101:2: warning: #warning Processor architecture undefined! [-Wcpp]
1 ../drivers/mtd/chips/cfi_cmdset_0020.c:651:1: warning: the frame size of 1224 bytes is larger than 1024 bytes [-Wframe-larger-than=]
1 ../drivers/isdn/hardware/mISDN/w6692.c:1181:2: warning: unsupported argument to '__builtin_return_address' [enabled by default]
1 ../drivers/isdn/hardware/mISDN/mISDNipac.c:759:2: warning: unsupported argument to '__builtin_return_address' [enabled by default]
1 ../drivers/iommu/intel-iommu.c:1749:25: warning: unused variable 'drhd' [-Wunused-variable]
1 ../drivers/infiniband/ulp/iser/iser_verbs.c:1206:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/infiniband/ulp/iser/iser_verbs.c:1201:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/infiniband/ulp/iser/iser_verbs.c:1175:31: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/infiniband/ulp/iser/iser_verbs.c:1174:33: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/infiniband/hw/qib/qib_qp.c:44:0: warning: "BITS_PER_PAGE" redefined
1 ../drivers/infiniband/hw/mlx5/mem.c:72:9: warning: comparison of distinct pointer types lacks a cast [enabled by default]
1 ../drivers/hsi/controllers/omap_ssi_port.c:1121:10: warning: 'err' may be used uninitialized in this function [-Wuninitialized]
1 ../drivers/block/drbd/drbd_bitmap.c:483:0: warning: "BITS_PER_PAGE_MASK" redefined
1 ../drivers/block/drbd/drbd_bitmap.c:482:0: warning: "BITS_PER_PAGE" redefined
1 ../crypto/wp512.c:987:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=]
1 ../arch/arm/mach-cns3xxx/pcie.c:313:1: warning: the frame size of 1072 bytes is larger than 1024 bytes [-Wframe-larger-than=]
===============================================================================
Detailed per-defconfig build reports below:
-------------------------------------------------------------------------------
arm64-allmodconfig : PASS, 0 errors, 18 warnings, 0 section mismatches
Warnings:
../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
../drivers/block/drbd/drbd_bitmap.c:482:0: warning: "BITS_PER_PAGE" redefined
../drivers/block/drbd/drbd_bitmap.c:483:0: warning: "BITS_PER_PAGE_MASK" redefined
../net/core/sysctl_net_core.c:26:12: warning: 'one' defined but not used [-Wunused-variable]
../drivers/input/mouse/synaptics.c:152:3: warning: missing braces around initializer [-Wmissing-braces]
../drivers/input/mouse/synaptics.c:152:3: warning: (near initialization for 'min_max_pnpid_table[3].board_id') [-Wmissing-braces]
../drivers/infiniband/hw/qib/qib_qp.c:44:0: warning: "BITS_PER_PAGE" redefined
../drivers/media/v4l2-core/videobuf2-core.c:3224:26: warning: unused variable 'fileio' [-Wunused-variable]
../drivers/net/ethernet/dec/tulip/winbond-840.c:910:2: warning: #warning Processor architecture undefined [-Wcpp]
../drivers/net/ethernet/dec/tulip/tulip_core.c:101:2: warning: #warning Processor architecture undefined! [-Wcpp]
../drivers/staging/bcm/CmHost.c:1503:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/staging/bcm/CmHost.c:1546:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/staging/bcm/CmHost.c:1564:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/scsi/ips.c:210:2: warning: #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" [-Wcpp]
../drivers/usb/gadget/function/f_ncm.c:203:0: warning: "NCAPS" redefined
../drivers/usb/gadget/udc/udc-xilinx.c:2136:34: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
../drivers/usb/renesas_usbhs/common.c:469:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
-------------------------------------------------------------------------------
arm-multi_v5_defconfig : PASS, 0 errors, 2 warnings, 0 section mismatches
Warnings:
../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
../net/core/sysctl_net_core.c:26:12: warning: 'one' defined but not used [-Wunused-variable]
-------------------------------------------------------------------------------
arm-multi_v7_defconfig : PASS, 0 errors, 6 warnings, 0 section mismatches
Warnings:
../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
../net/core/sysctl_net_core.c:26:12: warning: 'one' defined but not used [-Wunused-variable]
../drivers/input/mouse/synaptics.c:152:3: warning: missing braces around initializer [-Wmissing-braces]
../drivers/input/mouse/synaptics.c:152:3: warning: (near initialization for 'min_max_pnpid_table[3].board_id') [-Wmissing-braces]
../drivers/media/v4l2-core/videobuf2-core.c:3224:26: warning: unused variable 'fileio' [-Wunused-variable]
../include/linux/spinlock.h:372:2: warning: 'flags' may be used uninitialized in this function [-Wmaybe-uninitialized]
-------------------------------------------------------------------------------
x86_64-defconfig : PASS, 0 errors, 6 warnings, 0 section mismatches
Warnings:
../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
../net/core/sysctl_net_core.c:26:12: warning: 'one' defined but not used [-Wunused-variable]
../drivers/input/mouse/synaptics.c:152:3: warning: missing braces around initializer [-Wmissing-braces]
../drivers/input/mouse/synaptics.c:152:3: warning: (near initialization for 'min_max_pnpid_table[3].board_id') [-Wmissing-braces]
../drivers/iommu/intel-iommu.c:1749:25: warning: unused variable 'drhd' [-Wunused-variable]
../drivers/thermal/x86_pkg_temp_thermal.c:414:1: warning: no return statement in function returning non-void [-Wreturn-type]
-------------------------------------------------------------------------------
arm-allmodconfig : PASS, 0 errors, 32 warnings, 0 section mismatches
Warnings:
../arch/arm/mach-cns3xxx/pcie.c:313:1: warning: the frame size of 1072 bytes is larger than 1024 bytes [-Wframe-larger-than=]
../crypto/wp512.c:987:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=]
../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
../fs/btrfs/extent_io.c:2166:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../net/core/sysctl_net_core.c:26:12: warning: 'one' defined but not used [-Wunused-variable]
../drivers/hsi/controllers/omap_ssi_port.c:1121:10: warning: 'err' may be used uninitialized in this function [-Wuninitialized]
../arch/arm/include/asm/kmap_types.h:7:0: warning: "KM_TYPE_NR" redefined [enabled by default]
../drivers/infiniband/hw/mlx5/mem.c:72:9: warning: comparison of distinct pointer types lacks a cast [enabled by default]
../drivers/input/mouse/synaptics.c:152:3: warning: missing braces around initializer [-Wmissing-braces]
../drivers/input/mouse/synaptics.c:152:3: warning: (near initialization for 'min_max_pnpid_table[3].board_id') [-Wmissing-braces]
../drivers/infiniband/ulp/iser/iser_verbs.c:1174:33: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/infiniband/ulp/iser/iser_verbs.c:1175:31: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/infiniband/ulp/iser/iser_verbs.c:1201:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/infiniband/ulp/iser/iser_verbs.c:1206:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/isdn/hardware/mISDN/w6692.c:1181:2: warning: unsupported argument to '__builtin_return_address' [enabled by default]
../drivers/isdn/hardware/mISDN/mISDNipac.c:759:2: warning: unsupported argument to '__builtin_return_address' [enabled by default]
../drivers/mtd/chips/cfi_cmdset_0020.c:651:1: warning: the frame size of 1224 bytes is larger than 1024 bytes [-Wframe-larger-than=]
../drivers/pci/host/pcie-xilinx.c:154:3: warning: format '%d' expects argument of type 'int', but argument 4 has type 'long unsigned int' [-Wformat]
../drivers/media/v4l2-core/videobuf2-core.c:3224:26: warning: unused variable 'fileio' [-Wunused-variable]
../drivers/net/ethernet/dec/tulip/winbond-840.c:910:2: warning: #warning Processor architecture undefined [-Wcpp]
../arch/arm/include/asm/kmap_types.h:7:0: warning: "KM_TYPE_NR" redefined [enabled by default]
../arch/arm/include/asm/kmap_types.h:7:0: warning: "KM_TYPE_NR" redefined [enabled by default]
../arch/arm/include/asm/kmap_types.h:7:0: warning: "KM_TYPE_NR" redefined [enabled by default]
../arch/arm/include/asm/kmap_types.h:7:0: warning: "KM_TYPE_NR" redefined [enabled by default]
../drivers/net/ethernet/mellanox/mlx5/core/debugfs.c:303:11: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
../drivers/net/ethernet/mellanox/mlx5/core/debugfs.c:307:11: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
../drivers/net/ethernet/mellanox/mlx5/core/debugfs.c:467:46: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../arch/arm/include/asm/kmap_types.h:7:0: warning: "KM_TYPE_NR" redefined [enabled by default]
../drivers/tty/isicom.c:1058:2: warning: integer overflow in expression [-Woverflow]
../drivers/scsi/ips.c:210:2: warning: #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" [-Wcpp]
../drivers/staging/vt6655/device_main.c:2997:1: warning: the frame size of 1296 bytes is larger than 1024 bytes [-Wframe-larger-than=]
-------------------------------------------------------------------------------
arm64-defconfig : PASS, 0 errors, 4 warnings, 0 section mismatches
Warnings:
../block/blk-core.c:103:5: warning: "CONFIG_PREEMPT_RT_FULL" is not defined [-Wundef]
../net/core/sysctl_net_core.c:26:12: warning: 'one' defined but not used [-Wunused-variable]
../drivers/input/mouse/synaptics.c:152:3: warning: missing braces around initializer [-Wmissing-braces]
../drivers/input/mouse/synaptics.c:152:3: warning: (near initialization for 'min_max_pnpid_table[3].board_id') [-Wmissing-braces]
-------------------------------------------------------------------------------
Passed with no errors, warnings or mismatches:
x86_64-allnoconfig
arm64-allnoconfig
arm-allnoconfig
close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr
Hi Olof,
This series migrates ARM clockevent drivers (present in arch/arm/
directory), to the new set-state interface. This would enable these
drivers to use new states (like: ONESHOT_STOPPED, etc.) of a clockevent
device (if required), as the set-mode interface is marked obsolete now
and wouldn't be expanded to handle new states.
--
viresh
The following changes since commit bc0195aad0daa2ad5b0d76cce22b167bc3435590:
Linux 4.2-rc2 (2015-07-12 15:10:30 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/linux.git ARM/clkevt/set-state-4.3
for you to fetch changes up to 10dca88a4be632678088f5cbc20b54c2113ecb91:
ARM/orion/time: Migrate to new 'set-state' interface (2015-07-17 08:29:44 +0530)
----------------------------------------------------------------
Viresh Kumar (18):
ARM/smp_twd: Migrate to new 'set-state' interface
ARM/cns3xxx/timer: Migrate to new 'set-state' interface
ARM/davinci/time: Migrate to new 'set-state' interface
ARM/dc21285-timer: Migrate to new 'set-state' interface
ARM/gemini/time: Migrate to new 'set-state' interface
ARM/imx/epit: Migrate to new 'set-state' interface
ARM/ixp4xx/timer: Migrate to new 'set-state' interface
ARM/ks8695/time: Migrate to new 'set-state' interface
ARM/lpc32xx/timer: Migrate to new 'set-state' interface
ARM/mmp/time: Migrate to new 'set-state' interface
ARM/netx/time: Migrate to new 'set-state' interface
ARM/omap1/time: Migrate to new 'set-state' interface
ARM/omap1/timer32: Migrate to new 'set-state' interface
ARM/omap2/timer: Migrate to new 'set-state' interface
ARM/SPEAr/time: Migrate to new 'set-state' interface
ARM/w90x900/time: Migrate to new 'set-state' interface
ARM/iop/time: Migrate to new 'set-state' interface
ARM/orion/time: Migrate to new 'set-state' interface
arch/arm/kernel/smp_twd.c | 48 +++++++++--------
arch/arm/mach-cns3xxx/core.c | 55 ++++++++++---------
arch/arm/mach-davinci/time.c | 54 ++++++++++---------
arch/arm/mach-footbridge/dc21285-timer.c | 48 ++++++++---------
arch/arm/mach-gemini/time.c | 69 ++++++++++++------------
arch/arm/mach-imx/epit.c | 67 ++++++++++++-----------
arch/arm/mach-ixp4xx/common.c | 68 +++++++++++++----------
arch/arm/mach-ks8695/time.c | 43 ++++++++-------
arch/arm/mach-lpc32xx/timer.c | 40 +++++---------
arch/arm/mach-mmp/time.c | 29 ++++------
arch/arm/mach-netx/time.c | 61 +++++++++++----------
arch/arm/mach-omap1/time.c | 35 ++++++------
arch/arm/mach-omap1/timer32k.c | 33 ++++++------
arch/arm/mach-omap2/timer.c | 48 ++++++++---------
arch/arm/mach-spear/time.c | 89 ++++++++++++++++--------------
arch/arm/mach-w90x900/time.c | 51 ++++++++++--------
arch/arm/plat-iop/time.c | 70 ++++++++++++++----------
arch/arm/plat-orion/time.c | 93 ++++++++++++++++----------------
18 files changed, 522 insertions(+), 479 deletions(-)
--
2.4.0
Consider a dual core (0/1) system with two CPUs:
- sharing clock/voltage rails and hence cpufreq-policy
- CPU1 is offline while the cpufreq driver is registered
- cpufreq_add_dev() is called from subsys callback for CPU0 and we
create the policy for the group of CPUs and create links for all
present CPUs, i.e. CPU1 as well.
- cpufreq_add_dev() is called from subsys callback for CPU1, we find
that the cpu is offline and we try to create a sysfs link for CPU1.
This results in double addtion of the sysfs link and we will get this:
WARNING: CPU: 0 PID: 1 at fs/sysfs/dir.c:31 sysfs_warn_dup+0x60/0x7c()
sysfs: cannot create duplicate filename '/devices/system/cpu/cpu1/cpufreq'
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.2.0-rc2+ #1704
Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
Backtrace:
[<c0013248>] (dump_backtrace) from [<c00133e4>] (show_stack+0x18/0x1c)
r6:c01a1f30 r5:0000001f r4:00000000 r3:00000000
[<c00133cc>] (show_stack) from [<c076920c>] (dump_stack+0x7c/0x98)
[<c0769190>] (dump_stack) from [<c0029ab4>] (warn_slowpath_common+0x80/0xbc)
r4:d74abbd0 r3:d74c0000
[<c0029a34>] (warn_slowpath_common) from [<c0029b94>] (warn_slowpath_fmt+0x38/0x40)
r8:ffffffef r7:00000000 r6:d75a8960 r5:c0993280 r4:d6b4d000
[<c0029b60>] (warn_slowpath_fmt) from [<c01a1f30>] (sysfs_warn_dup+0x60/0x7c)
r3:d6b4dfe7 r2:c0930750
[<c01a1ed0>] (sysfs_warn_dup) from [<c01a22c8>] (sysfs_do_create_link_sd+0xb8/0xc0)
r6:d75a8960 r5:c0993280 r4:d00aba20
[<c01a2210>] (sysfs_do_create_link_sd) from [<c01a22fc>] (sysfs_create_link+0x2c/0x3c)
r10:00000001 r8:c14db3c8 r7:d7b89010 r6:c0ae7c60 r5:d7b89010 r4:d00d1200
[<c01a22d0>] (sysfs_create_link) from [<c0506160>] (add_cpu_dev_symlink+0x34/0x5c)
[<c050612c>] (add_cpu_dev_symlink) from [<c05084d0>] (cpufreq_add_dev+0x674/0x794)
r5:00000001 r4:00000000
[<c0507e5c>] (cpufreq_add_dev) from [<c03db114>] (subsys_interface_register+0x8c/0xd0)
r10:00000003 r9:d7bb01f0 r8:c14db3c8 r7:00106738 r6:c0ae7c60 r5:c0acbd08
r4:c0ae7e20
[<c03db088>] (subsys_interface_register) from [<c0508a2c>] (cpufreq_register_driver+0x104/0x1f4)
The check for offline-cpu in cpufreq_add_dev() is to ensure that link
gets added for the CPUs which weren't physically present earlier and
that misses the case where a CPU is offline while registering the
driver.
To fix this properly, don't create these links when the policy get
initialized. Rather wait for individual subsys callback for CPUs to
add/remove these links. This simplifies most of the code leaving
cpufreq_remove_dev().
The problem is that, we might remove cpu which was owner of policy->kobj
in sysfs, before other CPUs are removed. Fix this by the solution we
have been using until very recently, in which we move the kobject to any
other CPU, for which remove is yet to be called.
Tested on dual core exynos board with cpufreq-dt driver. The driver was
compiled as module and inserted/removed multiple times on a running
kernel.
Fixes: 87549141d516 ("cpufreq: Stop migrating sysfs files on hotplug")
Reported-and-suggested-by: Russell King <linux(a)arm.linux.org.uk>
Signed-off-by: Viresh Kumar <viresh.kumar(a)linaro.org>
---
V1->V2: Completely changed, please review again :)
@Rafael: I didn't review your solution and gave this one because I
thought Russell suggested the right thing. i.e. don't create links in
the beginning.
This is based of 4.2-rc3 and so your other patch,
https://patchwork.kernel.org/patch/6839031/ has to be rebased over it.
I didn't rebase this patch over yours for two reasons:
- Yours wasn't necessarily 4.2 material.
- I already mentioned a problem in that patch.
@Russell: I hope this will look much better than V1 to you. Please give
it a try once you get some time.
drivers/cpufreq/cpufreq.c | 165 ++++++++++++++++++----------------------------
include/linux/cpufreq.h | 1 +
2 files changed, 65 insertions(+), 101 deletions(-)
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 26063afb3eba..81c2417e52f4 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -966,67 +966,6 @@ void cpufreq_sysfs_remove_file(const struct attribute *attr)
}
EXPORT_SYMBOL(cpufreq_sysfs_remove_file);
-static int add_cpu_dev_symlink(struct cpufreq_policy *policy, int cpu)
-{
- struct device *cpu_dev;
-
- pr_debug("%s: Adding symlink for CPU: %u\n", __func__, cpu);
-
- if (!policy)
- return 0;
-
- cpu_dev = get_cpu_device(cpu);
- if (WARN_ON(!cpu_dev))
- return 0;
-
- return sysfs_create_link(&cpu_dev->kobj, &policy->kobj, "cpufreq");
-}
-
-static void remove_cpu_dev_symlink(struct cpufreq_policy *policy, int cpu)
-{
- struct device *cpu_dev;
-
- pr_debug("%s: Removing symlink for CPU: %u\n", __func__, cpu);
-
- cpu_dev = get_cpu_device(cpu);
- if (WARN_ON(!cpu_dev))
- return;
-
- sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
-}
-
-/* Add/remove symlinks for all related CPUs */
-static int cpufreq_add_dev_symlink(struct cpufreq_policy *policy)
-{
- unsigned int j;
- int ret = 0;
-
- /* Some related CPUs might not be present (physically hotplugged) */
- for_each_cpu_and(j, policy->related_cpus, cpu_present_mask) {
- if (j == policy->kobj_cpu)
- continue;
-
- ret = add_cpu_dev_symlink(policy, j);
- if (ret)
- break;
- }
-
- return ret;
-}
-
-static void cpufreq_remove_dev_symlink(struct cpufreq_policy *policy)
-{
- unsigned int j;
-
- /* Some related CPUs might not be present (physically hotplugged) */
- for_each_cpu_and(j, policy->related_cpus, cpu_present_mask) {
- if (j == policy->kobj_cpu)
- continue;
-
- remove_cpu_dev_symlink(policy, j);
- }
-}
-
static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
struct device *dev)
{
@@ -1057,7 +996,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
return ret;
}
- return cpufreq_add_dev_symlink(policy);
+ return 0;
}
static void cpufreq_init_policy(struct cpufreq_policy *policy)
@@ -1163,11 +1102,14 @@ static struct cpufreq_policy *cpufreq_policy_alloc(struct device *dev)
if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
goto err_free_cpumask;
+ if (!zalloc_cpumask_var(&policy->symlinks, GFP_KERNEL))
+ goto err_free_related_cpumask;
+
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq, &dev->kobj,
"cpufreq");
if (ret) {
pr_err("%s: failed to init policy->kobj: %d\n", __func__, ret);
- goto err_free_rcpumask;
+ goto err_free_symlink_cpumask;
}
INIT_LIST_HEAD(&policy->policy_list);
@@ -1184,7 +1126,9 @@ static struct cpufreq_policy *cpufreq_policy_alloc(struct device *dev)
return policy;
-err_free_rcpumask:
+err_free_symlink_cpumask:
+ free_cpumask_var(policy->symlinks);
+err_free_related_cpumask:
free_cpumask_var(policy->related_cpus);
err_free_cpumask:
free_cpumask_var(policy->cpus);
@@ -1204,7 +1148,6 @@ static void cpufreq_policy_put_kobj(struct cpufreq_policy *policy, bool notify)
CPUFREQ_REMOVE_POLICY, policy);
down_write(&policy->rwsem);
- cpufreq_remove_dev_symlink(policy);
kobj = &policy->kobj;
cmp = &policy->kobj_unregister;
up_write(&policy->rwsem);
@@ -1234,6 +1177,7 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy, bool notify)
write_unlock_irqrestore(&cpufreq_driver_lock, flags);
cpufreq_policy_put_kobj(policy, notify);
+ free_cpumask_var(policy->symlinks);
free_cpumask_var(policy->related_cpus);
free_cpumask_var(policy->cpus);
kfree(policy);
@@ -1252,26 +1196,37 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
{
unsigned int j, cpu = dev->id;
int ret = -ENOMEM;
- struct cpufreq_policy *policy;
+ struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
unsigned long flags;
bool recover_policy = !sif;
pr_debug("adding CPU %u\n", cpu);
+ /* sysfs links are only created on subsys callback */
+ if (sif && policy) {
+ pr_debug("%s: Adding symlink for CPU: %u\n", __func__, cpu);
+ ret = sysfs_create_link(&dev->kobj, &policy->kobj, "cpufreq");
+ if (ret) {
+ dev_err(dev, "%s: Failed to create link for cpu %d (%d)\n",
+ __func__, cpu, ret);
+ return ret;
+ }
+
+ /* Track CPUs for which sysfs links are created */
+ cpumask_set_cpu(cpu, policy->symlinks);
+ }
+
/*
- * Only possible if 'cpu' wasn't physically present earlier and we are
- * here from subsys_interface add callback. A hotplug notifier will
- * follow and we will handle it like logical CPU hotplug then. For now,
- * just create the sysfs link.
+ * A hotplug notifier will follow and we will take care of rest
+ * of the initialization then.
*/
if (cpu_is_offline(cpu))
- return add_cpu_dev_symlink(per_cpu(cpufreq_cpu_data, cpu), cpu);
+ return 0;
if (!down_read_trylock(&cpufreq_rwsem))
return 0;
/* Check if this CPU already has a policy to manage it */
- policy = per_cpu(cpufreq_cpu_data, cpu);
if (policy && !policy_is_inactive(policy)) {
WARN_ON(!cpumask_test_cpu(cpu, policy->related_cpus));
ret = cpufreq_add_policy_cpu(policy, cpu, dev);
@@ -1506,10 +1461,6 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
if (cpufreq_driver->exit)
cpufreq_driver->exit(policy);
- /* Free the policy only if the driver is getting removed. */
- if (sif)
- cpufreq_policy_free(policy, true);
-
return 0;
}
@@ -1521,42 +1472,54 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
{
unsigned int cpu = dev->id;
+ struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
int ret;
- /*
- * Only possible if 'cpu' is getting physically removed now. A hotplug
- * notifier should have already been called and we just need to remove
- * link or free policy here.
- */
- if (cpu_is_offline(cpu)) {
- struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
- struct cpumask mask;
+ if (!policy)
+ return 0;
- if (!policy)
- return 0;
+ if (cpu_online(cpu)) {
+ ret = __cpufreq_remove_dev_prepare(dev, sif);
+ if (!ret)
+ ret = __cpufreq_remove_dev_finish(dev, sif);
+ if (ret)
+ return ret;
+ }
- cpumask_copy(&mask, policy->related_cpus);
- cpumask_clear_cpu(cpu, &mask);
+ /* sysfs links are removed only on subsys callback */
+ if (cpumask_test_cpu(cpu, policy->symlinks)) {
+ dev_dbg(dev, "%s: Removing symlink for CPU: %u\n", __func__,
+ cpu);
+ cpumask_clear_cpu(cpu, policy->symlinks);
+ sysfs_remove_link(&dev->kobj, "cpufreq");
+ return 0;
+ }
+ if (cpumask_weight(policy->symlinks)) {
/*
- * Free policy only if all policy->related_cpus are removed
- * physically.
+ * Okay, we still have some CPUs left. Transfer the ownership of
+ * policy to one of them. Would be better to pass that to
+ * cpumask_last() as that will be the last CPU to get removed,
+ * but there is no API to get last cpu of the mask. Lets move it
+ * to the first cpu in the mask.
*/
- if (cpumask_intersects(&mask, cpu_present_mask)) {
- remove_cpu_dev_symlink(policy, cpu);
- return 0;
- }
+ int new_cpu = cpumask_first(policy->symlinks);
+ struct device *new_dev = get_cpu_device(new_cpu);
- cpufreq_policy_free(policy, true);
- return 0;
- }
+ dev_dbg(dev, "%s: Migrating kobj from %d to %d\n", __func__,
+ cpu, new_cpu);
- ret = __cpufreq_remove_dev_prepare(dev, sif);
+ cpumask_clear_cpu(new_cpu, policy->symlinks);
+ sysfs_remove_link(&new_dev->kobj, "cpufreq");
- if (!ret)
- ret = __cpufreq_remove_dev_finish(dev, sif);
+ policy->kobj_cpu = new_cpu;
+ WARN_ON(kobject_move(&policy->kobj, &new_dev->kobj));
+ } else {
+ /* This is the last CPU to be removed */
+ cpufreq_policy_free(policy, true);
+ }
- return ret;
+ return 0;
}
static void handle_update(struct work_struct *work)
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
index 29ad97c34fd5..c748d1cd0815 100644
--- a/include/linux/cpufreq.h
+++ b/include/linux/cpufreq.h
@@ -62,6 +62,7 @@ struct cpufreq_policy {
/* CPUs sharing clock, require sw coordination */
cpumask_var_t cpus; /* Online CPUs only */
cpumask_var_t related_cpus; /* Online + Offline CPUs */
+ cpumask_var_t symlinks; /* CPUs for which cpufreq sysfs directory is present */
unsigned int shared_type; /* ACPI: ANY or ALL affected CPUs
should set cpufreq */
--
2.4.0
Tree/Branch: v4.1.3
Git describe: v4.1.3
Commit: c8bde72f9a Linux 4.1.3
Build Time: 96 min 55 sec
Passed: 9 / 9 (100.00 %)
Failed: 0 / 9 ( 0.00 %)
Errors: 0
Warnings: 23
Section Mismatches: 1
-------------------------------------------------------------------------------
defconfigs with issues (other than build errors):
12 warnings 3 mismatches : arm64-allmodconfig
2 warnings 0 mismatches : arm-multi_v7_defconfig
10 warnings 0 mismatches : arm-allmodconfig
-------------------------------------------------------------------------------
Warnings Summary: 23
2 ../drivers/scsi/ips.c:210:2: warning: #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" [-Wcpp]
1 ../sound/soc/samsung/dmaengine.c:60:31: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../sound/soc/samsung/dmaengine.c:53:32: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../net/bluetooth/mgmt.c:6463:8: warning: 'r192' may be used uninitialized in this function [-Wmaybe-uninitialized]
1 ../net/bluetooth/mgmt.c:6463:8: warning: 'h192' may be used uninitialized in this function [-Wmaybe-uninitialized]
1 ../kernel/acct.c:174:2: warning: value computed is not used [-Wunused-value]
1 ../include/trace/ftrace.h:28:0: warning: "TRACE_SYSTEM_STRING" redefined [enabled by default]
1 ../drivers/usb/renesas_usbhs/common.c:492:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1 ../drivers/rtc/rtc-armada38x.c:91:22: warning: unused variable 'flags' [-Wunused-variable]
1 ../drivers/net/ethernet/dec/tulip/winbond-840.c:910:2: warning: #warning Processor architecture undefined [-Wcpp]
1 ../drivers/net/ethernet/dec/tulip/tulip_core.c:101:2: warning: #warning Processor architecture undefined! [-Wcpp]
1 ../drivers/mtd/chips/cfi_cmdset_0020.c:651:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=]
1 ../drivers/mmc/host/sh_mmcif.c:402:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/mmc/host/sh_mmcif.c:401:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
1 ../drivers/media/platform/coda/./trace.h:12:0: warning: "TRACE_SYSTEM_STRING" redefined [enabled by default]
1 ../drivers/infiniband/hw/qib/qib_qp.c:44:0: warning: "BITS_PER_PAGE" redefined
1 ../drivers/infiniband/hw/cxgb4/mem.c:147:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1 ../drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm204.c:975:1: warning: the frame size of 1208 bytes is larger than 1024 bytes [-Wframe-larger-than=]
1 ../drivers/gpio/gpio-74xx-mmio.c:132:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
1 ../drivers/block/drbd/drbd_bitmap.c:483:0: warning: "BITS_PER_PAGE_MASK" redefined
1 ../drivers/block/drbd/drbd_bitmap.c:482:0: warning: "BITS_PER_PAGE" redefined
1 ../crypto/wp512.c:987:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=]
1 ../arch/arm/mach-cns3xxx/pcie.c:266:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=]
Section Mismatch Summary: 1
3 WARNING: drivers/staging/fsl-mc/bus/mc-bus-driver.o(.init.text+0x18c): Section mismatch in reference from the function init_module() to the function .exit.text:dprc_driver_exit()
===============================================================================
Detailed per-defconfig build reports below:
-------------------------------------------------------------------------------
arm64-allmodconfig : PASS, 0 errors, 12 warnings, 3 section mismatches
Warnings:
../drivers/block/drbd/drbd_bitmap.c:482:0: warning: "BITS_PER_PAGE" redefined
../drivers/block/drbd/drbd_bitmap.c:483:0: warning: "BITS_PER_PAGE_MASK" redefined
../drivers/gpio/gpio-74xx-mmio.c:132:16: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
../sound/soc/samsung/dmaengine.c:53:32: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../sound/soc/samsung/dmaengine.c:60:31: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/infiniband/hw/qib/qib_qp.c:44:0: warning: "BITS_PER_PAGE" redefined
../drivers/mmc/host/sh_mmcif.c:401:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/mmc/host/sh_mmcif.c:402:4: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
../drivers/net/ethernet/dec/tulip/winbond-840.c:910:2: warning: #warning Processor architecture undefined [-Wcpp]
../drivers/net/ethernet/dec/tulip/tulip_core.c:101:2: warning: #warning Processor architecture undefined! [-Wcpp]
../drivers/scsi/ips.c:210:2: warning: #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" [-Wcpp]
../drivers/usb/renesas_usbhs/common.c:492:25: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
Section Mismatches:
WARNING: drivers/staging/fsl-mc/bus/mc-bus-driver.o(.init.text+0x18c): Section mismatch in reference from the function init_module() to the function .exit.text:dprc_driver_exit()
WARNING: drivers/staging/fsl-mc/bus/mc-bus-driver.o(.init.text+0x18c): Section mismatch in reference from the function init_module() to the function .exit.text:dprc_driver_exit()
WARNING: drivers/staging/fsl-mc/bus/mc-bus-driver.o(.init.text+0x18c): Section mismatch in reference from the function init_module() to the function .exit.text:dprc_driver_exit()
-------------------------------------------------------------------------------
arm-multi_v7_defconfig : PASS, 0 errors, 2 warnings, 0 section mismatches
Warnings:
../net/bluetooth/mgmt.c:6463:8: warning: 'r192' may be used uninitialized in this function [-Wmaybe-uninitialized]
../net/bluetooth/mgmt.c:6463:8: warning: 'h192' may be used uninitialized in this function [-Wmaybe-uninitialized]
-------------------------------------------------------------------------------
arm-allmodconfig : PASS, 0 errors, 10 warnings, 0 section mismatches
Warnings:
../arch/arm/mach-cns3xxx/pcie.c:266:1: warning: the frame size of 1088 bytes is larger than 1024 bytes [-Wframe-larger-than=]
../crypto/wp512.c:987:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=]
../kernel/acct.c:174:2: warning: value computed is not used [-Wunused-value]
../drivers/infiniband/hw/cxgb4/mem.c:147:20: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
../drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm204.c:975:1: warning: the frame size of 1208 bytes is larger than 1024 bytes [-Wframe-larger-than=]
../drivers/mtd/chips/cfi_cmdset_0020.c:651:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=]
../include/trace/ftrace.h:28:0: warning: "TRACE_SYSTEM_STRING" redefined [enabled by default]
../drivers/media/platform/coda/./trace.h:12:0: warning: "TRACE_SYSTEM_STRING" redefined [enabled by default]
../drivers/rtc/rtc-armada38x.c:91:22: warning: unused variable 'flags' [-Wunused-variable]
../drivers/scsi/ips.c:210:2: warning: #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" [-Wcpp]
-------------------------------------------------------------------------------
Passed with no errors, warnings or mismatches:
arm64-allnoconfig
arm-multi_v5_defconfig
x86_64-defconfig
arm-allnoconfig
x86_64-allnoconfig
arm64-defconfig
The existing alternative_insn macro has some limitations that make it
hard to work with. In partiuclar the fact it takes instructions from it
own macro arguments means it doesn't play very nicely with C pre-processor
macros because the macro arguments look like a string to the C
pre-processor. Workarounds are (probably) possible but things start to
look ugly.
Introduce an alternative set of macros that allows instructions to be
presented to the assembler as normal and switch everything over to the
new macros.
Signed-off-by: Daniel Thompson <daniel.thompson(a)linaro.org>
---
Notes:
To be honest these if not/else/endif macros are simply more readable
than the original macro and that might be enough to justify them on
their own. However below is an example that is needlessly hard to
write without them because ICC_PMR_EL1 is a C pre-processor macro.
.macro disable_irq, tmp
mov \tmp, #ICC_PMR_EL1_MASKED
alternative_if_not ARM64_HAS_SYSREG_GIC_CPUIF
msr daifset, #2
alternative_else
msr_s ICC_PMR_EL1, \tmp
alternative_endif
.endm
The new macros have received a fair degree of testing because I have
based my (not published since March) pseudo-NMI patch set on them.
arch/arm64/include/asm/alternative.h | 18 ++++++++++++------
arch/arm64/kernel/entry.S | 29 +++++++++++++----------------
arch/arm64/kvm/hyp.S | 12 ++++++++++--
arch/arm64/mm/cache.S | 7 ++++++-
4 files changed, 41 insertions(+), 25 deletions(-)
diff --git a/arch/arm64/include/asm/alternative.h b/arch/arm64/include/asm/alternative.h
index c385a0c4057f..8c8cdfac7251 100644
--- a/arch/arm64/include/asm/alternative.h
+++ b/arch/arm64/include/asm/alternative.h
@@ -65,13 +65,19 @@ void free_alternatives_memory(void);
.byte \alt_len
.endm
-.macro alternative_insn insn1 insn2 cap
-661: \insn1
-662: .pushsection .altinstructions, "a"
- altinstruction_entry 661b, 663f, \cap, 662b-661b, 664f-663f
+.macro alternative_if_not cap
+ .pushsection .altinstructions, "a"
+ altinstruction_entry 661f, 663f, \cap, 662f-661f, 664f-663f
.popsection
- .pushsection .altinstr_replacement, "ax"
-663: \insn2
+661:
+.endm
+
+.macro alternative_else
+662: .pushsection .altinstr_replacement, "ax"
+663:
+.endm
+
+.macro alternative_endif
664: .popsection
.org . - (664b-663b) + (662b-661b)
.org . - (662b-661b) + (664b-663b)
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index a7691a378668..be8a70d4028c 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -122,26 +122,23 @@
ct_user_enter
ldr x23, [sp, #S_SP] // load return stack pointer
msr sp_el0, x23
-
#ifdef CONFIG_ARM64_ERRATUM_845719
-
-#undef SEQUENCE_ORG
-#undef SEQUENCE_ALT
-
+alternative_if_not ARM64_WORKAROUND_845719
+ nop
+ nop
#ifdef CONFIG_PID_IN_CONTEXTIDR
-
-#define SEQUENCE_ORG "nop ; nop ; nop"
-#define SEQUENCE_ALT "tbz x22, #4, 1f ; mrs x29, contextidr_el1; msr contextidr_el1, x29; 1:"
-
+ nop
+#endif
+alternative_else
+ tbz x22, #4, 1f
+#ifdef CONFIG_PID_IN_CONTEXTIDR
+ mrs x29, contextidr_el1
+ msr contextidr_el1, x29
#else
-
-#define SEQUENCE_ORG "nop ; nop"
-#define SEQUENCE_ALT "tbz x22, #4, 1f ; msr contextidr_el1, xzr; 1:"
-
+ msr contextidr_el1, xzr
#endif
-
- alternative_insn SEQUENCE_ORG, SEQUENCE_ALT, ARM64_WORKAROUND_845719
-
+1:
+alternative_endif
#endif
.endif
msr elr_el1, x21 // set up the return data
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 17a8fb14f428..10915aaf0b01 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -810,7 +810,11 @@
* Call into the vgic backend for state saving
*/
.macro save_vgic_state
- alternative_insn "bl __save_vgic_v2_state", "bl __save_vgic_v3_state", ARM64_HAS_SYSREG_GIC_CPUIF
+alternative_if_not ARM64_HAS_SYSREG_GIC_CPUIF
+ bl __save_vgic_v2_state
+alternative_else
+ bl __save_vgic_v3_state
+alternative_endif
mrs x24, hcr_el2
mov x25, #HCR_INT_OVERRIDE
neg x25, x25
@@ -827,7 +831,11 @@
orr x24, x24, #HCR_INT_OVERRIDE
orr x24, x24, x25
msr hcr_el2, x24
- alternative_insn "bl __restore_vgic_v2_state", "bl __restore_vgic_v3_state", ARM64_HAS_SYSREG_GIC_CPUIF
+alternative_if_not ARM64_HAS_SYSREG_GIC_CPUIF
+ bl __restore_vgic_v2_state
+alternative_else
+ bl __restore_vgic_v3_state
+alternative_endif
.endm
.macro save_timer_state
diff --git a/arch/arm64/mm/cache.S b/arch/arm64/mm/cache.S
index bdeb5d38c2dd..eb48d5df4a0f 100644
--- a/arch/arm64/mm/cache.S
+++ b/arch/arm64/mm/cache.S
@@ -143,7 +143,12 @@ __dma_clean_range:
dcache_line_size x2, x3
sub x3, x2, #1
bic x0, x0, x3
-1: alternative_insn "dc cvac, x0", "dc civac, x0", ARM64_WORKAROUND_CLEAN_CACHE
+1:
+alternative_if_not ARM64_WORKAROUND_CLEAN_CACHE
+ dc cvac, x0
+alternative_else
+ dc civac, x0
+alternative_endif
add x0, x0, x2
cmp x0, x1
b.lo 1b
--
2.4.3