diff --git a/Documentation/ABI/testing/OWNERS b/Documentation/ABI/testing/OWNERS deleted file mode 100644 index 75edfd5b3a32..000000000000 --- a/Documentation/ABI/testing/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/Documentation/ABI/testing/OWNERS diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 8a2e377b0dde..1a9b6ac22c38 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -648,3 +648,21 @@ Description: SPURR ticks for cpuX when it was idle. This sysfs interface exposes the number of SPURR ticks for cpuX when it was idle. + +What: /sys/devices/system/cpu/cpuX/mte_tcf_preferred +Date: July 2021 +Contact: Linux ARM Kernel Mailing list +Description: Preferred MTE tag checking mode + + When a user program specifies more than one MTE tag checking + mode, this sysfs node is used to specify which mode should + be preferred when running on that CPU. Possible values: + + ================ ============================================== + "sync" Prefer synchronous mode + "async" Prefer asynchronous mode + ================ ============================================== + + Changes to this sysfs node may not take effect immediately. + + See also: Documentation/arm64/memory-tagging-extension.rst diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs index adc0d0e91607..f276b38287f8 100644 --- a/Documentation/ABI/testing/sysfs-driver-ufs +++ b/Documentation/ABI/testing/sysfs-driver-ufs @@ -987,6 +987,132 @@ Description: This entry shows the target state of an UFS UIC link The file is read only. +What: /sys/bus/platform/drivers/ufshcd/*/monitor/monitor_enable +Date: January 2021 +Contact: Can Guo +Description: This file shows the status of performance monitor enablement + and it can be used to start/stop the monitor. When the monitor + is stopped, the performance data collected is also cleared. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/monitor_chunk_size +Date: January 2021 +Contact: Can Guo +Description: This file tells the monitor to focus on requests transferring + data of specific chunk size (in Bytes). 0 means any chunk size. + It can only be changed when monitor is disabled. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_total_sectors +Date: January 2021 +Contact: Can Guo +Description: This file shows how many sectors (in 512 Bytes) have been + sent from device to host after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_total_busy +Date: January 2021 +Contact: Can Guo +Description: This file shows how long (in micro seconds) has been spent + sending data from device to host after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_nr_requests +Date: January 2021 +Contact: Can Guo +Description: This file shows how many read requests have been sent after + monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_max +Date: January 2021 +Contact: Can Guo +Description: This file shows the maximum latency (in micro seconds) of + read requests after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_min +Date: January 2021 +Contact: Can Guo +Description: This file shows the minimum latency (in micro seconds) of + read requests after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_avg +Date: January 2021 +Contact: Can Guo +Description: This file shows the average latency (in micro seconds) of + read requests after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/read_req_latency_sum +Date: January 2021 +Contact: Can Guo +Description: This file shows the total latency (in micro seconds) of + read requests sent after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_total_sectors +Date: January 2021 +Contact: Can Guo +Description: This file shows how many sectors (in 512 Bytes) have been sent + from host to device after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_total_busy +Date: January 2021 +Contact: Can Guo +Description: This file shows how long (in micro seconds) has been spent + sending data from host to device after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_nr_requests +Date: January 2021 +Contact: Can Guo +Description: This file shows how many write requests have been sent after + monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_max +Date: January 2021 +Contact: Can Guo +Description: This file shows the maximum latency (in micro seconds) of write + requests after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_min +Date: January 2021 +Contact: Can Guo +Description: This file shows the minimum latency (in micro seconds) of write + requests after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_avg +Date: January 2021 +Contact: Can Guo +Description: This file shows the average latency (in micro seconds) of write + requests after monitor gets started. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/monitor/write_req_latency_sum +Date: January 2021 +Contact: Can Guo +Description: This file shows the total latency (in micro seconds) of write + requests after monitor gets started. + + The file is read only. + What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/wb_presv_us_en Date: June 2020 Contact: Asutosh Das @@ -1153,3 +1279,239 @@ Description: This entry shows the configured size of WriteBooster buffer. 0400h corresponds to 4GB. The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/hpb_version +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the HPB specification version. + The full information about the descriptor could be found at UFS + HPB (Host Performance Booster) Extension specifications. + Example: version 1.2.3 = 0123h + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/hpb_control +Date: June 2021 +Contact: Daejun Park +Description: This entry shows an indication of the HPB control mode. + 00h: Host control mode + 01h: Device control mode + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_region_size +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the bHPBRegionSize which can be calculated + as in the following (in bytes): + HPB Region size = 512B * 2^bHPBRegionSize + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_number_lu +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the maximum number of HPB LU supported by + the device. + 00h: HPB is not supported by the device. + 01h ~ 20h: Maximum number of HPB LU supported by the device + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_subregion_size +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the bHPBSubRegionSize, which can be + calculated as in the following (in bytes) and shall be a multiple of + logical block size: + HPB Sub-Region size = 512B x 2^bHPBSubRegionSize + bHPBSubRegionSize shall not exceed bHPBRegionSize. + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/hpb_max_active_regions +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the maximum number of active HPB regions that + is supported by the device. + + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/hpb_lu_max_active_regions +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the maximum number of HPB regions assigned to + the HPB logical unit. + + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/hpb_pinned_region_start_offset +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the start offset of HPB pinned region. + + The file is read only. + +What: /sys/class/scsi_device/*/device/unit_descriptor/hpb_number_pinned_regions +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of HPB pinned regions assigned to + the HPB logical unit. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/hit_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of reads that changed to HPB read. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/miss_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of reads that cannot be changed to + HPB read. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/rb_noti_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of response UPIUs that has + recommendations for activating sub-regions and/or inactivating region. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/rb_active_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of active sub-regions recommended by + response UPIUs. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/rb_inactive_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of inactive regions recommended by + response UPIUs. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_stats/map_req_cnt +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the number of read buffer commands for + activating sub-regions recommended by response UPIUs. + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_params/requeue_timeout_ms +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the requeue timeout threshold for write buffer + command in ms. This value can be changed by writing proper integer to + this entry. + +What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_size_hpb_single_cmd +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the maximum HPB data size for using single HPB + command. + + === ======== + 00h 4KB + 01h 8KB + 02h 12KB + ... + FFh 1024KB + === ======== + + The file is read only. + +What: /sys/bus/platform/drivers/ufshcd/*/flags/hpb_enable +Date: June 2021 +Contact: Daejun Park +Description: This entry shows the status of HPB. + + == ============================ + 0 HPB is not enabled. + 1 HPB is enabled + == ============================ + + The file is read only. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/activation_thld +Date: February 2021 +Contact: Avri Altman +Description: In host control mode, reads are the major source of activation + trials. once this threshold hs met, the region is added to the + "to-be-activated" list. Since we reset the read counter upon + write, this include sending a rb command updating the region + ppn as well. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/normalization_factor +Date: February 2021 +Contact: Avri Altman +Description: In host control mode, We think of the regions as "buckets". + Those buckets are being filled with reads, and emptied on write. + We use entries_per_srgn - the amount of blocks in a subregion as + our bucket size. This applies because HPB1.0 only concern a + single-block reads. Once the bucket size is crossed, we trigger + a normalization work - not only to avoid overflow, but mainly + because we want to keep those counters normalized, as we are + using those reads as a comparative score, to make various decisions. + The normalization is dividing (shift right) the read counter by + the normalization_factor. If during consecutive normalizations + an active region has exhaust its reads - inactivate it. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/eviction_thld_enter +Date: February 2021 +Contact: Avri Altman +Description: Region deactivation is often due to the fact that eviction took + place: a region become active on the expense of another. This is + happening when the max-active-regions limit has crossed. + In host mode, eviction is considered an extreme measure. We + want to verify that the entering region has enough reads, and + the exiting region has much less reads. eviction_thld_enter is + the min reads that a region must have in order to be considered + as a candidate to evict other region. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/eviction_thld_exit +Date: February 2021 +Contact: Avri Altman +Description: same as above for the exiting region. A region is consider to + be a candidate to be evicted, only if it has less reads than + eviction_thld_exit. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/read_timeout_ms +Date: February 2021 +Contact: Avri Altman +Description: In order not to hang on to “cold” regions, we shall inactivate + a region that has no READ access for a predefined amount of + time - read_timeout_ms. If read_timeout_ms has expired, and the + region is dirty - it is less likely that we can make any use of + HPB-READing it. So we inactivate it. Still, deactivation has + its overhead, and we may still benefit from HPB-READing this + region if it is clean - see read_timeout_expiries. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/read_timeout_expiries +Date: February 2021 +Contact: Avri Altman +Description: if the region read timeout has expired, but the region is clean, + just re-wind its timer for another spin. Do that as long as it + is clean and did not exhaust its read_timeout_expiries threshold. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/timeout_polling_interval_ms +Date: February 2021 +Contact: Avri Altman +Description: the frequency in which the delayed worker that checks the + read_timeouts is awaken. + +What: /sys/class/scsi_device/*/device/hpb_param_sysfs/inflight_map_req +Date: February 2021 +Contact: Avri Altman +Description: in host control mode the host is the originator of map requests. + To not flood the device with map requests, use a simple throttling + mechanism that limits the number of inflight map requests. diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 5088281e312e..3d1f853c6681 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -203,7 +203,34 @@ Description: Shows total written kbytes issued to disk. What: /sys/fs/f2fs//features Date: July 2017 Contact: "Jaegeuk Kim" -Description: Shows all enabled features in current device. +Description: /feature_list/ + Shows all enabled features in current device. + Supported features: + encryption, blkzoned, extra_attr, projquota, inode_checksum, + flexible_inline_xattr, quota_ino, inode_crtime, lost_found, + verity, sb_checksum, casefold, readonly, compression, pin_file. + +What: /sys/fs/f2fs//feature_list/ +Date: June 2021 +Contact: "Jaegeuk Kim" +Description: Expand /sys/fs/f2fs//features to meet sysfs rule. + Supported on-disk features: + encryption, block_zoned (aka blkzoned), extra_attr, + project_quota (aka projquota), inode_checksum, + flexible_inline_xattr, quota_ino, inode_crtime, lost_found, + verity, sb_checksum, casefold, readonly, compression. + Note that, pin_file is moved into /sys/fs/f2fs/features/. + +What: /sys/fs/f2fs/features/ +Date: July 2017 +Contact: "Jaegeuk Kim" +Description: Shows all enabled kernel features. + Supported features: + encryption, block_zoned, extra_attr, project_quota, + inode_checksum, flexible_inline_xattr, quota_ino, + inode_crtime, lost_found, verity, sb_checksum, + casefold, readonly, compression, test_dummy_encryption_v2, + atomic_write, pin_file, encrypted_casefold. What: /sys/fs/f2fs//inject_rate Date: May 2016 @@ -466,3 +493,17 @@ Contact: "Chao Yu" Description: When ATGC is on, it controls age threshold to bypass GCing young candidates whose age is not beyond the threshold, by default it was initialized as 604800 seconds (equals to 7 days). + +What: /sys/fs/f2fs//gc_reclaimed_segments +Date: July 2021 +Contact: "Daeho Jeong" +Description: Show how many segments have been reclaimed by GC during a specific + GC mode (0: GC normal, 1: GC idle CB, 2: GC idle greedy, + 3: GC idle AT, 4: GC urgent high, 5: GC urgent low) + You can re-initialize this value to "0". + +What: /sys/fs/f2fs//gc_segment_mode +Date: July 2021 +Contact: "Daeho Jeong" +Description: You can control for which gc mode the "gc_reclaimed_segments" node shows. + Refer to the description of the modes in "gc_reclaimed_segments". diff --git a/Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers b/Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers index 721d486a186b..122185c6a88c 100644 --- a/Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers +++ b/Documentation/ABI/testing/sysfs-kernel-dmabuf-buffers @@ -22,38 +22,3 @@ KernelVersion: v5.12 Contact: Hridya Valsaraju Description: This file is read-only and specifies the size of the DMA-BUF in bytes. - -What: /sys/kernel/dmabuf/buffers//attachments -Date: January 2021 -KernelVersion: v5.12 -Contact: Hridya Valsaraju -Description: This directory will contain subdirectories representing every - attachment of the DMA-BUF. - -What: /sys/kernel/dmabuf/buffers//attachments/ -Date: January 2021 -KernelVersion: v5.12 -Contact: Hridya Valsaraju -Description: This directory will contain information on the attaching device - and the number of current distinct device mappings. - -What: /sys/kernel/dmabuf/buffers//attachments//device -Date: January 2021 -KernelVersion: v5.12 -Contact: Hridya Valsaraju -Description: This file is read-only and is a symlink to the attaching devices's - sysfs entry. - -What: /sys/kernel/dmabuf/buffers//attachments//map_counter -Date: January 2021 -KernelVersion: v5.12 -Contact: Hridya Valsaraju -Description: This file is read-only and contains a map_counter indicating the - number of distinct device mappings of the attachment. - -What: /sys/kernel/dmabuf/buffers//mmap_count -Date: January 2021 -KernelVersion: v5.10 -Contact: Kalesh Singh -Description: This file is read-only and contains a counter indicating the - number of times the buffer has been mmap(). diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 608d7c279396..540ee6db5c48 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -54,6 +54,7 @@ v1 is available under :ref:`Documentation/admin-guide/cgroup-v1/index.rst /mte_tcf_preferred``, to which a +privileged user may write the value ``async`` or ``sync``. The default +preferred mode for each CPU is ``async``. + +To allow a program to potentially run in the CPU's preferred tag +checking mode, the user program may set multiple tag check fault mode +bits in the ``flags`` argument to the ``prctl(PR_SET_TAGGED_ADDR_CTRL, +flags, 0, 0, 0)`` system call. If the CPU's preferred tag checking +mode is in the task's set of provided tag checking modes (this will +always be the case at present because the kernel only supports two +tag checking modes, but future kernels may support more modes), that +mode will be selected. Otherwise, one of the modes in the task's mode +set will be selected in a currently unspecified manner. + Initial process state --------------------- On ``execve()``, the new process has the following configuration: - ``PR_TAGGED_ADDR_ENABLE`` set to 0 (disabled) -- Tag checking mode set to ``PR_MTE_TCF_NONE`` +- No tag checking modes are selected (tag check faults ignored) - ``PR_MTE_TAG_MASK`` set to 0 (all tags excluded) - ``PSTATE.TCO`` set to 0 - ``PROT_MTE`` not set on any of the initial memory maps @@ -251,11 +283,13 @@ Example of correct usage return EXIT_FAILURE; /* - * Enable the tagged address ABI, synchronous MTE tag check faults and - * allow all non-zero tags in the randomly generated set. + * Enable the tagged address ABI, synchronous or asynchronous MTE + * tag check faults (based on per-CPU preference) and allow all + * non-zero tags in the randomly generated set. */ if (prctl(PR_SET_TAGGED_ADDR_CTRL, - PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | (0xfffe << PR_MTE_TAG_SHIFT), + PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC | + (0xfffe << PR_MTE_TAG_SHIFT), 0, 0, 0)) { perror("prctl() failed"); return EXIT_FAILURE; diff --git a/Documentation/arm64/pointer-authentication.rst b/Documentation/arm64/pointer-authentication.rst index 30b2ab06526b..f127666ea3a8 100644 --- a/Documentation/arm64/pointer-authentication.rst +++ b/Documentation/arm64/pointer-authentication.rst @@ -107,3 +107,37 @@ filter out the Pointer Authentication system key registers from KVM_GET/SET_REG_* ioctls and mask those features from cpufeature ID register. Any attempt to use the Pointer Authentication instructions will result in an UNDEFINED exception being injected into the guest. + + +Enabling and disabling keys +--------------------------- + +The prctl PR_PAC_SET_ENABLED_KEYS allows the user program to control which +PAC keys are enabled in a particular task. It takes two arguments, the +first being a bitmask of PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY +and PR_PAC_APDBKEY specifying which keys shall be affected by this prctl, +and the second being a bitmask of the same bits specifying whether the key +should be enabled or disabled. For example:: + + prctl(PR_PAC_SET_ENABLED_KEYS, + PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY, + PR_PAC_APIBKEY, 0, 0); + +disables all keys except the IB key. + +The main reason why this is useful is to enable a userspace ABI that uses PAC +instructions to sign and authenticate function pointers and other pointers +exposed outside of the function, while still allowing binaries conforming to +the ABI to interoperate with legacy binaries that do not sign or authenticate +pointers. + +The idea is that a dynamic loader or early startup code would issue this +prctl very early after establishing that a process may load legacy binaries, +but before executing any PAC instructions. + +For compatibility with previous kernel versions, processes start up with IA, +IB, DA and DB enabled, and are reset to this state on exec(). Processes created +via fork() and clone() inherit the key enabled state from the calling process. + +It is recommended to avoid disabling the IA key, as this has higher performance +overhead than disabling any of the other keys. diff --git a/Documentation/devicetree/bindings/arm/ete.yaml b/Documentation/devicetree/bindings/arm/ete.yaml index 35a42d92bf97..572564a0fc6f 100644 --- a/Documentation/devicetree/bindings/arm/ete.yaml +++ b/Documentation/devicetree/bindings/arm/ete.yaml @@ -37,7 +37,11 @@ properties: out-ports: description: | Output connections from the ETE to legacy CoreSight trace bus. - $ref: /schemas/graph.yaml#/properties/port + $ref: /schemas/graph.yaml#/properties/ports + properties: + port: + description: Output connection from the ETE to legacy CoreSight Trace bus. + $ref: /schemas/graph.yaml#/properties/port required: required: - compatible diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt b/Documentation/devicetree/bindings/usb/dwc3.txt deleted file mode 100644 index 1aae2b6160c1..000000000000 --- a/Documentation/devicetree/bindings/usb/dwc3.txt +++ /dev/null @@ -1,128 +0,0 @@ -synopsys DWC3 CORE - -DWC3- USB3 CONTROLLER. Complies to the generic USB binding properties - as described in 'usb/generic.txt' - -Required properties: - - compatible: must be "snps,dwc3" - - reg : Address and length of the register set for the device - - interrupts: Interrupts used by the dwc3 controller. - - clock-names: list of clock names. Ideally should be "ref", - "bus_early", "suspend" but may be less or more. - - clocks: list of phandle and clock specifier pairs corresponding to - entries in the clock-names property. - -Exception for clocks: - clocks are optional if the parent node (i.e. glue-layer) is compatible to - one of the following: - "cavium,octeon-7130-usb-uctl" - "qcom,dwc3" - "samsung,exynos5250-dwusb3" - "samsung,exynos5433-dwusb3" - "samsung,exynos7-dwusb3" - "sprd,sc9860-dwc3" - "st,stih407-dwc3" - "ti,am437x-dwc3" - "ti,dwc3" - "ti,keystone-dwc3" - "rockchip,rk3399-dwc3" - "xlnx,zynqmp-dwc3" - -Optional properties: - - usb-phy : array of phandle for the PHY device. The first element - in the array is expected to be a handle to the USB2/HS PHY and - the second element is expected to be a handle to the USB3/SS PHY - - phys: from the *Generic PHY* bindings - - phy-names: from the *Generic PHY* bindings; supported names are "usb2-phy" - or "usb3-phy". - - resets: set of phandle and reset specifier pairs - - snps,usb2-lpm-disable: indicate if we don't want to enable USB2 HW LPM - - snps,usb3_lpm_capable: determines if platform is USB3 LPM capable - - snps,dis-start-transfer-quirk: when set, disable isoc START TRANSFER command - failure SW work-around for DWC_usb31 version 1.70a-ea06 - and prior. - - snps,disable_scramble_quirk: true when SW should disable data scrambling. - Only really useful for FPGA builds. - - snps,has-lpm-erratum: true when DWC3 was configured with LPM Erratum enabled - - snps,lpm-nyet-threshold: LPM NYET threshold - - snps,u2exit_lfps_quirk: set if we want to enable u2exit lfps quirk - - snps,u2ss_inp3_quirk: set if we enable P3 OK for U2/SS Inactive quirk - - snps,req_p1p2p3_quirk: when set, the core will always request for - P1/P2/P3 transition sequence. - - snps,del_p1p2p3_quirk: when set core will delay P1/P2/P3 until a certain - amount of 8B10B errors occur. - - snps,del_phy_power_chg_quirk: when set core will delay PHY power change - from P0 to P1/P2/P3. - - snps,lfps_filter_quirk: when set core will filter LFPS reception. - - snps,rx_detect_poll_quirk: when set core will disable a 400us delay to start - Polling LFPS after RX.Detect. - - snps,tx_de_emphasis_quirk: when set core will set Tx de-emphasis value. - - snps,tx_de_emphasis: the value driven to the PHY is controlled by the - LTSSM during USB3 Compliance mode. - - snps,dis_u3_susphy_quirk: when set core will disable USB3 suspend phy. - - snps,dis_u2_susphy_quirk: when set core will disable USB2 suspend phy. - - snps,dis_enblslpm_quirk: when set clears the enblslpm in GUSB2PHYCFG, - disabling the suspend signal to the PHY. - - snps,dis-u1-entry-quirk: set if link entering into U1 needs to be disabled. - - snps,dis-u2-entry-quirk: set if link entering into U2 needs to be disabled. - - snps,dis_rxdet_inp3_quirk: when set core will disable receiver detection - in PHY P3 power state. - - snps,dis-u2-freeclk-exists-quirk: when set, clear the u2_freeclk_exists - in GUSB2PHYCFG, specify that USB2 PHY doesn't provide - a free-running PHY clock. - - snps,dis-del-phy-power-chg-quirk: when set core will change PHY power - from P0 to P1/P2/P3 without delay. - - snps,dis-tx-ipgap-linecheck-quirk: when set, disable u2mac linestate check - during HS transmit. - - snps,parkmode-disable-ss-quirk: when set, all SuperSpeed bus instances in - park mode are disabled. - - snps,dis_metastability_quirk: when set, disable metastability workaround. - CAUTION: use only if you are absolutely sure of it. - - snps,dis-split-quirk: when set, change the way URBs are handled by the - driver. Needed to avoid -EPROTO errors with usbhid - on some devices (Hikey 970). - - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal - utmi_l1_suspend_n, false when asserts utmi_sleep_n - - snps,hird-threshold: HIRD threshold - - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for - UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3. - - snps,quirk-frame-length-adjustment: Value for GFLADJ_30MHZ field of GFLADJ - register for post-silicon frame length adjustment when the - fladj_30mhz_sdbnd signal is invalid or incorrect. - - snps,rx-thr-num-pkt-prd: periodic ESS RX packet threshold count - host mode - only. Set this and rx-max-burst-prd to a valid, - non-zero value 1-16 (DWC_usb31 programming guide - section 1.2.4) to enable periodic ESS RX threshold. - - snps,rx-max-burst-prd: max periodic ESS RX burst size - host mode only. Set - this and rx-thr-num-pkt-prd to a valid, non-zero value - 1-16 (DWC_usb31 programming guide section 1.2.4) to - enable periodic ESS RX threshold. - - snps,tx-thr-num-pkt-prd: periodic ESS TX packet threshold count - host mode - only. Set this and tx-max-burst-prd to a valid, - non-zero value 1-16 (DWC_usb31 programming guide - section 1.2.3) to enable periodic ESS TX threshold. - - snps,tx-max-burst-prd: max periodic ESS TX burst size - host mode only. Set - this and tx-thr-num-pkt-prd to a valid, non-zero value - 1-16 (DWC_usb31 programming guide section 1.2.3) to - enable periodic ESS TX threshold. - - - tx-fifo-resize: determines if the FIFO *has* to be reallocated. - - snps,incr-burst-type-adjustment: Value for INCR burst type of GSBUSCFG0 - register, undefined length INCR burst type enable and INCRx type. - When just one value, which means INCRX burst mode enabled. When - more than one value, which means undefined length INCR burst type - enabled. The values can be 1, 4, 8, 16, 32, 64, 128 and 256. - - - in addition all properties from usb-xhci.txt from the current directory are - supported as well - - -This is usually a subnode to DWC3 glue to which it is connected. - -dwc3@4a030000 { - compatible = "snps,dwc3"; - reg = <0x4a030000 0xcfff>; - interrupts = <0 92 4> - usb-phy = <&usb2_phy>, <&usb3,phy>; - snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; -}; diff --git a/Documentation/devicetree/bindings/usb/snps,dwc3.yaml b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml new file mode 100644 index 000000000000..3091a43c11d5 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/snps,dwc3.yaml @@ -0,0 +1,323 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/snps,dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Synopsys DesignWare USB3 Controller + +maintainers: + - Felipe Balbi + +description: + This is usually a subnode to DWC3 glue to which it is connected, but can also + be presented as a standalone DT node with an optional vendor-specific + compatible string. + +allOf: + - $ref: usb-drd.yaml# + - if: + properties: + dr_mode: + const: peripheral + + required: + - dr_mode + then: + $ref: usb.yaml# + else: + $ref: usb-xhci.yaml# + +properties: + compatible: + contains: + const: snps,dwc3 + + interrupts: + minItems: 1 + maxItems: 3 + + clocks: + description: + In general the core supports three types of clocks. bus_early is a + SoC Bus Clock (AHB/AXI/Native). ref generates ITP when the UTMI/ULPI + PHY is suspended. suspend clocks a small part of the USB3 core when + SS PHY in P3. But particular cases may differ from that having less + or more clock sources with another names. + + clock-names: + contains: + anyOf: + - enum: [bus_early, ref, suspend] + - true + + usb-phy: + minItems: 1 + items: + - description: USB2/HS PHY + - description: USB3/SS PHY + + phys: + minItems: 1 + items: + - description: USB2/HS PHY + - description: USB3/SS PHY + + phy-names: + minItems: 1 + items: + - const: usb2-phy + - const: usb3-phy + + resets: + minItems: 1 + + snps,usb2-lpm-disable: + description: Indicate if we don't want to enable USB2 HW LPM + type: boolean + + snps,usb3_lpm_capable: + description: Determines if platform is USB3 LPM capable + type: boolean + + snps,dis-start-transfer-quirk: + description: + When set, disable isoc START TRANSFER command failure SW work-around + for DWC_usb31 version 1.70a-ea06 and prior. + type: boolean + + snps,disable_scramble_quirk: + description: + True when SW should disable data scrambling. Only really useful for FPGA + builds. + type: boolean + + snps,has-lpm-erratum: + description: True when DWC3 was configured with LPM Erratum enabled + type: boolean + + snps,lpm-nyet-threshold: + description: LPM NYET threshold + $ref: /schemas/types.yaml#/definitions/uint8 + + snps,u2exit_lfps_quirk: + description: Set if we want to enable u2exit lfps quirk + type: boolean + + snps,u2ss_inp3_quirk: + description: Set if we enable P3 OK for U2/SS Inactive quirk + type: boolean + + snps,req_p1p2p3_quirk: + description: + When set, the core will always request for P1/P2/P3 transition sequence. + type: boolean + + snps,del_p1p2p3_quirk: + description: + When set core will delay P1/P2/P3 until a certain amount of 8B10B errors + occur. + type: boolean + + snps,del_phy_power_chg_quirk: + description: When set core will delay PHY power change from P0 to P1/P2/P3. + type: boolean + + snps,lfps_filter_quirk: + description: When set core will filter LFPS reception. + type: boolean + + snps,rx_detect_poll_quirk: + description: + when set core will disable a 400us delay to start Polling LFPS after + RX.Detect. + type: boolean + + snps,tx_de_emphasis_quirk: + description: When set core will set Tx de-emphasis value + type: boolean + + snps,tx_de_emphasis: + description: + The value driven to the PHY is controlled by the LTSSM during USB3 + Compliance mode. + $ref: /schemas/types.yaml#/definitions/uint8 + + snps,dis_u3_susphy_quirk: + description: When set core will disable USB3 suspend phy + type: boolean + + snps,dis_u2_susphy_quirk: + description: When set core will disable USB2 suspend phy + type: boolean + + snps,dis_enblslpm_quirk: + description: + When set clears the enblslpm in GUSB2PHYCFG, disabling the suspend signal + to the PHY. + type: boolean + + snps,dis-u1-entry-quirk: + description: Set if link entering into U1 needs to be disabled + type: boolean + + snps,dis-u2-entry-quirk: + description: Set if link entering into U2 needs to be disabled + type: boolean + + snps,dis_rxdet_inp3_quirk: + description: + When set core will disable receiver detection in PHY P3 power state. + type: boolean + + snps,dis-u2-freeclk-exists-quirk: + description: + When set, clear the u2_freeclk_exists in GUSB2PHYCFG, specify that USB2 + PHY doesn't provide a free-running PHY clock. + type: boolean + + snps,dis-del-phy-power-chg-quirk: + description: + When set core will change PHY power from P0 to P1/P2/P3 without delay. + type: boolean + + snps,dis-tx-ipgap-linecheck-quirk: + description: When set, disable u2mac linestate check during HS transmit + type: boolean + + snps,parkmode-disable-ss-quirk: + description: + When set, all SuperSpeed bus instances in park mode are disabled. + type: boolean + + snps,dis_metastability_quirk: + description: + When set, disable metastability workaround. CAUTION! Use only if you are + absolutely sure of it. + type: boolean + + snps,dis-split-quirk: + description: + When set, change the way URBs are handled by the driver. Needed to + avoid -EPROTO errors with usbhid on some devices (Hikey 970). + type: boolean + + snps,is-utmi-l1-suspend: + description: + True when DWC3 asserts output signal utmi_l1_suspend_n, false when + asserts utmi_sleep_n. + type: boolean + + snps,hird-threshold: + description: HIRD threshold + $ref: /schemas/types.yaml#/definitions/uint8 + + snps,hsphy_interface: + description: + High-Speed PHY interface selection between UTMI+ and ULPI when the + DWC_USB3_HSPHY_INTERFACE has value 3. + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [utmi, ulpi] + + snps,quirk-frame-length-adjustment: + description: + Value for GFLADJ_30MHZ field of GFLADJ register for post-silicon frame + length adjustment when the fladj_30mhz_sdbnd signal is invalid or + incorrect. + $ref: /schemas/types.yaml#/definitions/uint32 + + snps,rx-thr-num-pkt-prd: + description: + Periodic ESS RX packet threshold count (host mode only). Set this and + snps,rx-max-burst-prd to a valid, non-zero value 1-16 (DWC_usb31 + programming guide section 1.2.4) to enable periodic ESS RX threshold. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + snps,rx-max-burst-prd: + description: + Max periodic ESS RX burst size (host mode only). Set this and + snps,rx-thr-num-pkt-prd to a valid, non-zero value 1-16 (DWC_usb31 + programming guide section 1.2.4) to enable periodic ESS RX threshold. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + snps,tx-thr-num-pkt-prd: + description: + Periodic ESS TX packet threshold count (host mode only). Set this and + snps,tx-max-burst-prd to a valid, non-zero value 1-16 (DWC_usb31 + programming guide section 1.2.3) to enable periodic ESS TX threshold. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + snps,tx-max-burst-prd: + description: + Max periodic ESS TX burst size (host mode only). Set this and + snps,tx-thr-num-pkt-prd to a valid, non-zero value 1-16 (DWC_usb31 + programming guide section 1.2.3) to enable periodic ESS TX threshold. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 16 + + tx-fifo-resize: + description: Determines if the TX fifos can be dynamically resized depending + on the number of IN endpoints used and if bursting is supported. This + may help improve bandwidth on platforms with higher system latencies, as + increased fifo space allows for the controller to prefetch data into its + internal memory. + type: boolean + + tx-fifo-max-num: + description: Specifies the max number of packets the txfifo resizing logic + can account for when higher endpoint bursting is used. (bMaxBurst > 6) The + higher the number, the more fifo space the txfifo resizing logic will + allocate for that endpoint. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 3 + + snps,incr-burst-type-adjustment: + description: + Value for INCR burst type of GSBUSCFG0 register, undefined length INCR + burst type enable and INCRx type. A single value means INCRX burst mode + enabled. If more than one value specified, undefined length INCR burst + type will be enabled with burst lengths utilized up to the maximum + of the values passed in this property. + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 1 + maxItems: 8 + uniqueItems: true + items: + enum: [1, 4, 8, 16, 32, 64, 128, 256] + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + +examples: + - | + usb@4a030000 { + compatible = "snps,dwc3"; + reg = <0x4a030000 0xcfff>; + interrupts = <0 92 4>; + usb-phy = <&usb2_phy>, <&usb3_phy>; + snps,incr-burst-type-adjustment = <1>, <4>, <8>, <16>; + }; + - | + usb@4a000000 { + compatible = "snps,dwc3"; + reg = <0x4a000000 0xcfff>; + interrupts = <0 92 4>; + clocks = <&clk 1>, <&clk 2>, <&clk 3>; + clock-names = "bus_early", "ref", "suspend"; + phys = <&usb2_phy>, <&usb3_phy>; + phy-names = "usb2-phy", "usb3-phy"; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + }; +... diff --git a/Documentation/filesystems/OWNERS b/Documentation/filesystems/OWNERS deleted file mode 100644 index 5b6ec532f1e2..000000000000 --- a/Documentation/filesystems/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/Documentation/filesystems/OWNERS diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index 992bf91eeec8..b91e5a8444d5 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -289,6 +289,9 @@ compress_mode=%s Control file compression mode. This supports "fs" and "user" choosing the target file and the timing. The user can do manual compression/decompression on the compression enabled files using ioctls. +compress_cache Support to use address space of a filesystem managed inode to + cache compressed block, in order to improve cache hit ratio of + random read. inlinecrypt When possible, encrypt/decrypt the contents of encrypted files using the blk-crypto framework rather than filesystem-layer encryption. This allows the use of @@ -717,10 +720,10 @@ users. ===================== ======================== =================== User F2FS Block ===================== ======================== =================== - META WRITE_LIFE_NOT_SET - HOT_NODE " - WARM_NODE " - COLD_NODE " +N/A META WRITE_LIFE_NOT_SET +N/A HOT_NODE " +N/A WARM_NODE " +N/A COLD_NODE " ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME extension list " " @@ -746,10 +749,10 @@ WRITE_LIFE_LONG " WRITE_LIFE_LONG ===================== ======================== =================== User F2FS Block ===================== ======================== =================== - META WRITE_LIFE_MEDIUM; - HOT_NODE WRITE_LIFE_NOT_SET - WARM_NODE " - COLD_NODE WRITE_LIFE_NONE +N/A META WRITE_LIFE_MEDIUM; +N/A HOT_NODE WRITE_LIFE_NOT_SET +N/A WARM_NODE " +N/A COLD_NODE WRITE_LIFE_NONE ioctl(COLD) COLD_DATA WRITE_LIFE_EXTREME extension list " " diff --git a/OWNERS b/OWNERS index 2b5ccceaf513..414594e3f646 100644 --- a/OWNERS +++ b/OWNERS @@ -1,2 +1,12 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/OWNERS +set noparent + +# GKI Dr. No Enforcement is active on this branch. Approval of one of the Dr. +# No reviewers is required following a regular CodeReview+2 vote of a code +# reviewer. +# +# See the GKI release documentation (go/gki-dr-no) for further details. +# +# The expanded list of reviewers can be found at: +# https://android.googlesource.com/kernel/common/+/android-mainline/OWNERS_DrNo + +include kernel/common:android-mainline:/OWNERS_DrNo diff --git a/android/OWNERS b/android/OWNERS deleted file mode 100644 index 15daab5460ab..000000000000 --- a/android/OWNERS +++ /dev/null @@ -1,12 +0,0 @@ -# If we ever add another OWNERS above this directory, it's likely to be -# more permissive, so don't inherit from it -set noparent -adelva@google.com -maennich@google.com -saravanak@google.com -sspatil@google.com -tkjos@google.com -willmcvicker@google.com -# Downstream boards maintained directly in this manifest branch -per-file abi_gki_aarch64_cuttlefish = adelva@google.com, rammuthiah@google.com -per-file abi_gki_aarch64_goldfish = rkir@google.com diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml old mode 100644 new mode 100755 index cf87ad21f7e6..11b0567bed91 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -1,22 +1,23 @@ - - - - + + + + - - + + - + + @@ -25,63 +26,63 @@ - - - - - - - + + + + + - - - - + + + + - - - + + + - - - + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + @@ -91,22 +92,26 @@ - + - + - + - + + + - - - - - - - + + + + + + + + + @@ -115,261 +120,358 @@ - - + + + + - + - + + - - + + + - - - - - + + + + + + - - + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + + + - - - + + + - - - - - - - - - + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + - - + + - + + + - - - + + + - + - - - + + + + + + + + - - - - - + + + + + + + + - - + + + + - - + + + - - + + - - + + - - - - - - + + + + + + - + - - - + + + + - - + + - + + - - - - + + + + + + + - + + - - + + + + + + + - - - + + + + + + + + + + + + + + + + + - - - + + - - - + + + + + + + + - - - + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + - + + - + + + + + + + + - + + + + - + - - + + + + + + @@ -378,53 +480,67 @@ - - - - - - - + + + + + + + + + - + - - - + + + + - - - - + + + + + + + + - + - - + + - - - + + + + + + + + - + + - - - - - - - - - + + + + + + + + + + @@ -448,27 +564,28 @@ + - - - - - + + + + + - + - - + + @@ -477,26 +594,32 @@ - + - + + + + - - - - + + + + - + - - - - + + + + + - + - - + + + + @@ -507,44 +630,46 @@ - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + @@ -557,279 +682,270 @@ - - - - + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - + + + + + - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - + + + + - - - - - - - - - + + + + + + + + + + - + - - - - + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - + + + + + + + + + - + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - + - - + + - + - + - - - - + + + + + - - + + - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + + - + + @@ -843,481 +959,504 @@ - - - - - - - + + + + + + + + - - - + + + + - + - - + + - - + + - - - - + + + + - - + + + + - + - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1335,57 +1474,61 @@ - - - - - - - - - + + + + + + + + + + - + - - - - - + + + + + - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + @@ -1399,507 +1542,560 @@ - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - - - + + + + + + + + - - - - - - + + + + + + - + - - - - + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - + + + + - - - - + + + + - + - - - - - + + + + + - - + + - + - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + - + - + - - - - - - - - - - + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - + + + + + + + + - - - - - + + + + + + - + + - - - - + + + + + - - - - + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - + + + + + + - + - + - + + + - + - + - - - - - + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + @@ -1916,49 +2112,58 @@ - - - + + + + - - - - - - - - - + + + + + + + + + + + + - - - - - - + + + + + + + + + + - - + + + - + - - - - - - + + + + + + - - - + + + @@ -1966,148 +2171,180 @@ - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - - - - + + + + + - + - - - - - + + + + + + - - - - - + + + + + + + - - + + - - + + - - + + - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + @@ -2121,312 +2358,268 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + - - - - - - - - - - + + + + + + + + + + + - + + - + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - + + + + - + + - + + - - - + + + - - - - - + + + + + + + - + - + - - - - + + + + + + + - + + - - - - + + + + - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + + + - - + + + - + @@ -2446,91 +2639,116 @@ - - - - - - + + + + + + - - - - - + + + + + - - + + - - - - + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2558,103 +2776,105 @@ - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + @@ -2664,60 +2884,64 @@ - + - - - - - - - - - + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + - + - + - - + + @@ -2727,406 +2951,453 @@ - - - - + + + + - + + - - - - + + + + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + - + - - + + - + @@ -3137,52 +3408,57 @@ - - - + + + + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - + + - - - - - - - + + + + + + + - - - + + + @@ -3221,386 +3497,421 @@ - + - - - - - + + + + + + + - - - - - - - - + + + + + + + + - + - + - + - - + + + - - + + - + - - + + - - - - - + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - + + - + - - - - + + + + - + - + - - + + + + + + + - - - + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + - + - - + + - + - + - + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + - - - - + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - + + + + - + - - - + + + - + - + @@ -3609,304 +3920,325 @@ - - - - - + + + + + + - - - - - + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + @@ -3914,7 +4246,7 @@ - + @@ -3936,14 +4268,14 @@ - - - - - + + + + + - - + + @@ -3951,46 +4283,48 @@ - - - + + + - + - + - - - - - - - - + + + + + + + + - - - - - - - - - + + + + + + + + + + - + - - - + + + + - + @@ -4001,572 +4335,627 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - + + + - - - - - - + + + + + + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + + - + - + - - - - + + + + - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - - + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + + - + - - - - - + + + + + + - - - + + + + + - - + + - - - + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + - - - - + + + + + - + - - + + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + + - - + + - - - - + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - + - + - + - - - + + + - - + + + - - + + - - - + + + @@ -4581,87 +4970,82 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - + - - - + + + - + - - - - - - + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - + + + + - - - - - - - - - + + + + + + + + + - - + + - - + + @@ -4673,6 +5057,8 @@ + + @@ -4683,18 +5069,28 @@ + + + + + + + + + + @@ -4702,6 +5098,7 @@ + @@ -4726,6 +5123,7 @@ + @@ -4733,38 +5131,59 @@ + + + + + + + + + + + + + + + + + + + + + + - - + @@ -4773,45 +5192,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4820,6 +5286,10 @@ + + + + @@ -4830,6 +5300,8 @@ + + @@ -4841,29 +5313,35 @@ + + + + + - + - - + + - - - - - - + + + + + + + - + @@ -4871,11 +5349,12 @@ - + - - - + + + + @@ -4886,71 +5365,78 @@ - + + + - + - + + - - - - - + + + + + + - - - + + + - - + + + - + - - - + + + - + + + - - + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -4958,21 +5444,20 @@ - - + - + - - + + - - - + + + @@ -4991,87 +5476,31 @@ - - - + + + + - + - - - + + + - - - - - + + + - + - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -5080,1111 +5509,1003 @@ - - - + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - + + + + + + + + + + - - - + + + + + + + + + - + - - - - + - + + + + + + - + - + - - - - - - - - - - - - + - + - - + + - - + + - - + + - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + + + + + + + + + + + + + + - + + + + + + + + - + - + - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - - - - - - - - - - - - - - - - - + - - - - - - - + - + + - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - + + - - - - + - + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + - + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6195,42 +6516,4955 @@ - + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + - + - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6258,3843 +11492,227 @@ - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - + - - - - - - - - + + + + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + - - + + - - + + - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - + - - + + - + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + - + - + - - + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -10151,943 +11769,1007 @@ - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + + - - + + + + + + + + - + + + + - - - - - - - + - - - - + - - - - + - + - + - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - + - + - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + - + + + + - + + + + - + - + - - + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - + + - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + - + + - + - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -11150,2356 +12832,380 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + - - - - - - - - - - + - + - - + + + + + - + - + - + + + + + + + - + - + - - - - - + + - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - + - - - - + - + - + - - - - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - + - + - - + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + + + + - - + + - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + + + - - - - + + + - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - + + + + + @@ -13583,462 +13289,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + @@ -14056,3999 +13314,1289 @@ - + - + - - + + - - + + - - + + - - - - - - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - + - + + + + - + - + - + - - - - - - - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + - + - - + + - - + + + + + - + + + + + + + + + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + - + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + + + + - - - - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - + - - - - - - - + - + - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + - + + + + - + + + + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + - + + + + - + - + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -18072,6613 +14620,476 @@ - + - - - - - - - - - + - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - + - + - - - - + - + - + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + - + - + - + - - + + - + - + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - + - + - + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - + - - - - + - - - - + - + - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - + + + + + - + - - + + + + + - + - - + + + + + - + - - + + + + + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - + - + + + + + + + + + + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + - - - - + - - - - - - - + - + - + - + - + + + + - - - - - - - + - - - + + - + - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -24686,179 +15097,292 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -24919,35590 +15443,128 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -60510,5389 +15572,211 @@ - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + + + + - - - - - - - + - - - - - - - - - - + - - - - - - - - - - + - - - - + - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + - - + + - - + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + - + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -65940,8446 +15824,193 @@ - + + + + - + + + + + + + + + + + + + + + + + + + + + + - + - + - - + + - - + + + + + - + + + + - - - - + - - - - + - - - - + - - - - + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - - + + - + - + + + + + + + - + - - - - - - - + - + - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - + + - + + - - - + + + + + - - - - - - - - - - - + + + + - + - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -74430,852 +16061,1283 @@ - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - + + + - + - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + @@ -75285,3589 +17347,17 @@ - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -78932,51800 +17422,404 @@ - + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - - + - + + + + + + + - + - - - - - - - - + + - - - - - - - - - - + + - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + - + + + - + + + + + + + + + + + + + + + + + + + + + - - - - + - - - - + - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - + + - - - + + + + - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - + + - + + + + - + + + + - + - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - + + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + + + + @@ -130746,15050 +17840,412 @@ - + + + + + + + + + + + + + - + - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + - + + + + + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - - + - - - - + - - - - + - + - + - - - - + - - - - + - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + + + - + - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - + - - - - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - - + + - - + + - + - - - - + - - - - + - - - - + - - - - + - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + - + + + + + + + + + + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + + + + + + - + + - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -145963,828 +18419,12679 @@ - + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + + - - - + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + - - - - - - - - + + + + + + + + + + + - + - + - + - + - + - - - - + - + - + - + + - + - + - - - - - - - - - - - - - + + - - - - - - - - - - - - - + - + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - + + + + + + + - + - + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + + + + + @@ -146804,467 +31111,548 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + - + - - - - + - + - + - + - + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -147275,112 +31663,390 @@ - + - - - - - - - - - - + - + - + - + + + - - - + + + - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -147401,102 +32067,1587 @@ - + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - + + - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - + + - + + + + + + + - + + + + - - - - - - + + + + + + + - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -147521,693 +33672,3734 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - + + - - + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - - - - - - - + - + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + + + - - + + - - + + - - + + - - + + + + - - + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - + - - - - - - - - - - - - - + - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + - - - - + - + - - + + - - + + - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -148219,124 +37411,7934 @@ - + + + + - - - - - - - - - + + + - + + + + + + + + + + + + - + - - - - - - - - - - + - + + - + - + + + + + + + + + + + + + + + + + + + + + - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -148351,20 +45353,3185 @@ - + + + - + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -148466,3812 +48633,3092 @@ - + + + + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - - - - + - - - - + - + - + - + - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + - + + + + - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - + + + - - - - - - + + - + - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + - + - + - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + - + - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - + + + + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - + + - - + + - - - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -152279,295 +51726,3327 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -152594,173 +55073,1454 @@ - - + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -152772,1069 +56532,184 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -153842,871 +56717,698 @@ - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - + - + - + - - + + - - + + - - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - - - - + - + - + - + + + + - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - + + + + - + + + + + + + + + + + - - - - - + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -154725,699 +57427,2322 @@ - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + + + + + + - + - + - - - - + - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -155518,1198 +59843,289 @@ - - + - + - - - - - - - + - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - + - - - - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - + - - - - - - - + - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - - + + + + + - - + + - - + + - - + + - - + + - - + + + + - - + + + + + - - + + - - + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + + - - + + - - + + - - + + - - + + + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -156771,96 +60187,4808 @@ - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -156925,419 +65053,3625 @@ - + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + - + - - - - + - - - - - - - - - - - - - - - - - - + - + - - - - + - + - + - + + + + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - + + - - + + + + + - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + - - - - + - + - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + - + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - - - + - + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - @@ -157409,6 +68743,9518 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -157645,6175 +78491,357 @@ - - - - - - - - + + + + + + + + + + + + + + + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + + + - - - - - + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + - + + + + - + - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - + - + - + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - + + + + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -163831,7797 +78859,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -171665,5211 +78903,47 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + @@ -176884,9964 +78958,1349 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - - - - - - - - - - - - - - - - - - - - - + - + + + + - + - + - + - + - + - + - + - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - + + - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - - + + - - + + - - - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - + - - + + - - + + - - + + - + - - - - - - - - - - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - - - - - - - - - - - + + - + + + + + + + - - - - - - - - - - - - - + - + - + - + + + + - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - + - + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - - - + + - - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - - - - - - - - - - - - + - + + + + + + + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -187018,5716 +80477,1270 @@ - - - - - + - - - - + - - - - + - + - - + + - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - + - - - - - - - - - - - - + - + - + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + - - - - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - + - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - + - + + + + + + + + + + + + + + + + + + + + + + - + - - + + + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + - + - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -192854,196 +81867,12145 @@ + + + - + + + + + + + + + + + - + - - - - - - - - - - - - - + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - + - + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -193070,66 +94032,26108 @@ - + + + + + + + + + - - - - + - - - + + + + + + + + + + + + + + + + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - + + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - - + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -193139,64 +120143,15400 @@ - - - - - - - - - - - - - - + - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/abi_gki_aarch64_db845c b/android/abi_gki_aarch64_db845c index ef65c2cad42b..86ef49b9a976 100644 --- a/android/abi_gki_aarch64_db845c +++ b/android/abi_gki_aarch64_db845c @@ -2,19 +2,25 @@ # commonly used symbols add_uevent_var alloc_io_pgtable_ops + __alloc_skb alloc_workqueue __arch_copy_from_user __arch_copy_to_user arm64_const_caps_ready arm64_use_ng_mappings + bcmp blocking_notifier_call_chain blocking_notifier_chain_register blocking_notifier_chain_unregister + bpf_trace_run1 + bpf_trace_run2 bpf_trace_run3 bpf_trace_run4 bpf_trace_run5 + bpf_trace_run6 bus_register bus_unregister + cancel_delayed_work cancel_delayed_work_sync cancel_work_sync capable @@ -23,6 +29,8 @@ cdev_init __cfi_slowpath __check_object_size + __class_register + class_unregister clk_bulk_disable clk_bulk_enable clk_bulk_prepare @@ -54,7 +62,9 @@ cpumask_next cpu_number __cpu_online_mask + __cpu_possible_mask crc32_le + _ctype debugfs_create_dir debugfs_create_file debugfs_create_u32 @@ -62,8 +72,10 @@ debugfs_remove default_llseek delayed_work_timer_fn + del_timer del_timer_sync destroy_workqueue + dev_close dev_coredumpv dev_driver_string _dev_err @@ -108,6 +120,7 @@ devm_pinctrl_register devm_platform_ioremap_resource devm_regmap_add_irq_chip + devm_regmap_field_alloc __devm_regmap_init __devm_regmap_init_i2c __devm_regmap_init_mmio_clk @@ -175,15 +188,20 @@ drm_helper_probe_single_connector_modes drm_mode_vrefresh enable_irq + eth_mac_addr eth_platform_get_mac_address + ethtool_op_get_link + eth_type_trans eth_validate_addr event_triggers_call find_next_bit find_next_zero_bit finish_wait + flush_work flush_workqueue free_io_pgtable_ops free_irq + gcd generic_handle_irq generic_mii_ioctl get_device @@ -232,12 +250,13 @@ idr_alloc_cyclic idr_destroy idr_find + idr_for_each idr_get_next idr_remove - ieee80211_get_channel_khz init_net __init_swait_queue_head init_timer_key + init_uts_ns init_wait_entry __init_waitqueue_head iomem_resource @@ -276,6 +295,8 @@ irq_to_desc is_vmalloc_addr jiffies + jiffies_to_msecs + jiffies_to_usecs kasan_flag_enabled kasprintf kernel_connect @@ -284,6 +305,7 @@ kernel_sendmsg kfree kfree_const + kfree_sensitive kfree_skb __kmalloc kmalloc_caches @@ -297,8 +319,12 @@ ktime_get ktime_get_mono_fast_ns ktime_get_real_ts64 + kvfree + kvfree_call_rcu + kvmalloc_node __list_add_valid __list_del_entry_valid + __local_bh_enable_ip __log_post_read_mmio __log_read_mmio __log_write_mmio @@ -313,10 +339,12 @@ memremap memset memstart_addr + memunmap mii_ethtool_gset mii_nway_restart misc_deregister misc_register + mod_delayed_work_on mod_timer module_layout __msecs_to_jiffies @@ -333,10 +361,15 @@ netdev_err netdev_info netdev_warn + netif_carrier_on netif_napi_add __netif_napi_del + __nla_parse + nla_put no_llseek nr_cpu_ids + nvmem_cell_get + nvmem_cell_put nvmem_cell_read of_address_to_resource of_alias_get_id @@ -348,6 +381,7 @@ of_device_is_compatible of_device_uevent_modalias of_dma_configure_id + of_find_device_by_node of_find_property of_fwnode_ops of_genpd_add_provider_onecell @@ -380,8 +414,11 @@ of_property_read_u32_index of_property_read_variable_u32_array of_property_read_variable_u8_array + of_prop_next_u32 of_reserved_mem_lookup param_ops_bool + param_ops_charp + param_ops_int param_ops_uint __pci_register_driver pci_unregister_driver @@ -419,10 +456,12 @@ __pm_runtime_set_status __pm_runtime_suspend __pm_runtime_use_autosuspend + preempt_schedule preempt_schedule_notrace prepare_to_wait_event printk pskb_expand_head + __pskb_pull_tail put_device __put_task_struct qcom_smem_state_register @@ -451,10 +490,13 @@ regcache_cache_only regcache_mark_dirty regcache_sync + register_netdevice_notifier register_reboot_notifier __register_rpmsg_driver regmap_bulk_read regmap_bulk_write + regmap_field_read + regmap_field_update_bits_base __regmap_init regmap_irq_get_virq regmap_multi_reg_write @@ -480,6 +522,7 @@ reset_control_assert reset_control_deassert reset_control_reset + round_jiffies_up rpmsg_register_device rpmsg_send rpmsg_unregister_device @@ -490,6 +533,9 @@ rproc_del rproc_free rproc_remove_subdev + rtnl_is_locked + rtnl_lock + rtnl_unlock schedule schedule_timeout scnprintf @@ -507,10 +553,14 @@ single_open single_release skb_clone + skb_copy + skb_copy_bits + skb_copy_expand skb_dequeue skb_pull skb_push skb_put + skb_queue_head skb_queue_purge skb_queue_tail skb_trim @@ -557,16 +607,22 @@ strncpy strpbrk strsep + __sw_hweight16 __sw_hweight32 __sw_hweight64 + __sw_hweight8 synchronize_irq synchronize_net + synchronize_rcu syscon_node_to_regmap syscon_regmap_lookup_by_phandle sysfs_create_link sysfs_remove_link sysrq_mask + system_power_efficient_wq system_wq + tasklet_init + tasklet_kill __tasklet_schedule thermal_cooling_device_unregister trace_event_buffer_commit @@ -597,6 +653,7 @@ uart_write_wakeup __udelay unregister_chrdev_region + unregister_netdevice_notifier unregister_reboot_notifier unregister_rpmsg_driver usb_deregister @@ -623,6 +680,7 @@ usbnet_write_cmd_async usbnet_write_cmd_nopm usb_register_driver + __usecs_to_jiffies usleep_range vabits_actual vfree @@ -657,12 +715,10 @@ iommu_group_ref_get iommu_put_dma_cookie of_dma_is_coherent - param_ops_int pci_bus_type pci_device_group # required by asix.ko - eth_mac_addr genphy_resume mdiobus_alloc_size mdiobus_free @@ -679,7 +735,6 @@ phy_print_status phy_start phy_stop - skb_copy_expand usbnet_change_mtu usbnet_get_drvinfo usbnet_get_link @@ -687,98 +742,23 @@ usbnet_set_link_ksettings usbnet_unlink_rx_urbs -# required by ath.ko - freq_reg_info - reg_initiator_name - wiphy_apply_custom_regulatory - # required by ath10k_core.ko - bcmp - cancel_delayed_work - __cfg80211_alloc_event_skb - __cfg80211_alloc_reply_skb - cfg80211_calculate_bitrate - cfg80211_find_elem_match - cfg80211_find_vendor_elem - cfg80211_get_bss - cfg80211_put_bss - __cfg80211_send_event_skb - cfg80211_vendor_cmd_reply cpu_latency_qos_add_request cpu_latency_qos_remove_request device_get_mac_address device_set_wakeup_enable firmware_request_nowarn guid_gen - idr_for_each - ieee80211_alloc_hw_nm - ieee80211_beacon_cntdwn_is_complete - ieee80211_beacon_get_template - ieee80211_beacon_get_tim - ieee80211_beacon_loss - ieee80211_beacon_update_cntdwn - ieee80211_bss_get_elem - ieee80211_channel_to_freq_khz - ieee80211_connection_loss - ieee80211_csa_finish - ieee80211_find_sta - ieee80211_find_sta_by_ifaddr - ieee80211_free_hw - ieee80211_free_txskb - ieee80211_hdrlen - ieee80211_iterate_active_interfaces_atomic - ieee80211_iterate_stations_atomic - ieee80211_iter_chan_contexts_atomic - ieee80211_manage_rx_ba_offl - ieee80211_next_txq - ieee80211_proberesp_get - ieee80211_queue_delayed_work - ieee80211_queue_work - ieee80211_radar_detected - ieee80211_ready_on_channel - ieee80211_register_hw - ieee80211_remain_on_channel_expired - ieee80211_report_low_ack - ieee80211_restart_hw - ieee80211_rx_napi - ieee80211_scan_completed - __ieee80211_schedule_txq - ieee80211_sta_register_airtime - ieee80211_stop_queue - ieee80211_stop_queues - ieee80211_tdls_oper_request - ieee80211_tx_dequeue - ieee80211_txq_get_depth - ieee80211_txq_may_transmit - ieee80211_txq_schedule_start - ieee80211_tx_rate_update - ieee80211_tx_status - ieee80211_tx_status_irqsafe - ieee80211_unregister_hw - ieee80211_wake_queue - ieee80211_wake_queues init_dummy_netdev - init_uts_ns __kfifo_alloc __kfifo_free - __local_bh_enable_ip - __nla_parse - nla_put param_ops_ulong - regulatory_hint - skb_copy skb_dequeue_tail - skb_queue_head skb_realloc_headroom strlcat strscpy - __sw_hweight16 - __sw_hweight8 thermal_cooling_device_register vzalloc - wiphy_read_of_freq_limits - wiphy_rfkill_set_hw_state - wiphy_to_ieee80211_hw # required by ath10k_pci.ko pci_clear_master @@ -801,11 +781,9 @@ iommu_map # required by ax88179_178a.ko - ethtool_op_get_link ethtool_op_get_ts_info mii_ethtool_get_link_ksettings mii_ethtool_set_link_ksettings - netif_carrier_on # required by bam_dma.ko dma_async_device_register @@ -815,7 +793,6 @@ of_dma_controller_free of_dma_controller_register pm_runtime_irq_safe - tasklet_kill tasklet_setup vchan_dma_desc_free_list vchan_find_desc @@ -823,6 +800,59 @@ vchan_tx_desc_free vchan_tx_submit +# required by cfg80211.ko + bpf_trace_run10 + bpf_trace_run7 + debugfs_rename + dev_change_net_namespace + __dev_get_by_index + dev_get_by_index + device_add + device_del + device_rename + genlmsg_multicast_allns + genlmsg_put + genl_register_family + genl_unregister_family + get_net_ns_by_fd + get_net_ns_by_pid + inet_csk_get_port + key_create_or_update + key_put + keyring_alloc + ktime_get_coarse_with_offset + memcmp + netif_rx_ni + netlink_broadcast + netlink_register_notifier + netlink_unicast + netlink_unregister_notifier + net_ns_type_operations + nla_find + nla_memcpy + nla_put_64bit + nla_reserve + __nla_validate + __put_net + rb_erase + rb_insert_color + register_pernet_device + request_firmware_nowait + rfkill_alloc + rfkill_blocked + rfkill_destroy + rfkill_pause_polling + rfkill_register + rfkill_resume_polling + rfkill_set_hw_state + rfkill_unregister + skb_add_rx_frag + __sock_create + trace_print_array_seq + unregister_pernet_device + verify_pkcs7_signature + wireless_nlevent_flush + # required by clk-qcom.ko __clk_determine_rate clk_fixed_factor_ops @@ -836,7 +866,6 @@ __clk_mux_determine_rate_closest divider_ro_round_rate_parent of_find_node_opts_by_path - of_prop_next_u32 pm_genpd_remove_subdomain # required by clk-rpmh.ko @@ -858,7 +887,6 @@ gpiod_get_value_cansleep gpiod_set_debounce gpiod_to_irq - system_power_efficient_wq # required by fastrpc.ko dma_buf_attach @@ -925,9 +953,6 @@ i2c_put_dma_safe_msg_buf of_machine_is_compatible -# required by i2c-qup.ko - __usecs_to_jiffies - # required by i2c-rk3x.ko clk_notifier_register clk_notifier_unregister @@ -953,12 +978,88 @@ mipi_dsi_device_unregister of_find_mipi_dsi_host_by_node +# required by mac80211.ko + alloc_netdev_mqs + __alloc_percpu_gfp + arc4_crypt + arc4_setkey + call_rcu + crc32_be + crypto_aead_decrypt + crypto_aead_encrypt + crypto_aead_setauthsize + crypto_aead_setkey + crypto_alloc_aead + crypto_alloc_shash + crypto_alloc_skcipher + crypto_destroy_tfm + __crypto_memneq + crypto_shash_digest + crypto_shash_finup + crypto_shash_setkey + crypto_shash_update + crypto_skcipher_decrypt + crypto_skcipher_encrypt + crypto_skcipher_setkey + __crypto_xor + dev_alloc_name + dev_fetch_sw_netstats + dev_printk + dev_queue_xmit + ether_setup + flush_delayed_work + free_netdev + free_percpu + get_random_u32 + __hw_addr_init + __hw_addr_sync + __hw_addr_unsync + kernel_param_lock + kernel_param_unlock + kfree_skb_list + ktime_get_seconds + ktime_get_with_offset + napi_gro_receive + netdev_set_default_ethtool_ops + netif_carrier_off + netif_receive_skb + netif_receive_skb_list + netif_rx + netif_tx_stop_all_queues + netif_tx_wake_queue + net_ratelimit + __per_cpu_offset + prandom_bytes + prandom_u32 + ___pskb_trim + rcu_barrier + register_inet6addr_notifier + register_inetaddr_notifier + register_netdevice + rhashtable_free_and_destroy + rhashtable_insert_slow + rhltable_init + __rht_bucket_nested + rht_bucket_nested + rht_bucket_nested_insert + round_jiffies + round_jiffies_relative + sg_init_one + skb_checksum_help + skb_clone_sk + skb_complete_wifi_ack + skb_ensure_writable + __skb_get_hash + __skb_gso_segment + system_freezable_wq + unregister_inet6addr_notifier + unregister_inetaddr_notifier + unregister_netdevice_many + unregister_netdevice_queue + # required by msm.ko __bitmap_andnot __bitmap_weight - bpf_trace_run1 - bpf_trace_run2 - bpf_trace_run6 bpf_trace_run8 clk_get_parent __clk_hw_register_divider @@ -975,10 +1076,8 @@ component_master_add_with_match component_master_del component_unbind_all - _ctype debugfs_create_bool debugfs_create_u64 - del_timer dev_coredumpm devfreq_recommended_opp devfreq_resume_device @@ -1198,12 +1297,9 @@ kthread_create_worker kthread_destroy_worker kthread_queue_work - kvfree - kvmalloc_node llist_add_batch memdup_user_nul memparse - memunmap mipi_dsi_create_packet mipi_dsi_host_register mipi_dsi_host_unregister @@ -1211,20 +1307,16 @@ mutex_lock_interruptible mutex_trylock_recursive nsecs_to_jiffies - nvmem_cell_get - nvmem_cell_put of_clk_hw_onecell_get of_device_is_available of_drm_find_bridge of_drm_find_panel - of_find_device_by_node of_find_matching_node_and_match of_get_compatible_child of_graph_get_endpoint_by_regs of_graph_get_next_endpoint of_graph_get_remote_port_parent of_icc_get - param_ops_charp phy_calibrate phy_configure pid_task @@ -1240,7 +1332,6 @@ regulator_get regulator_put reservation_ww_class - round_jiffies_up sched_set_fifo schedule_timeout_interruptible __sg_page_iter_dma_next @@ -1280,7 +1371,6 @@ dma_pool_create dma_pool_destroy dma_pool_free - flush_work free_pages gen_pool_dma_alloc_align gen_pool_dma_zalloc_align @@ -1391,7 +1481,6 @@ cpufreq_get_driver_data cpufreq_register_driver cpufreq_unregister_driver - __cpu_possible_mask dev_pm_opp_adjust_voltage dev_pm_opp_disable dev_pm_opp_enable @@ -1450,9 +1539,6 @@ # required by qcom_hwspinlock.ko devm_hwspin_lock_register - devm_regmap_field_alloc - regmap_field_read - regmap_field_update_bits_base # required by qcom_pil_info.ko __memset_io @@ -1476,7 +1562,6 @@ __num_online_cpus # required by qcom_spmi-regulator.ko - jiffies_to_usecs regulator_disable_regmap regulator_enable_regmap regulator_is_enabled_regmap @@ -1486,14 +1571,16 @@ rproc_get_by_child try_wait_for_completion -# required by qrtr-smd.ko - __pskb_pull_tail +# required by qcom_tsens.ko + debugfs_lookup + devm_thermal_zone_of_sensor_register + thermal_zone_device_update + thermal_zone_get_slope # required by qrtr-tun.ko _copy_to_iter # required by qrtr.ko - __alloc_skb autoremove_wake_function datagram_poll do_wait_intr_irq @@ -1507,7 +1594,6 @@ refcount_dec_and_mutex_lock release_sock sk_alloc - skb_copy_bits skb_copy_datagram_iter skb_free_datagram __skb_pad @@ -1526,7 +1612,6 @@ sock_queue_rcv_skb sock_register sock_unregister - synchronize_rcu # required by reboot-mode.ko devres_add @@ -1545,8 +1630,6 @@ # required by rmtfs_mem.ko alloc_chrdev_region - __class_register - class_unregister # required by rtc-pm8xxx.ko devm_request_any_context_irq @@ -1605,9 +1688,6 @@ snd_soc_of_parse_aux_devs snd_soc_of_parse_card_name -# required by snd-soc-rl6231.ko - gcd - # required by snd-soc-rt5663.ko regcache_cache_bypass snd_soc_add_component_controls @@ -1666,7 +1746,6 @@ spi_delay_exec spi_finalize_current_message spi_get_next_queued_message - tasklet_init # required by spmi-pmic-arb.ko irq_domain_set_info @@ -1686,7 +1765,6 @@ dma_sync_sg_for_cpu dma_sync_sg_for_device __free_pages - preempt_schedule __sg_page_iter_next # required by ufs_qcom.ko diff --git a/android/abi_gki_aarch64_exynos b/android/abi_gki_aarch64_exynos index 2240832a275f..c90c881c0e1a 100644 --- a/android/abi_gki_aarch64_exynos +++ b/android/abi_gki_aarch64_exynos @@ -3,11 +3,17 @@ add_cpu add_timer add_timer_on + add_uevent_var + add_wait_queue adjust_managed_page_count alarm_cancel alarm_init + alarm_start alarm_start_relative + alloc_anon_inode alloc_chrdev_region + __alloc_disk_node + alloc_etherdev_mqs alloc_netdev_mqs __alloc_pages_nodemask __alloc_percpu @@ -17,8 +23,14 @@ amba_driver_unregister android_debug_symbol android_rvh_probe_register + anon_inode_getfd + anon_inode_getfile + __arch_clear_user __arch_copy_from_user + __arch_copy_in_user __arch_copy_to_user + argv_free + argv_split arm64_const_caps_ready arm64_use_ng_mappings __arm_smccc_hvc @@ -31,27 +43,46 @@ backlight_device_register backlight_device_unregister bcmp + bdget_disk + bdput + bio_endio __bitmap_andnot + __bitmap_clear __bitmap_complement __bitmap_or bitmap_parse bitmap_parselist + bitmap_print_to_pagebuf + __bitmap_set bitmap_to_arr32 __bitmap_weight __bitmap_xor + blk_alloc_queue + blk_cleanup_queue blkdev_get_by_path + blkdev_put + blk_ksm_init + blk_queue_flag_clear + blk_queue_flag_set + blk_queue_io_min + blk_queue_io_opt + blk_queue_logical_block_size + blk_queue_max_discard_sectors + blk_queue_max_write_zeroes_sectors + blk_queue_physical_block_size blocking_notifier_call_chain blocking_notifier_chain_register blocking_notifier_chain_unregister + bpf_trace_run1 bpf_trace_run10 bpf_trace_run12 - bpf_trace_run1 bpf_trace_run2 bpf_trace_run3 bpf_trace_run4 bpf_trace_run5 bpf_trace_run6 bpf_trace_run7 + bpf_trace_run8 bpf_trace_run9 build_skb bus_find_device @@ -61,12 +92,14 @@ bus_set_iommu bus_unregister bus_unregister_notifier + cache_line_size call_rcu cancel_delayed_work cancel_delayed_work_sync cancel_work_sync capable cdev_add + cdev_alloc cdev_del cdev_device_add cdev_device_del @@ -77,9 +110,13 @@ __check_object_size check_preempt_curr __class_create + class_create_file_ns class_destroy + class_find_device __class_register class_unregister + clear_page + __ClearPageMovable clk_disable clk_enable clk_get @@ -88,12 +125,14 @@ clk_get_rate clk_hw_get_name clk_hw_get_parent + clk_hw_get_rate __clk_hw_register_divider __clk_hw_register_gate __clk_hw_register_mux clk_hw_unregister_divider clk_hw_unregister_gate clk_hw_unregister_mux + __clk_is_enabled clk_prepare clk_put clk_register @@ -106,17 +145,31 @@ clk_unprepare clockevents_config_and_register __clocksource_register_scale + __close_fd cma_alloc cma_release + compat_alloc_user_space complete complete_all complete_and_exit completion_done + component_add + component_bind_all + component_del + component_master_add_with_match + component_master_del + component_match_add_release + component_unbind_all config_ep_by_speed config_group_init_type_name + console_lock + console_printk console_stop console_suspend_enabled + console_trylock + console_unlock __const_udelay + consume_skb contig_page_data __cpu_active_mask cpu_all_bits @@ -125,10 +178,14 @@ cpufreq_cpu_get cpufreq_cpu_get_raw cpufreq_cpu_put + cpufreq_disable_fast_switch + cpufreq_driver_fast_switch cpufreq_driver_resolve_freq __cpufreq_driver_target + cpufreq_enable_fast_switch cpufreq_freq_transition_begin cpufreq_freq_transition_end + cpufreq_frequency_table_get_index cpufreq_frequency_table_verify cpufreq_generic_attr cpufreq_get_policy @@ -141,11 +198,17 @@ cpufreq_table_index_unsorted cpufreq_this_cpu_can_update cpufreq_unregister_notifier + __cpuhp_remove_state __cpuhp_setup_state __cpuhp_setup_state_cpuslocked + __cpuhp_state_add_instance + __cpuhp_state_remove_instance cpuhp_tasks_frozen cpu_hwcap_keys cpu_hwcaps + cpuidle_get_cpu_driver + cpuidle_pause_and_lock + cpuidle_resume_and_unlock cpumask_next cpumask_next_and cpu_number @@ -157,10 +220,23 @@ cpus_read_unlock cpu_subsys cpu_topology + crc32_le + crypto_alloc_base crypto_alloc_shash + crypto_comp_compress + crypto_comp_decompress crypto_destroy_tfm + crypto_has_alg + __crypto_memneq + crypto_register_alg + crypto_register_scomp + crypto_shash_digest crypto_shash_final crypto_shash_update + crypto_unregister_alg + crypto_unregister_scomp + csum_partial + csum_tcpudp_nofold _ctype dapm_pinctrl_event dapm_regulator_event @@ -171,12 +247,21 @@ debugfs_create_symlink debugfs_create_u32 debugfs_create_x32 + debugfs_create_x64 debugfs_remove + debugfs_rename + dec_zone_page_state default_llseek + default_wake_function + deferred_free delayed_work_timer_fn + del_gendisk del_timer del_timer_sync destroy_workqueue + dev_alloc_name + dev_change_net_namespace + dev_close _dev_crit dev_driver_string _dev_emerg @@ -184,6 +269,7 @@ dev_err_probe devfreq_add_device devfreq_add_governor + devfreq_get_devfreq_by_phandle devfreq_monitor_resume devfreq_monitor_start devfreq_monitor_stop @@ -196,21 +282,29 @@ devfreq_suspend_device devfreq_unregister_opp_notifier devfreq_update_interval + __dev_get_by_index + dev_get_by_index dev_get_by_name dev_get_regmap + device_add + device_add_disk device_create device_create_bin_file device_create_file + device_del device_destroy device_for_each_child + device_get_dma_attr device_initialize device_init_wakeup device_link_add device_link_del device_property_present + device_property_read_string_array device_property_read_u32_array device_register device_remove_file + device_rename device_set_wakeup_capable device_set_wakeup_enable device_show_bool @@ -222,18 +316,27 @@ _dev_info __dev_kfree_skb_any devm_add_action + devm_backlight_device_register + devm_backlight_device_unregister devm_clk_get devm_clk_get_optional + devm_clk_put devm_devfreq_register_notifier devm_devfreq_unregister_notifier __devm_drm_dev_alloc + devm_drm_panel_bridge_add_typed + devm_extcon_dev_allocate + devm_extcon_dev_register devm_free_irq devm_gen_pool_create devm_gpiochip_add_data_with_key + devm_gpiod_get devm_gpiod_get_optional + devm_gpio_request devm_gpio_request_one devm_hwrng_register devm_i2c_new_dummy_device + devm_iio_channel_get devm_iio_device_alloc __devm_iio_device_register devm_input_allocate_device @@ -245,6 +348,7 @@ devm_kfree devm_kmalloc devm_kmemdup + devm_krealloc devm_kstrdup devm_kstrdup_const devm_led_classdev_register_ext @@ -252,18 +356,25 @@ __devm_of_phy_provider_register devm_phy_create devm_phy_get + devm_phy_put devm_pinctrl_get + devm_pinctrl_put devm_pinctrl_register devm_platform_get_and_ioremap_resource devm_platform_ioremap_resource + devm_platform_ioremap_resource_byname + __devm_regmap_init __devm_regmap_init_i2c __devm_regmap_init_mmio_clk devm_regulator_bulk_get devm_regulator_get + devm_regulator_get_optional devm_regulator_register + __devm_release_region __devm_request_region devm_request_threaded_irq __devm_reset_control_get + devm_rtc_allocate_device devm_rtc_device_register devm_snd_dmaengine_pcm_register devm_snd_soc_register_card @@ -275,25 +386,34 @@ dev_pm_opp_disable dev_pm_opp_find_freq_ceil dev_pm_opp_find_freq_exact + dev_pm_opp_find_freq_floor dev_pm_opp_get_freq dev_pm_opp_get_opp_count dev_pm_opp_get_voltage + dev_pm_opp_of_add_table dev_pm_opp_of_register_em + dev_pm_opp_of_remove_table dev_pm_opp_put + dev_pm_opp_put_regulators + dev_pm_opp_set_regulators dev_pm_qos_add_request dev_pm_qos_read_value dev_pm_qos_remove_request dev_pm_qos_update_request + dev_printk dev_queue_xmit devres_add devres_alloc_node devres_free devres_release dev_set_name + dev_vprintk_emit _dev_warn disable_irq disable_irq_nosync disable_percpu_irq + disk_end_io_acct + disk_start_io_acct dma_alloc_attrs dma_async_device_register dma_async_device_unregister @@ -311,6 +431,10 @@ dma_buf_map_attachment dma_buf_mmap dma_buf_move_notify + dmabuf_page_pool_alloc + dmabuf_page_pool_create + dmabuf_page_pool_destroy + dmabuf_page_pool_free dma_buf_pin dma_buf_put dma_buf_unmap_attachment @@ -322,6 +446,7 @@ dma_fence_array_create dma_fence_context_alloc dma_fence_default_wait + dma_fence_get_status dma_fence_get_stub dma_fence_init dma_fence_release @@ -345,6 +470,7 @@ dma_map_page_attrs dma_map_resource dma_map_sg_attrs + dmam_free_coherent dma_mmap_attrs dma_pool_alloc dma_pool_free @@ -368,14 +494,69 @@ do_SAK do_wait_intr down + downgrade_write + down_interruptible down_read down_read_killable down_read_trylock + down_trylock down_write d_path drain_workqueue + driver_register driver_unregister drm_add_edid_modes + drm_atomic_add_affected_connectors + drm_atomic_add_affected_planes + drm_atomic_commit + drm_atomic_get_crtc_state + drm_atomic_get_plane_state + drm_atomic_get_private_obj_state + drm_atomic_helper_check_modeset + drm_atomic_helper_check_planes + drm_atomic_helper_check_plane_state + drm_atomic_helper_cleanup_planes + drm_atomic_helper_commit_cleanup_done + drm_atomic_helper_commit_duplicated_state + drm_atomic_helper_commit_hw_done + drm_atomic_helper_commit_modeset_disables + drm_atomic_helper_commit_modeset_enables + drm_atomic_helper_commit_planes + drm_atomic_helper_commit_tail + __drm_atomic_helper_connector_destroy_state + drm_atomic_helper_connector_destroy_state + __drm_atomic_helper_connector_duplicate_state + drm_atomic_helper_connector_duplicate_state + drm_atomic_helper_connector_reset + __drm_atomic_helper_crtc_destroy_state + __drm_atomic_helper_crtc_duplicate_state + drm_atomic_helper_disable_plane + drm_atomic_helper_disable_planes_on_crtc + drm_atomic_helper_duplicate_state + drm_atomic_helper_fake_vblank + drm_atomic_helper_page_flip + __drm_atomic_helper_plane_destroy_state + __drm_atomic_helper_plane_duplicate_state + drm_atomic_helper_prepare_planes + __drm_atomic_helper_private_obj_duplicate_state + drm_atomic_helper_set_config + drm_atomic_helper_setup_commit + drm_atomic_helper_swap_state + drm_atomic_helper_update_plane + drm_atomic_helper_wait_for_dependencies + drm_atomic_helper_wait_for_fences + drm_atomic_normalize_zpos + drm_atomic_private_obj_fini + drm_atomic_private_obj_init + drm_atomic_set_crtc_for_plane + drm_atomic_set_fb_for_plane + drm_atomic_set_mode_for_crtc + drm_atomic_state_alloc + __drm_atomic_state_free + drm_bridge_add + drm_bridge_attach + drm_bridge_chain_mode_set + drm_bridge_remove drm_compat_ioctl drm_connector_attach_dp_subconnector_property drm_connector_attach_encoder @@ -385,14 +566,20 @@ drm_connector_list_iter_begin drm_connector_list_iter_end drm_connector_list_iter_next + drm_connector_register drm_connector_unregister drm_connector_update_edid_property + drm_crtc_arm_vblank_event drm_crtc_cleanup + drm_crtc_enable_color_mgmt + drm_crtc_handle_vblank drm_crtc_helper_set_config drm_crtc_helper_set_mode drm_crtc_init + drm_crtc_init_with_planes drm_crtc_send_vblank_event drm_crtc_vblank_count + drm_crtc_vblank_get drm_crtc_vblank_helper_get_vblank_timestamp drm_crtc_vblank_off drm_crtc_vblank_on @@ -402,11 +589,13 @@ __drm_debug drm_debugfs_create_files drm_detect_hdmi_monitor + drm_dev_alloc drm_dev_dbg drm_dev_printk drm_dev_put drm_dev_register drm_dev_unregister + drm_display_mode_to_videomode drm_dp_aux_init drm_dp_aux_register drm_dp_aux_unregister @@ -429,9 +618,11 @@ drm_encoder_cleanup drm_encoder_init __drm_err + drm_format_info drm_framebuffer_cleanup drm_framebuffer_init drm_framebuffer_unregister_private + drm_gem_create_mmap_offset drm_gem_dmabuf_mmap drm_gem_dmabuf_release drm_gem_dmabuf_vmap @@ -439,17 +630,23 @@ drm_gem_fb_create_handle drm_gem_fb_destroy drm_gem_handle_create + drm_gem_mmap drm_gem_object_free drm_gem_object_lookup drm_gem_object_release drm_gem_prime_export drm_gem_prime_fd_to_handle drm_gem_prime_handle_to_fd + drm_gem_prime_import_dev drm_gem_private_object_init + drm_gem_vm_close + drm_gem_vm_open drm_get_edid + drm_get_format_info drm_get_format_name drm_handle_vblank drm_hdmi_avi_infoframe_from_display_mode + drm_hdmi_infoframe_set_hdr_metadata drm_helper_connector_dpms drm_helper_disable_unused_functions drm_helper_force_disable_all @@ -461,6 +658,7 @@ drm_irq_install drm_irq_uninstall drm_is_current_master + drm_kms_helper_hotplug_event drm_kms_helper_is_poll_worker drm_kms_helper_poll_disable drm_kms_helper_poll_enable @@ -473,13 +671,23 @@ drm_mm_remove_node drm_mm_takedown drm_mode_config_cleanup + drm_mode_config_reset + drm_mode_convert_to_umode + drm_mode_copy drm_mode_create_scaling_mode_property drm_mode_crtc_set_gamma_size drm_mode_duplicate + drm_mode_equal + drm_mode_match drm_mode_probed_add + drm_modeset_acquire_fini + drm_modeset_acquire_init + drm_modeset_backoff drm_mode_set_crtcinfo + drm_modeset_drop_locks drm_modeset_lock drm_modeset_lock_all + drm_modeset_lock_all_ctx drm_mode_set_name drm_modeset_unlock drm_modeset_unlock_all @@ -487,17 +695,43 @@ drm_need_swiotlb drm_object_attach_property drm_open + drm_panel_add + drm_panel_disable + drm_panel_enable + drm_panel_get_modes + drm_panel_init + drm_panel_prepare + drm_panel_remove + drm_panel_unprepare + drm_plane_cleanup + drm_plane_create_alpha_property + drm_plane_create_blend_mode_property + drm_plane_create_rotation_property + drm_plane_create_zpos_property drm_poll drm_prime_gem_destroy drm_prime_pages_to_sg drm_prime_sg_to_page_addr_arrays drm_printf + __drm_printfn_info __drm_printfn_seq_file + drm_property_blob_get + drm_property_blob_put + drm_property_create + drm_property_create_bitmask + drm_property_create_blob + drm_property_create_bool drm_property_create_enum drm_property_create_range + drm_property_create_signed_range + drm_property_lookup_blob + drm_property_replace_blob __drm_puts_seq_file drm_read + drm_rect_clip_scaled + drm_rect_intersect drm_release + drm_rotation_simplify drm_syncobj_add_point drm_syncobj_create drm_syncobj_find @@ -506,10 +740,14 @@ drm_syncobj_get_fd drm_syncobj_get_handle drm_syncobj_replace_fence + drm_universal_plane_init drm_vblank_init drm_vma_node_allow drm_vma_node_is_allowed drm_vma_node_revoke + drm_writeback_connector_init + drm_writeback_queue_job + drm_writeback_signal_completion dump_backtrace dump_stack dw_handle_msi_irq @@ -522,9 +760,17 @@ emergency_restart enable_irq enable_percpu_irq + end_buffer_read_sync + ether_setup + eth_type_trans event_triggers_call + extcon_get_state + extcon_set_state_sync + failure_tracking + fb_mode_option __fdget fd_install + find_get_pid find_last_bit find_next_bit find_next_zero_bit @@ -549,33 +795,59 @@ freq_qos_remove_request freq_qos_update_request freq_scale + fsync_bdev gcd generic_file_llseek generic_handle_irq + genlmsg_multicast_allns + genlmsg_put + genl_register_family + genl_unregister_family gen_pool_add_owner gen_pool_alloc_algo_owner + gen_pool_avail + gen_pool_create + gen_pool_destroy + gen_pool_first_fit_align gen_pool_free_owner + gen_pool_has_addr + gen_pool_size + __getblk_gfp get_cpu_device get_cpu_idle_time get_device __get_free_pages + get_net_ns_by_fd + get_net_ns_by_pid + get_random_bytes get_random_u32 __get_task_comm get_task_exe_file get_task_mm get_thermal_instance get_unused_fd_flags + get_user_pages + get_user_pages_fast + get_user_pages_remote + __get_vm_area_caller get_zeroed_page gic_nonsecure_priorities + gpiochip_add_data_with_key + gpiochip_add_pin_range gpiochip_generic_free gpiochip_generic_request gpiochip_get_data gpiochip_lock_as_irq + gpiochip_remove gpiochip_unlock_as_irq gpiod_direction_input + gpiod_direction_output gpiod_direction_output_raw gpiod_get_raw_value + gpiod_get_raw_value_cansleep gpiod_set_raw_value + gpiod_set_raw_value_cansleep + gpiod_set_value gpiod_set_value_cansleep gpiod_to_irq gpio_free @@ -591,7 +863,10 @@ handle_simple_irq handle_sysrq hdmi_avi_infoframe_pack + hdmi_drm_infoframe_pack_only hex_dump_to_buffer + hmm_range_fault + housekeeping_cpumask hrtimer_active hrtimer_cancel hrtimer_forward @@ -602,6 +877,7 @@ i2c_add_numbered_adapter i2c_bit_add_bus i2c_bus_type + i2c_clients_command i2c_del_adapter i2c_del_driver i2c_for_each_dev @@ -617,10 +893,26 @@ i2c_smbus_write_i2c_block_data i2c_smbus_write_word_data i2c_smbus_xfer + __i2c_transfer i2c_transfer i2c_transfer_buffer_flags i2c_unregister_device i2c_verify_client + i3c_generic_ibi_alloc_pool + i3c_generic_ibi_free_pool + i3c_generic_ibi_get_free_slot + i3c_generic_ibi_recycle_slot + i3c_master_add_i3c_dev_locked + i3c_master_defslvs_locked + i3c_master_disec_locked + i3c_master_do_daa + i3c_master_enec_locked + i3c_master_entdaa_locked + i3c_master_get_free_addr + i3c_master_queue_ibi + i3c_master_register + i3c_master_set_info + i3c_master_unregister ida_alloc_range ida_destroy ida_free @@ -631,12 +923,27 @@ idr_get_next idr_remove idr_replace + ignore_console_lock_warning + iio_channel_get + iio_channel_release + iio_convert_raw_to_processed + iio_device_alloc + iio_device_free + __iio_device_register + iio_device_unregister + iio_get_channel_type + iio_read_channel_processed + iio_read_channel_raw + inc_zone_page_state + inet_csk_get_port init_dummy_netdev init_net + init_pseudo __init_rwsem __init_swait_queue_head init_task init_timer_key + init_uts_ns init_wait_entry __init_waitqueue_head input_allocate_device @@ -654,6 +961,7 @@ input_set_capability input_unregister_device input_unregister_handle + int_sqrt iomem_resource iommu_alloc_resv_region iommu_attach_group @@ -682,8 +990,12 @@ iommu_report_device_fault iommu_unmap iommu_unregister_device_fault_handler + __ioread32_copy __ioremap iounmap + __iowrite32_copy + ip_send_check + iput __irq_alloc_descs irq_create_mapping_affinity __irq_domain_add @@ -693,6 +1005,7 @@ irq_domain_xlate_onetwocell irq_domain_xlate_twocell irq_find_mapping + irq_get_irqchip_state irq_get_irq_data irq_modify_status irq_of_parse_and_map @@ -703,21 +1016,40 @@ irq_set_chip_data __irq_set_handler irq_set_handler_data + irq_set_irqchip_state irq_set_irq_wake irq_to_desc irq_work_queue irq_work_sync + is_console_locked + is_dma_buf_file is_vmalloc_addr + iterate_fd + jiffies jiffies_64_to_clock_t jiffies64_to_msecs - jiffies jiffies_to_msecs jiffies_to_usecs kasan_flag_enabled kasprintf kernel_kobj + kern_mount + kern_unmount + key_create_or_update + key_put + keyring_alloc + __kfifo_alloc + __kfifo_free + __kfifo_in + __kfifo_init + __kfifo_out + __kfifo_to_user kfree kfree_const + kfree_sensitive + kfree_skb + kfree_skb_list + kill_anon_super kimage_voffset __kmalloc kmalloc_caches @@ -740,11 +1072,13 @@ kstat kstrdup kstrndup + kstrtobool kstrtobool_from_user kstrtoint kstrtoint_from_user kstrtol_from_user kstrtoll + kstrtou16 kstrtou8 kstrtouint kstrtouint_from_user @@ -753,9 +1087,11 @@ ksys_sync_helper kthread_bind kthread_cancel_delayed_work_sync + kthread_cancel_work_sync kthread_create_on_node kthread_delayed_work_timer_fn kthread_flush_work + kthread_flush_worker __kthread_init_worker kthread_mod_delayed_work kthread_park @@ -767,7 +1103,9 @@ kthread_unpark kthread_worker_fn ktime_get + ktime_get_coarse_with_offset ktime_get_mono_fast_ns + ktime_get_raw ktime_get_raw_ts64 ktime_get_real_seconds ktime_get_real_ts64 @@ -775,28 +1113,72 @@ ktime_get_with_offset kvasprintf kvfree + kvfree_call_rcu kvmalloc_node __list_add_valid __list_del_entry_valid + list_sort + llist_add_batch + __local_bh_enable_ip + __lock_buffer + __lock_page __log_post_read_mmio __log_read_mmio __log_write_mmio loops_per_jiffy + lzo1x_1_compress + lzo1x_decompress_safe + lzorle1x_1_compress + map_kernel_range + media_device_register_entity + media_entity_pads_init memchr + memcmp memcpy __memcpy_fromio __memcpy_toio memdup_user memmove + memparse memremap memset + memset64 __memset_io memstart_addr memunmap mfd_add_devices mfd_remove_devices + mipi_dsi_attach + mipi_dsi_compression_mode + mipi_dsi_dcs_read + mipi_dsi_dcs_set_column_address + mipi_dsi_dcs_set_display_brightness + mipi_dsi_dcs_set_page_address + mipi_dsi_dcs_write_buffer + mipi_dsi_detach + mipi_dsi_device_register_full + mipi_dsi_driver_register_full + mipi_dsi_driver_unregister + mipi_dsi_host_register + mipi_dsi_host_unregister + mipi_dsi_picture_parameter_set misc_deregister misc_register + mmc_add_host + mmc_alloc_host + mmc_can_gpio_cd + mmc_detect_change + mmc_free_host + mmc_gpio_get_cd + mmc_gpio_get_ro + mmc_of_parse + mmc_regulator_get_supply + mmc_regulator_set_ocr + mmc_regulator_set_vqmmc + mmc_remove_host + mmc_request_done + mmc_wait_for_req + __mmdrop mmput mmu_interval_notifier_insert mmu_interval_notifier_remove @@ -809,49 +1191,85 @@ module_put __msecs_to_jiffies msleep + msleep_interruptible __mutex_init mutex_is_locked mutex_lock mutex_lock_interruptible mutex_trylock mutex_unlock + names_cachep __napi_alloc_skb napi_complete_done + napi_disable napi_gro_flush napi_gro_receive __napi_schedule napi_schedule_prep __netdev_alloc_skb + netdev_err + netif_carrier_off + netif_carrier_on netif_napi_add + __netif_napi_del netif_receive_skb + netif_rx + netif_rx_ni + netif_tx_stop_all_queues netif_tx_wake_queue + netlink_broadcast + __netlink_kernel_create + netlink_kernel_release + netlink_register_notifier + netlink_unicast + netlink_unregister_notifier + net_ns_type_operations + net_ratelimit + nla_append + nla_find + nla_memcpy + __nla_parse + nla_put + nla_put_64bit + nla_put_nohdr + nla_reserve + __nla_validate + __nlmsg_put no_llseek + nonseekable_open noop_llseek nr_cpu_ids nr_irqs nsecs_to_jiffies + ns_to_kernel_old_timeval ns_to_timespec64 __num_online_cpus of_address_to_resource + of_alias_get_highest_id of_alias_get_id of_clk_add_hw_provider of_clk_add_provider of_clk_del_provider + of_clk_get of_clk_get_by_name of_clk_hw_onecell_get of_clk_src_onecell_get of_count_phandle_with_args + of_cpu_node_to_id of_device_get_match_data of_device_is_available of_device_is_compatible of_dma_controller_free of_dma_controller_register + of_drm_find_bridge + of_drm_find_panel of_find_compatible_node of_find_device_by_node of_find_matching_node_and_match of_find_node_by_name of_find_node_by_type of_find_node_opts_by_path + of_find_node_with_property of_find_property of_fwnode_ops of_genpd_add_provider_simple @@ -863,6 +1281,8 @@ of_get_next_child of_get_property of_get_regulator_init_data + of_get_videomode + of_i2c_get_board_info of_iomap of_irq_get_byname of_irq_parse_one @@ -873,6 +1293,7 @@ of_node_name_eq of_n_size_cells of_parse_phandle + of_parse_phandle_with_args of_parse_phandle_with_fixed_args of_phandle_iterator_init of_phandle_iterator_next @@ -883,6 +1304,7 @@ of_property_read_string_helper of_property_read_u32_index of_property_read_u64 + of_property_read_variable_u16_array of_property_read_variable_u32_array of_property_read_variable_u8_array of_prop_next_string @@ -894,27 +1316,41 @@ of_root of_thermal_get_ntrips of_usb_host_tpl_support + oops_in_progress orderly_poweroff + page_endio + page_mapping + __page_pinner_migration_failed panic panic_notifier_list + param_array_ops param_ops_bool + param_ops_byte param_ops_charp param_ops_hexint param_ops_int param_ops_long param_ops_string param_ops_uint + param_ops_ullong param_ops_ulong + param_set_uint pci_alloc_irq_vectors_affinity + pci_assign_resource pci_assign_unassigned_bus_resources pci_bus_resource_n pci_bus_type pci_clear_master + pci_disable_device pcie_bandwidth_available pcie_get_mps pcie_get_speed_cap pci_enable_atomic_ops_to_root + pci_enable_device + pci_enable_pcie_error_reporting + pci_enable_wake pci_find_bus + pci_find_capability pci_find_ext_capability pci_free_irq_vectors pci_generic_config_read @@ -923,19 +1359,23 @@ pci_get_domain_bus_and_slot pci_iomap pci_irq_vector + pci_load_and_free_saved_state pci_load_saved_state pci_map_rom pci_msix_vec_count pci_read_config_dword pci_read_config_word + __pci_register_driver pci_release_resource pci_rescan_bus pci_resize_resource pci_restore_state pci_save_state pci_set_master + pci_set_power_state pci_store_saved_state pci_unmap_rom + pci_unregister_driver pci_write_config_dword pci_write_config_word PDE_DATA @@ -946,17 +1386,27 @@ perf_trace_buf_alloc perf_trace_run_bpf_submit pfn_valid + phy_configure + phy_init + phy_power_off + phy_power_on + phy_reset pid_task + pinconf_generic_dt_node_to_map pinctrl_add_gpio_range pinctrl_dev_get_drvdata pinctrl_force_sleep pinctrl_get pinctrl_lookup_state + pinctrl_pm_select_default_state + pinctrl_pm_select_sleep_state pinctrl_put pinctrl_remove_gpio_range pinctrl_select_state + pinctrl_utils_free_map pin_get_name pin_user_pages + pin_user_pages_remote platform_bus_type platform_device_add platform_device_add_properties @@ -970,6 +1420,7 @@ __platform_driver_probe __platform_driver_register platform_driver_unregister + platform_find_device_by_driver platform_get_irq platform_get_irq_byname platform_get_resource @@ -1010,6 +1461,7 @@ power_supply_register power_supply_set_property power_supply_unregister + prandom_u32 preempt_schedule preempt_schedule_notrace prepare_to_wait_event @@ -1019,12 +1471,20 @@ printk_timed_ratelimit proc_create proc_create_data + proc_create_seq_private proc_mkdir + proc_mkdir_data proc_remove proc_set_size + proc_set_user proc_symlink + __pskb_copy_fclone + __pskb_pull_tail put_device + put_disk + __put_net __put_page + put_pid __put_task_struct put_unused_fd pwmchip_add @@ -1039,24 +1499,37 @@ raw_notifier_chain_register raw_notifier_chain_unregister _raw_read_lock + _raw_read_lock_bh _raw_read_lock_irqsave _raw_read_unlock + _raw_read_unlock_bh _raw_read_unlock_irqrestore _raw_spin_lock + _raw_spin_lock_bh _raw_spin_lock_irq _raw_spin_lock_irqsave _raw_spin_trylock _raw_spin_unlock + _raw_spin_unlock_bh _raw_spin_unlock_irq _raw_spin_unlock_irqrestore + _raw_write_lock + _raw_write_lock_bh _raw_write_lock_irqsave + _raw_write_trylock + _raw_write_unlock + _raw_write_unlock_bh _raw_write_unlock_irqrestore + rb_erase __rb_erase_color + rb_first rb_first_postorder __rb_insert_augmented rb_insert_color rb_next rb_next_postorder + rb_prev + rb_replace_node rcu_barrier __rcu_read_lock __rcu_read_unlock @@ -1066,15 +1539,23 @@ refcount_warn_saturate refresh_frequency_limits __refrigerator + regcache_cache_bypass regcache_cache_only regcache_drop_region regcache_mark_dirty regcache_sync + register_blkdev __register_chrdev register_chrdev_region register_console register_die_notifier + register_inet6addr_notifier + register_inetaddr_notifier register_netdev + register_netdevice + register_netdevice_notifier + register_oom_notifier + register_pernet_device register_pm_notifier register_reboot_notifier register_restart_handler @@ -1082,6 +1563,7 @@ register_syscore_ops regmap_async_complete regmap_bulk_read + regmap_bulk_write regmap_multi_reg_write regmap_multi_reg_write_bypassed regmap_raw_read @@ -1095,57 +1577,91 @@ regulator_bulk_enable regulator_disable regulator_enable + regulator_force_disable regulator_get + regulator_get_optional + regulator_get_voltage regulator_is_enabled regulator_list_voltage_linear regulator_map_voltage_linear regulator_put + regulator_set_mode regulator_set_voltage release_firmware release_pages __release_region remap_pfn_range + remap_vmalloc_range remove_cpu + remove_proc_entry + remove_wait_queue request_firmware request_firmware_direct request_firmware_into_buf request_firmware_nowait + __request_module __request_percpu_irq __request_region request_threaded_irq reset_control_assert reset_control_deassert return_address + revalidate_disk_size + rfkill_alloc + rfkill_blocked + rfkill_destroy + rfkill_pause_polling + rfkill_register + rfkill_resume_polling + rfkill_set_hw_state + rfkill_unregister + rps_needed rtc_class_close rtc_class_open rtc_read_time + __rtc_register_device + rtc_set_time rtc_time64_to_tm + rtc_tm_to_time64 rtc_update_irq rtc_valid_tm + rtnl_is_locked + rtnl_lock + rtnl_unlock runqueues sched_clock sched_set_fifo_low sched_set_normal + sched_setscheduler sched_setscheduler_nocheck schedule schedule_timeout + schedule_timeout_interruptible scnprintf scsi_block_when_processing_errors + scsi_eh_ready_devs __scsi_execute scsi_print_sense_hdr sdev_prefix_printk + sdio_signal_irq seq_lseek + seq_open seq_printf + seq_putc seq_puts seq_read + seq_release seq_write set_cpus_allowed_ptr set_normalized_timespec64 set_page_dirty_lock + __SetPageMovable set_task_cpu sg_alloc_table sg_alloc_table_from_pages + sg_copy_to_buffer sg_free_table + sg_init_one sg_init_table sg_miter_next sg_miter_start @@ -1161,12 +1677,16 @@ simple_attr_write simple_open simple_read_from_buffer + simple_strtol simple_strtoul simple_write_to_buffer single_open single_open_size single_release + skb_add_rx_frag skb_clone + skb_copy + skb_copy_bits skb_copy_expand skb_dequeue skb_dequeue_tail @@ -1176,6 +1696,7 @@ skb_queue_head skb_queue_purge skb_queue_tail + skb_realloc_headroom skb_trim smp_call_function smp_call_function_many @@ -1193,7 +1714,9 @@ snd_hwdep_new snd_pcm_format_physical_width snd_pcm_format_width + snd_pcm_hw_constraint_integer snd_pcm_hw_constraint_list + snd_pcm_hw_constraint_mask64 snd_pcm_lib_free_pages snd_pcm_lib_ioctl snd_pcm_lib_malloc_pages @@ -1262,13 +1785,20 @@ snd_soc_register_card snd_soc_register_component snd_soc_set_runtime_hwparams + snd_soc_tplg_component_load + snd_soc_tplg_component_remove + snd_soc_tplg_widget_bind_event snd_soc_unregister_card snd_soc_unregister_component snd_vendor_set_ops snprintf soc_device_register + __sock_create + sock_release + softnet_data sort __spi_alloc_controller + spi_bus_type spi_controller_resume spi_controller_suspend spi_finalize_current_message @@ -1287,31 +1817,46 @@ sscanf __stack_chk_fail __stack_chk_guard + static_key_slow_dec + static_key_slow_inc stop_one_cpu_nowait + stpcpy strcasecmp strcat strchr strcmp strcpy + strcspn stream_open strim strlcat strlcpy strlen strncasecmp + strncat + strnchr strncmp strncpy strnlen strnstr strpbrk + strrchr + strscpy strsep + strspn strstr + submit_bh subsys_system_register + __sw_hweight16 __sw_hweight32 __sw_hweight64 + __sw_hweight8 swiotlb_nr_tbl + __sync_dirty_buffer sync_file_create sync_file_get_fence + synchronize_irq + synchronize_net synchronize_rcu syscon_regmap_lookup_by_phandle sysfs_add_file_to_group @@ -1321,6 +1866,9 @@ sysfs_create_group sysfs_create_groups sysfs_create_link + sysfs_emit + __sysfs_match_string + sysfs_merge_group sysfs_notify sysfs_remove_bin_file sysfs_remove_file_from_group @@ -1328,10 +1876,12 @@ sysfs_remove_files sysfs_remove_group sysfs_remove_link + sysfs_streq sysrq_mask system_freezable_wq system_freezing_cnt system_highpri_wq + system_power_efficient_wq system_state system_unbound_wq system_wq @@ -1354,6 +1904,7 @@ time64_to_tm topology_set_thermal_pressure _totalram_pages + __trace_bprintk trace_event_buffer_commit trace_event_buffer_reserve trace_event_ignore_this_pid @@ -1365,6 +1916,11 @@ __traceiter_android_rvh_dequeue_task __traceiter_android_rvh_enqueue_task __traceiter_android_rvh_find_lowest_rq + __traceiter_android_rvh_find_new_ilb + __traceiter_android_rvh_gic_v3_set_affinity + __traceiter_android_rvh_post_init_entity_util_avg + __traceiter_android_rvh_replace_next_task_fair + __traceiter_android_rvh_sched_fork_init __traceiter_android_rvh_sched_newidle_balance __traceiter_android_rvh_sched_nohz_balancer_kick __traceiter_android_rvh_sched_rebalance_domains @@ -1373,12 +1929,16 @@ __traceiter_android_rvh_select_task_rq_rt __traceiter_android_vh_cpu_idle_enter __traceiter_android_vh_cpu_idle_exit - __traceiter_android_rvh_gic_v3_set_affinity __traceiter_android_vh_ipi_stop __traceiter_android_vh_scheduler_tick + __traceiter_android_vh_show_mem + __traceiter_android_vh_ufs_compl_command + __traceiter_android_vh_ufs_prepare_command __traceiter_cpu_idle __traceiter_device_pm_callback_end __traceiter_device_pm_callback_start + __traceiter_dwc3_ep_queue + __traceiter_gpu_mem_total __traceiter_hrtimer_expire_entry __traceiter_hrtimer_expire_exit __traceiter_ipi_entry @@ -1399,11 +1959,17 @@ __traceiter_suspend_resume __traceiter_workqueue_execute_end __traceiter_workqueue_execute_start + trace_output_call __tracepoint_android_rvh_can_migrate_task __tracepoint_android_rvh_cpu_cgroup_can_attach __tracepoint_android_rvh_dequeue_task __tracepoint_android_rvh_enqueue_task __tracepoint_android_rvh_find_lowest_rq + __tracepoint_android_rvh_find_new_ilb + __tracepoint_android_rvh_gic_v3_set_affinity + __tracepoint_android_rvh_post_init_entity_util_avg + __tracepoint_android_rvh_replace_next_task_fair + __tracepoint_android_rvh_sched_fork_init __tracepoint_android_rvh_sched_newidle_balance __tracepoint_android_rvh_sched_nohz_balancer_kick __tracepoint_android_rvh_sched_rebalance_domains @@ -1412,12 +1978,16 @@ __tracepoint_android_rvh_select_task_rq_rt __tracepoint_android_vh_cpu_idle_enter __tracepoint_android_vh_cpu_idle_exit - __tracepoint_android_rvh_gic_v3_set_affinity __tracepoint_android_vh_ipi_stop __tracepoint_android_vh_scheduler_tick + __tracepoint_android_vh_show_mem + __tracepoint_android_vh_ufs_compl_command + __tracepoint_android_vh_ufs_prepare_command __tracepoint_cpu_idle __tracepoint_device_pm_callback_end __tracepoint_device_pm_callback_start + __tracepoint_dwc3_ep_queue + __tracepoint_gpu_mem_total __tracepoint_hrtimer_expire_entry __tracepoint_hrtimer_expire_exit __tracepoint_ipi_entry @@ -1441,6 +2011,8 @@ __tracepoint_workqueue_execute_end __tracepoint_workqueue_execute_start trace_print_array_seq + trace_print_flags_seq + trace_print_symbols_seq trace_raw_output_prep trace_seq_printf try_module_get @@ -1488,6 +2060,7 @@ tty_insert_flip_string_fixed_flag tty_kref_put tty_port_tty_get + typec_get_drvdata typec_register_partner typec_register_port typec_set_data_role @@ -1508,18 +2081,34 @@ uart_unregister_driver uart_update_timeout uart_write_wakeup + uclamp_eff_value __udelay ufshcd_auto_hibern8_update + ufshcd_dme_get_attr + ufshcd_hold ufshcd_pltfrm_init + ufshcd_query_flag_retry + ufshcd_release ufshcd_remove ufshcd_shutdown ufshcd_system_resume ufshcd_system_suspend + unlock_page + unmap_mapping_range + unpin_user_page + unregister_blkdev __unregister_chrdev unregister_chrdev_region + unregister_inet6addr_notifier + unregister_inetaddr_notifier unregister_netdev + unregister_netdevice_notifier + unregister_netdevice_queue + unregister_oom_notifier + unregister_pernet_device unregister_pm_notifier unregister_reboot_notifier + unregister_shrinker up update_devfreq up_read @@ -1531,7 +2120,10 @@ __usb_create_hcd usb_disabled usb_enable_autosuspend + usb_ep_alloc_request usb_ep_autoconfig + usb_ep_free_request + usb_ep_queue usb_function_register usb_function_unregister usb_gadget_set_state @@ -1549,6 +2141,7 @@ usb_unregister_notify __usecs_to_jiffies usleep_range + v4l2_ctrl_auto_cluster v4l2_ctrl_handler_free v4l2_ctrl_handler_init_class v4l2_ctrl_handler_setup @@ -1556,12 +2149,22 @@ v4l2_ctrl_new_custom v4l2_ctrl_new_std v4l2_ctrl_new_std_menu + v4l2_ctrl_poll + v4l2_ctrl_subscribe_event v4l2_device_register + v4l2_device_register_subdev + v4l2_device_set_name v4l2_device_unregister + v4l2_device_unregister_subdev + v4l2_event_unsubscribe v4l2_fh_add v4l2_fh_del v4l2_fh_exit v4l2_fh_init + v4l2_fh_is_singular + v4l2_fh_open + v4l2_fh_release + v4l2_i2c_subdev_init v4l2_m2m_buf_queue v4l2_m2m_buf_remove v4l2_m2m_ctx_init @@ -1582,11 +2185,16 @@ v4l2_m2m_next_buf v4l2_m2m_poll v4l2_m2m_qbuf + v4l2_m2m_querybuf v4l2_m2m_release v4l2_m2m_reqbufs v4l2_m2m_streamoff v4l2_m2m_streamon v4l2_m2m_try_schedule + v4l2_match_dv_timings + v4l2_spi_subdev_init + v4l2_subdev_call_wrappers + v4l2_subdev_init v4l_bound_align_image vabits_actual vb2_buffer_done @@ -1600,6 +2208,7 @@ vb2_plane_cookie vb2_plane_vaddr vb2_poll + vb2_prepare_buf vb2_qbuf vb2_querybuf vb2_queue_init @@ -1608,21 +2217,34 @@ vb2_streamoff vb2_streamon vb2_wait_for_all_buffers + verify_pkcs7_signature vfree + vfs_fsync + vfs_getattr + vfs_llseek video_devdata video_device_alloc video_device_release + video_device_release_empty video_ioctl2 __video_register_device video_unregister_device vmalloc vmalloc_to_page + vmalloc_to_pfn + vmalloc_user vmap + vmf_insert_pfn_prot + vm_get_page_prot + vm_insert_page + vm_iomap_memory vm_map_pages vm_map_ram vm_unmap_ram + vprintk_emit vscnprintf vsnprintf + vsprintf vunmap vzalloc wait_for_completion @@ -1630,23 +2252,30 @@ wait_for_completion_interruptible_timeout wait_for_completion_killable wait_for_completion_timeout + __wait_on_buffer __wake_up __wake_up_locked + __wake_up_locked_key wake_up_process wakeup_source_add + wakeup_source_destroy wakeup_source_register wakeup_source_unregister + __wake_up_sync __warn_printk watchdog_init_timeout watchdog_register_device watchdog_set_restart_priority watchdog_unregister_device + wireless_nlevent_flush work_busy ww_mutex_lock ww_mutex_lock_interruptible ww_mutex_unlock xhci_add_endpoint xhci_address_device + xhci_bus_resume + xhci_bus_suspend xhci_check_trb_in_td_math xhci_gen_setup xhci_get_endpoint_index diff --git a/android/abi_gki_aarch64_exynosauto b/android/abi_gki_aarch64_exynosauto new file mode 100644 index 000000000000..dc913dc0e1d2 --- /dev/null +++ b/android/abi_gki_aarch64_exynosauto @@ -0,0 +1,1499 @@ +[abi_symbol_list] +# commonly used symbols + add_wait_queue + alloc_chrdev_region + __alloc_pages_nodemask + __alloc_percpu + alloc_workqueue + __arch_copy_from_user + __arch_copy_to_user + arm64_const_caps_ready + arm64_use_ng_mappings + __arm_smccc_smc + atomic_notifier_call_chain + atomic_notifier_chain_register + atomic_notifier_chain_unregister + __bitmap_and + blocking_notifier_call_chain + blocking_notifier_chain_register + blocking_notifier_chain_unregister + bpf_trace_run2 + bpf_trace_run4 + cancel_delayed_work + cancel_delayed_work_sync + cancel_work_sync + capable + cdev_add + cdev_del + cdev_init + __cfi_slowpath + __check_object_size + __class_create + class_destroy + clk_disable + clk_enable + clk_get + clk_get_rate + __clk_is_enabled + clk_prepare + clk_put + clk_register + clk_set_rate + clk_unprepare + clk_unregister + cma_alloc + cma_release + complete + complete_all + complete_and_exit + __const_udelay + cpu_bit_bitmap + cpu_hwcap_keys + cpu_hwcaps + cpumask_next + cpu_number + __cpu_online_mask + cpu_pm_register_notifier + __cpu_possible_mask + crc32_le + __crypto_memneq + debugfs_create_dir + debugfs_create_file + debugfs_create_u32 + debugfs_remove + default_llseek + delayed_work_timer_fn + del_timer + del_timer_sync + destroy_workqueue + _dev_crit + dev_driver_string + _dev_emerg + _dev_err + device_create + device_create_file + device_destroy + device_initialize + device_init_wakeup + device_remove_file + _dev_info + devm_clk_get + devm_free_irq + devm_gpiod_get_optional + devm_gpio_request_one + devm_i2c_new_dummy_device + devm_ioremap + devm_ioremap_resource + devm_kasprintf + devm_kfree + devm_kmalloc + devm_kmemdup + __devm_of_phy_provider_register + devm_phy_create + devm_phy_get + devm_pinctrl_get + devm_platform_ioremap_resource + __devm_regmap_init_i2c + devm_regulator_bulk_get + __devm_request_region + devm_request_threaded_irq + devm_rtc_device_register + devm_snd_soc_register_card + devm_snd_soc_register_component + _dev_notice + devres_add + devres_alloc_node + dev_set_name + _dev_warn + disable_irq + disable_irq_nosync + display_timings_release + dma_alloc_attrs + dma_buf_attach + dma_buf_begin_cpu_access + dma_buf_detach + dma_buf_end_cpu_access + dma_buf_export + dma_buf_fd + dma_buf_get + dma_buf_map_attachment + dma_buf_mmap + dma_buf_put + dma_buf_unmap_attachment + dma_buf_vmap + dma_buf_vunmap + dmaengine_unmap_put + dma_fence_add_callback + dma_fence_context_alloc + dma_fence_default_wait + dma_fence_init + dma_fence_release + dma_fence_remove_callback + dma_fence_signal + dma_free_attrs + dma_heap_buffer_alloc + dma_heap_find + dma_heap_get_drvdata + dma_heap_put + dma_map_page_attrs + dma_map_sg_attrs + dma_release_channel + dma_request_chan + dma_set_coherent_mask + dma_set_mask + dma_sync_sg_for_cpu + dma_sync_sg_for_device + dma_sync_single_for_cpu + dma_sync_single_for_device + dma_unmap_page_attrs + dma_unmap_sg_attrs + down_interruptible + down_read + drm_add_edid_modes + drm_atomic_helper_connector_destroy_state + drm_atomic_helper_connector_duplicate_state + drm_atomic_helper_connector_reset + drm_bridge_add + drm_bridge_remove + drm_connector_attach_encoder + drm_connector_cleanup + drm_connector_init + drm_connector_register + drm_connector_update_edid_property + drm_display_mode_from_videomode + __drm_err + drm_helper_probe_single_connector_modes + drm_kms_helper_hotplug_event + drm_mode_copy + drm_mode_create + drm_mode_probed_add + drm_mode_vrefresh + dump_stack + enable_irq + event_triggers_call + fd_install + find_next_bit + find_vma + finish_wait + flush_delayed_work + flush_work + flush_workqueue + fput + frame_vector_to_pages + free_irq + __free_pages + free_pages + free_percpu + freezing_slow_path + generic_file_llseek + generic_handle_irq + gen_pool_add_owner + gen_pool_alloc_algo_owner + gen_pool_free_owner + get_device + __get_free_pages + get_random_bytes + get_task_mm + get_unused_fd_flags + gic_nonsecure_priorities + gpiod_direction_input + gpiod_direction_output_raw + gpiod_get_raw_value + gpiod_set_raw_value + gpiod_set_value_cansleep + gpiod_to_irq + gpio_free + gpio_request + gpio_request_one + gpio_to_desc + handle_edge_irq + handle_level_irq + handle_nested_irq + hrtimer_cancel + hrtimer_forward + hrtimer_init + hrtimer_start_range_ns + i2c_add_numbered_adapter + i2c_del_driver + i2c_register_driver + i2c_transfer + i2c_unregister_device + idr_remove + __init_rwsem + __init_swait_queue_head + init_timer_key + init_wait_entry + __init_waitqueue_head + iomem_resource + iommu_get_domain_for_dev + iommu_register_device_fault_handler + iommu_unregister_device_fault_handler + __ioremap + iounmap + __irq_alloc_descs + __irq_domain_add + irq_domain_remove + irq_find_mapping + irq_get_irq_data + irq_modify_status + irq_of_parse_and_map + irq_set_affinity_hint + irq_set_chip_and_handler_name + irq_set_chip_data + irq_set_irq_wake + irq_to_desc + is_vmalloc_addr + jiffies + jiffies_to_msecs + kasan_flag_enabled + kasprintf + kfree + kimage_voffset + __kmalloc + kmalloc_caches + kmalloc_order_trace + kmem_cache_alloc + kmem_cache_alloc_trace + kmem_cache_create + kmem_cache_destroy + kmem_cache_free + kmemdup + kobject_create_and_add + kobject_get + kobject_init_and_add + kobject_put + krealloc + kset_unregister + kstrdup + kstrtobool + kstrtoint + kstrtou8 + kstrtouint + kstrtoull + kthread_create_on_node + __kthread_init_worker + kthread_queue_work + kthread_stop + kthread_worker_fn + ktime_get + ktime_get_mono_fast_ns + ktime_get_raw_ts64 + ktime_get_real_ts64 + ktime_get_ts64 + kvfree + kvmalloc_node + __list_add_valid + __list_del_entry_valid + __log_post_read_mmio + __log_read_mmio + __log_write_mmio + loops_per_jiffy + memcpy + memdup_user + memset + memstart_addr + mfd_add_devices + mfd_remove_devices + mipi_dsi_attach + mipi_dsi_detach + mipi_dsi_device_register_full + mipi_dsi_device_unregister + mipi_dsi_driver_register_full + mipi_dsi_driver_unregister + misc_deregister + misc_register + mmput + mod_timer + module_layout + __msecs_to_jiffies + msleep + __mutex_init + mutex_lock + mutex_lock_interruptible + mutex_unlock + no_llseek + nonseekable_open + noop_llseek + nr_cpu_ids + ns_to_timespec64 + __num_online_cpus + of_address_to_resource + of_alias_get_id + of_clk_add_provider + of_clk_del_provider + of_clk_get + of_count_phandle_with_args + of_device_get_match_data + of_device_is_available + of_device_is_compatible + of_find_compatible_node + of_find_device_by_node + of_find_matching_node_and_match + of_find_mipi_dsi_host_by_node + of_find_node_by_name + of_find_node_opts_by_path + of_find_property + of_get_child_by_name + of_get_display_timings + of_get_named_gpio_flags + of_get_next_child + of_get_property + of_get_regulator_init_data + of_graph_get_remote_node + of_iomap + of_match_device + of_match_node + of_parse_phandle + of_platform_populate + of_property_count_elems_of_size + of_property_read_string + of_property_read_string_helper + of_property_read_u32_index + of_property_read_variable_u16_array + of_property_read_variable_u32_array + of_property_read_variable_u8_array + of_prop_next_string + of_reserved_mem_device_init_by_idx + of_reserved_mem_lookup + of_root + panic + panic_notifier_list + param_ops_bool + param_ops_int + param_ops_string + param_ops_uint + PDE_DATA + __per_cpu_offset + perf_trace_buf_alloc + perf_trace_run_bpf_submit + phy_power_off + phy_power_on + pinctrl_lookup_state + pinctrl_select_state + platform_bus_type + platform_device_register_full + platform_device_unregister + __platform_driver_probe + __platform_driver_register + platform_driver_unregister + platform_get_irq + platform_get_resource + platform_get_resource_byname + pm_power_off + __pm_runtime_disable + pm_runtime_enable + __pm_runtime_idle + __pm_runtime_resume + pm_runtime_set_autosuspend_delay + __pm_runtime_suspend + __pm_runtime_use_autosuspend + pm_wakeup_dev_event + pm_wakeup_ws_event + preempt_schedule + preempt_schedule_notrace + prepare_to_wait_event + print_hex_dump + printk + proc_create_data + put_device + __put_task_struct + put_unused_fd + queue_delayed_work_on + queue_work_on + radix_tree_delete + radix_tree_insert + radix_tree_lookup + radix_tree_next_chunk + ___ratelimit + _raw_spin_lock + _raw_spin_lock_irq + _raw_spin_lock_irqsave + _raw_spin_unlock + _raw_spin_unlock_irq + _raw_spin_unlock_irqrestore + __rcu_read_lock + __rcu_read_unlock + rdev_get_drvdata + rdev_get_id + refcount_dec_and_mutex_lock + refcount_warn_saturate + __refrigerator + regcache_mark_dirty + regcache_sync + __register_chrdev + register_pm_notifier + register_reboot_notifier + register_restart_handler + register_syscore_ops + regmap_read + regmap_update_bits_base + regmap_write + regulator_bulk_disable + regulator_bulk_enable + regulator_disable + regulator_enable + regulator_get_optional + regulator_list_voltage_linear + regulator_map_voltage_linear + regulator_put + regulator_register + regulator_unregister + release_firmware + __release_region + remove_proc_entry + request_firmware + __request_region + request_threaded_irq + sched_clock + schedule + schedule_timeout + scnprintf + seq_lseek + seq_printf + seq_putc + seq_puts + seq_read + seq_release + set_cpus_allowed_ptr + set_page_dirty_lock + sg_alloc_table + sg_alloc_table_from_pages + sg_free_table + sg_init_table + sg_next + __sg_page_iter_next + __sg_page_iter_start + simple_attr_open + simple_attr_read + simple_attr_release + simple_attr_write + simple_open + simple_read_from_buffer + simple_strtoul + simple_write_to_buffer + single_open + single_release + smp_call_function + snd_pcm_format_width + snd_soc_component_update_bits + snd_soc_component_write + snd_soc_dai_set_fmt + snd_soc_dai_set_tdm_slot + snd_soc_dai_set_tristate + snd_soc_info_volsw + snd_soc_of_get_dai_link_codecs + snd_soc_of_get_dai_name + snd_soc_of_parse_audio_routing + snd_soc_of_put_dai_link_codecs + snd_soc_pm_ops + snprintf + sort + split_page + sprintf + sscanf + __stack_chk_fail + __stack_chk_guard + strcasecmp + strcmp + strcpy + strcspn + strlcat + strlcpy + strlen + strncmp + strncpy + strnlen + strstr + __sw_hweight64 + sync_file_create + sync_file_get_fence + synchronize_irq + syscon_regmap_lookup_by_phandle + sysfs_create_file_ns + sysfs_create_group + sysfs_create_groups + sysfs_remove_file_ns + sysfs_remove_group + system_freezing_cnt + system_wq + tasklet_kill + __tasklet_schedule + _totalram_pages + trace_event_buffer_commit + trace_event_buffer_reserve + trace_event_ignore_this_pid + trace_event_raw_init + trace_event_reg + trace_handle_return + __traceiter_rwmmio_post_read + __traceiter_rwmmio_read + __traceiter_rwmmio_write + tracepoint_probe_register + __tracepoint_rwmmio_post_read + __tracepoint_rwmmio_read + __tracepoint_rwmmio_write + trace_raw_output_prep + trace_seq_printf + __udelay + __unregister_chrdev + unregister_chrdev_region + unregister_pm_notifier + unregister_reboot_notifier + up + up_read + __usecs_to_jiffies + usleep_range + v4l2_device_register + v4l2_device_unregister + v4l2_fh_add + v4l2_fh_del + v4l2_fh_exit + v4l2_fh_init + v4l2_subdev_init + vabits_actual + vb2_buffer_done + vb2_dqbuf + vb2_mmap + vb2_plane_cookie + vb2_plane_vaddr + vb2_poll + vb2_qbuf + vb2_querybuf + vb2_queue_init + vb2_queue_release + vb2_reqbufs + vb2_streamoff + vb2_streamon + vfree + video_devdata + video_device_alloc + video_device_release + video_ioctl2 + videomode_from_timings + __video_register_device + video_unregister_device + vmalloc + vmalloc_to_page + vmap + vsnprintf + vunmap + vzalloc + wait_for_completion + wait_for_completion_interruptible_timeout + wait_for_completion_timeout + __wake_up + wake_up_process + wakeup_source_register + wakeup_source_unregister + __warn_printk + work_busy + +# required by adv7511.ko + cec_s_phys_addr + cec_s_phys_addr_from_edid + cec_unregister_adapter + drm_bridge_hpd_notify + drm_detect_hdmi_monitor + drm_do_get_edid + hdmi_avi_infoframe_init + hdmi_avi_infoframe_pack + i2c_new_ancillary_device + regmap_bulk_write + regmap_register_patch + +# required by bts-exynos.ko + strpbrk + +# required by bufq.ko + kstrndup + +# required by clk_exynos.ko + __clk_get_hw + clk_hw_get_parent + clk_register_clkdev + clk_register_fixed_factor + clk_register_fixed_rate + of_clk_src_onecell_get + +# required by cmupmucal.ko + debugfs_create_x32 + kernel_kobj + +# required by dmatest.ko + dmaengine_get_unmap_data + __dma_request_channel + dma_sync_wait + kthread_should_stop + param_get_bool + param_get_string + param_set_bool + param_set_copystring + prandom_bytes + set_freezable + set_user_nice + strim + +# required by dss.ko + android_debug_symbol + arch_timer_read_counter + dump_backtrace + init_task + input_close_device + input_open_device + input_register_handle + input_register_handler + input_unregister_handle + kmsg_dump_get_line + kmsg_dump_rewind + kstat + nr_irqs + proc_create + register_die_notifier + return_address + rtc_time64_to_tm + sys_tz + time64_to_tm + __traceiter_android_vh_ipi_stop + __traceiter_android_vh_logbuf + __traceiter_cpu_idle + __traceiter_device_pm_callback_end + __traceiter_device_pm_callback_start + __traceiter_hrtimer_expire_entry + __traceiter_hrtimer_expire_exit + __traceiter_irq_handler_entry + __traceiter_irq_handler_exit + __traceiter_sched_switch + __traceiter_suspend_resume + __traceiter_workqueue_execute_end + __traceiter_workqueue_execute_start + __tracepoint_android_vh_ipi_stop + __tracepoint_android_vh_logbuf + __tracepoint_cpu_idle + __tracepoint_device_pm_callback_end + __tracepoint_device_pm_callback_start + __tracepoint_hrtimer_expire_entry + __tracepoint_hrtimer_expire_exit + __tracepoint_irq_handler_entry + __tracepoint_irq_handler_exit + __tracepoint_sched_switch + __tracepoint_suspend_resume + __tracepoint_workqueue_execute_end + __tracepoint_workqueue_execute_start + +# required by dwc3-exynosauto-usb.ko + device_for_each_child + device_property_present + devm_regulator_get + phy_exit + phy_init + platform_device_add + platform_device_add_properties + platform_device_add_resources + platform_device_alloc + platform_device_del + platform_device_put + platform_get_irq_byname_optional + __pm_relax + pm_runtime_allow + pm_runtime_forbid + __pm_runtime_set_status + __pm_stay_awake + __traceiter_dwc3_readl + __traceiter_dwc3_writel + __tracepoint_dwc3_readl + __tracepoint_dwc3_writel + usb_gadget_set_state + usb_otg_state_string + +# required by exynos-chipid_v2.ko + soc_device_register + subsys_system_register + +# required by exynos-coresight.ko + __cpuhp_setup_state_cpuslocked + cpu_pm_unregister_notifier + of_prop_next_u32 + +# required by exynos-debug-test.ko + _ctype + kstrtoll + remove_cpu + smp_call_function_single + strsep + +# required by exynos-ehld.ko + sprint_symbol + +# required by exynos-pd.ko + of_genpd_add_provider_simple + pm_genpd_add_subdomain + pm_genpd_init + +# required by exynos9drm.ko + bus_find_device + component_add + component_bind_all + component_del + component_master_add_with_match + component_master_del + component_unbind_all + console_trylock + console_unlock + debugfs_lookup + device_rename + drm_atomic_bridge_chain_enable + drm_atomic_bridge_chain_pre_enable + drm_atomic_helper_check + drm_atomic_helper_cleanup_planes + drm_atomic_helper_commit + drm_atomic_helper_commit_modeset_disables + drm_atomic_helper_commit_planes + drm_atomic_helper_crtc_destroy_state + drm_atomic_helper_crtc_duplicate_state + drm_atomic_helper_crtc_reset + drm_atomic_helper_disable_plane + drm_atomic_helper_disable_planes_on_crtc + drm_atomic_helper_fake_vblank + drm_atomic_helper_page_flip + __drm_atomic_helper_plane_destroy_state + __drm_atomic_helper_plane_duplicate_state + __drm_atomic_helper_plane_reset + __drm_atomic_helper_private_obj_duplicate_state + drm_atomic_helper_set_config + drm_atomic_helper_shutdown + drm_atomic_helper_update_plane + drm_atomic_helper_wait_for_vblanks + drm_atomic_normalize_zpos + drm_atomic_private_obj_init + drm_bridge_attach + drm_compat_ioctl + drm_connector_list_iter_begin + drm_connector_list_iter_end + drm_connector_list_iter_next + drm_connector_set_path_property + drm_connector_set_tile_property + drm_connector_unregister + drm_crtc_arm_vblank_event + drm_crtc_cleanup + __drm_crtc_commit_free + drm_crtc_handle_vblank + drm_crtc_init_with_planes + drm_crtc_send_vblank_event + drm_crtc_vblank_count + drm_crtc_vblank_get + drm_crtc_vblank_off + drm_crtc_vblank_on + drm_crtc_vblank_put + drm_crtc_vblank_waitqueue + __drm_dbg + drm_debugfs_create_files + drm_dev_alloc + drm_dev_dbg + drm_dev_printk + drm_dev_put + drm_dev_register + drm_dev_unregister + drm_display_mode_to_videomode + drm_dp_aux_register + drm_dp_aux_unregister + drm_dp_bw_code_to_link_rate + drm_dp_calc_pbn_mode + drm_dp_channel_eq_ok + drm_dp_check_act_status + drm_dp_clock_recovery_ok + drm_dp_downstream_debug + drm_dp_dpcd_read + drm_dp_dpcd_read_link_status + drm_dp_dpcd_write + drm_dp_dsc_sink_line_buf_depth + drm_dp_dsc_sink_max_slice_count + drm_dp_find_vcpi_slots + drm_dp_get_adjust_request_pre_emphasis + drm_dp_get_adjust_request_voltage + drm_dp_link_train_channel_eq_delay + drm_dp_link_train_clock_recovery_delay + drm_dp_mst_allocate_vcpi + drm_dp_mst_deallocate_vcpi + drm_dp_mst_detect_port + drm_dp_mst_dump_topology + drm_dp_mst_get_port_malloc + drm_dp_mst_hpd_irq + drm_dp_mst_put_port_malloc + drm_dp_mst_reset_vcpi_slots + drm_dp_mst_topology_mgr_init + drm_dp_mst_topology_mgr_set_mst + drm_dp_update_payload_part1 + drm_dp_update_payload_part2 + drm_dsc_compute_rc_parameters + drm_dsc_pps_payload_pack + drm_encoder_cleanup + drm_encoder_init + drm_flip_work_cleanup + drm_flip_work_commit + drm_flip_work_init + drm_flip_work_queue + drm_framebuffer_cleanup + drm_framebuffer_init + drm_gem_create_mmap_offset + drm_gem_handle_create + drm_gem_mmap + drm_gem_object_free + drm_gem_object_lookup + drm_gem_object_release + drm_gem_prime_fd_to_handle + drm_gem_prime_handle_to_fd + drm_gem_private_object_init + drm_gem_vm_close + drm_gem_vm_open + drm_get_connector_status_name + drm_get_edid + drm_get_format_info + drm_helper_connector_dpms + drm_helper_hpd_irq_event + drm_helper_mode_fill_fb_struct + drm_helper_probe_detect + drm_ioctl + drm_kms_helper_poll_fini + drm_kms_helper_poll_init + drmm_mode_config_init + drm_mode_config_cleanup + drm_mode_config_helper_resume + drm_mode_config_helper_suspend + drm_mode_config_reset + drm_mode_object_get + drm_mode_object_put + drm_of_component_match_add + drm_of_crtc_port_mask + drm_of_find_possible_crtcs + drm_open + drm_panel_disable + drm_panel_enable + drm_panel_get_modes + drm_panel_prepare + drm_panel_unprepare + drm_plane_cleanup + drm_plane_create_alpha_property + drm_plane_create_blend_mode_property + drm_plane_create_zpos_immutable_property + drm_plane_create_zpos_property + drm_poll + drm_prime_gem_destroy + drm_read + drm_release + drm_universal_plane_init + drm_vblank_init + mipi_dsi_host_register + mipi_dsi_host_unregister + mutex_is_locked + of_drm_find_bridge + of_drm_find_panel + of_graph_get_endpoint_by_regs + of_graph_get_endpoint_count + of_graph_get_next_endpoint + of_graph_get_port_by_id + of_graph_get_remote_port + of_graph_get_remote_port_parent + of_graph_parse_endpoint + of_phandle_iterator_init + of_phandle_iterator_next + seq_hex_dump + +# required by exynos_mfc.ko + iommu_dma_reserve_iova + iommu_map_sg + iommu_unmap + +# required by exynos_pm_qos.ko + kstrtoint_from_user + _raw_read_lock_irqsave + _raw_read_unlock_irqrestore + _raw_write_lock_irqsave + _raw_write_unlock_irqrestore + +# required by exynos_thermal.ko + of_thermal_get_ntrips + of_thermal_is_trip_valid + thermal_zone_device_update + thermal_zone_of_sensor_register + thermal_zone_of_sensor_unregister + +# required by exynos_tty.ko + dma_get_slave_caps + do_SAK + handle_sysrq + register_console + sysrq_mask + tty_flip_buffer_push + tty_insert_flip_string_fixed_flag + tty_kref_put + tty_port_tty_get + uart_add_one_port + uart_console_write + uart_get_baud_rate + uart_parse_options + uart_register_driver + uart_remove_one_port + uart_resume_port + uart_set_options + uart_suspend_port + uart_try_toggle_sysrq + uart_unregister_driver + uart_update_timeout + uart_write_wakeup + +# required by g2d.ko + add_timer + device_get_dma_attr + dma_fence_signal_locked + frame_vector_create + frame_vector_destroy + get_vaddr_frames + mod_delayed_work_on + put_vaddr_frames + +# required by hardlockup-watchdog.ko + __cpuhp_setup_state + cpus_read_lock + cpus_read_unlock + smp_call_on_cpu + +# required by i2c-exynosauto.ko + i2c_del_adapter + +# required by mali_kbase.ko + anon_inode_getfd + __arch_clear_user + __bitmap_weight + bpf_trace_run1 + bpf_trace_run3 + bpf_trace_run5 + cache_line_size + clear_page + __close_fd + debugfs_create_bool + dev_pm_opp_of_add_table + dev_pm_opp_of_remove_table + dev_pm_opp_put_regulators + dev_pm_opp_set_regulators + dma_fence_get_status + down + downgrade_write + down_trylock + down_write + failure_tracking + __get_task_comm + get_user_pages + get_user_pages_fast + get_user_pages_remote + hrtimer_active + kstrtobool_from_user + ktime_get_raw + kvfree_call_rcu + __mmdrop + module_put + of_machine_is_compatible + __page_pinner_migration_failed + param_array_ops + param_ops_byte + __put_page + rb_erase + rb_first + rb_insert_color + rb_next + rb_prev + rb_replace_node + register_shrinker + remap_pfn_range + remap_vmalloc_range + seq_open + seq_write + static_key_slow_dec + static_key_slow_inc + strncasecmp + __sw_hweight32 + synchronize_rcu + sysfs_streq + __traceiter_gpu_mem_total + trace_output_call + __tracepoint_gpu_mem_total + trace_print_array_seq + trace_print_flags_seq + trace_print_symbols_seq + try_module_get + unmap_mapping_range + unregister_shrinker + up_write + vmalloc_user + vmf_insert_pfn_prot + +# required by mcDrvModule.ko + crypto_alloc_shash + crypto_destroy_tfm + crypto_shash_final + crypto_shash_update + d_path + get_task_exe_file + get_zeroed_page + kstrtol_from_user + kstrtouint_from_user + pin_user_pages + release_pages + sg_miter_next + sg_miter_start + sg_miter_stop + unpin_user_page + wait_for_completion_interruptible + wait_for_completion_killable + +# required by panel-samsung-dummy.ko + drm_panel_add + drm_panel_init + drm_panel_remove + +# required by pcie-exynos-dw-ep.ko + dw_pcie_ep_init + dw_pcie_read_dbi + dw_pcie_write_dbi + pci_epc_clear_bar + pci_epc_map_addr + pci_epc_mem_alloc_addr + pci_epc_mem_free_addr + pci_epc_set_bar + pci_epc_unmap_addr + +# required by pcie-exynos-dw-rc.ko + bitmap_find_free_region + bitmap_release_region + dw_pcie_host_init + dw_pcie_msi_init + dw_pcie_own_conf_map_bus + dw_pcie_read + dw_pcie_setup_rc + dw_pcie_write + irq_chip_ack_parent + irq_chip_mask_parent + irq_chip_unmask_parent + irq_domain_get_irq_data + irq_domain_set_info + irq_domain_update_bus_token + pcie_get_mps + pcie_set_mps + pci_find_bus + pci_generic_config_read + pci_generic_config_write + pci_get_device + pci_load_saved_state + pci_msi_create_irq_domain + pci_msi_mask_irq + pci_msi_unmask_irq + pci_num_vf + pci_rescan_bus + pci_restore_state + pci_save_state + pci_store_saved_state + +# required by pcs-xpcs.ko + mdiobus_read + mdiobus_write + +# required by pinctrl-samsung-core.ko + devm_gpiochip_add_data_with_key + devm_pinctrl_register + gpiochip_generic_free + gpiochip_generic_request + gpiochip_get_data + gpiochip_lock_as_irq + gpiochip_unlock_as_irq + irq_create_mapping_affinity + irq_domain_xlate_twocell + irq_set_chained_handler_and_data + of_node_name_eq + pinctrl_add_gpio_range + pinctrl_dev_get_drvdata + pinctrl_remove_gpio_range + +# required by pl330.ko + amba_driver_register + amba_driver_unregister + dev_err_probe + __devm_reset_control_get + dma_async_device_register + dma_async_device_unregister + dma_async_tx_descriptor_init + dma_get_slave_channel + dma_map_resource + dma_unmap_resource + of_dma_controller_free + of_dma_controller_register + pm_runtime_force_resume + pm_runtime_force_suspend + pm_runtime_irq_safe + reset_control_assert + reset_control_deassert + tasklet_setup + +# required by pps_core.ko + fasync_helper + idr_alloc + idr_get_next + kill_fasync + +# required by ptp.ko + ida_alloc_range + ida_destroy + ida_free + kthread_cancel_delayed_work_sync + kthread_create_worker + kthread_delayed_work_timer_fn + kthread_destroy_worker + kthread_mod_delayed_work + kthread_queue_delayed_work + ktime_get_snapshot + posix_clock_register + posix_clock_unregister + +# required by reboot-mode.ko + devres_free + devres_release + kfree_const + kstrdup_const + +# required by rtc-s2vps01.ko + rtc_update_irq + rtc_valid_tm + +# required by s3c2410_wdt.ko + watchdog_init_timeout + watchdog_register_device + watchdog_set_restart_priority + watchdog_unregister_device + +# required by sam-is.ko + get_task_pid + i2c_get_adapter + i2c_new_client_device + kobject_del + kstrtou16 + kthread_flush_work + kthread_flush_worker + ktime_get_with_offset + phy_configure + pm_relax + pm_stay_awake + regulator_get_voltage + regulator_is_enabled + regulator_set_voltage + sched_set_fifo + tasklet_init + v4l2_device_register_subdev + v4l2_device_unregister_subdev + v4l2_subdev_call_wrappers + +# required by samsung-iommu-group.ko + iommu_group_alloc + iommu_group_set_name + +# required by samsung-secure-iova.ko + gen_pool_avail + gen_pool_create + gen_pool_destroy + gen_pool_first_fit_align + gen_pool_size + +# required by samsung-seqos.ko + alloc_etherdev_mqs + __bitmap_andnot + consume_skb + dev_close + device_get_phy_mode + device_set_wakeup_capable + device_set_wakeup_enable + __dev_kfree_skb_any + dev_open + dql_completed + dql_reset + eth_mac_addr + ethtool_op_get_link + ethtool_op_get_ts_info + eth_type_trans + free_netdev + in4_pton + in6_pton + jiffies_to_usecs + mdiobus_alloc_size + mdiobus_free + mdiobus_get_phy + __mdiobus_register + mdiobus_unregister + napi_complete_done + napi_disable + napi_gro_receive + __napi_schedule + __napi_schedule_irqoff + napi_schedule_prep + netdev_alert + __netdev_alloc_skb + netdev_err + netdev_info + netdev_update_features + netdev_warn + netif_carrier_off + netif_device_attach + netif_device_detach + netif_napi_add + __netif_napi_del + netif_schedule_queue + netif_set_real_num_rx_queues + netif_set_real_num_tx_queues + netif_tx_wake_queue + net_ratelimit + of_get_mac_address + of_mdiobus_register + of_phy_deregister_fixed_link + of_phy_is_fixed_link + of_phy_register_fixed_link + phy_attached_info + phy_disconnect + phy_ethtool_get_eee + phy_ethtool_ksettings_get + phy_ethtool_ksettings_set + phy_ethtool_nway_reset + phy_ethtool_set_eee + phy_get_eee_err + phy_init_eee + phylink_connect_phy + phylink_create + phylink_destroy + phylink_of_phy_connect + phylink_set_port_modes + phylink_start + phy_mac_interrupt + phy_mii_ioctl + phy_resume + phy_start_aneg + phy_stop + phy_suspend + pinctrl_pm_select_default_state + pinctrl_pm_select_sleep_state + platform_get_irq_byname + _raw_spin_lock_bh + _raw_spin_unlock_bh + register_netdev + rtnl_lock + rtnl_unlock + skb_pull + skb_put + skb_tstamp_tx + synchronize_net + unregister_netdev + +# required by samsung_dma_heap.ko + anon_inode_getfile + deferred_free + devm_add_action + devm_gen_pool_create + dmabuf_page_pool_alloc + dmabuf_page_pool_create + dmabuf_page_pool_destroy + dmabuf_page_pool_free + dma_heap_add + dma_heap_get_dev + dma_heap_get_name + is_dma_buf_file + iterate_fd + mutex_trylock + of_reserved_mem_device_release + __traceiter_android_vh_show_mem + __tracepoint_android_vh_show_mem + vm_insert_page + +# required by samsung_iommu.ko + bus_set_iommu + device_link_add + device_link_del + iommu_attach_group + iommu_device_register + iommu_device_sysfs_add + iommu_device_sysfs_remove + iommu_device_unlink + iommu_device_unregister + iommu_domain_alloc + iommu_fwspec_add_ids + iommu_fwspec_free + iommu_get_dma_cookie + iommu_group_for_each_dev + iommu_group_get + iommu_group_get_iommudata + iommu_group_remove_device + iommu_group_set_iommudata + iommu_put_dma_cookie + iommu_report_device_fault + of_get_dma_window + pfn_valid + +# required by scaler.ko + clk_set_parent + dma_heap_buffer_free + v4l2_ctrl_handler_free + v4l2_ctrl_handler_init_class + v4l2_ctrl_handler_setup + v4l2_ctrl_new_custom + v4l2_ctrl_new_std + v4l2_m2m_buf_queue + v4l2_m2m_buf_remove + v4l2_m2m_ctx_init + v4l2_m2m_ctx_release + v4l2_m2m_dqbuf + v4l2_m2m_get_curr_priv + v4l2_m2m_get_vq + v4l2_m2m_init + v4l2_m2m_job_finish + v4l2_m2m_mmap + v4l2_m2m_next_buf + v4l2_m2m_poll + v4l2_m2m_qbuf + v4l2_m2m_querybuf + v4l2_m2m_release + v4l2_m2m_reqbufs + v4l2_m2m_streamoff + v4l2_m2m_streamon + v4l2_m2m_try_schedule + v4l_bound_align_image + +# required by snd-soc-s3c-dma.ko + devm_snd_dmaengine_pcm_register + snd_dmaengine_pcm_prepare_slave_config + +# required by snd-soc-samsung-abox-core.ko + devm_iounmap + __devm_regmap_init + __devm_regmap_init_mmio_clk + dma_mmap_attrs + __platform_register_drivers + platform_unregister_drivers + pm_runtime_no_callbacks + snd_pcm_hw_constraint_integer + snd_pcm_lib_free_pages + snd_pcm_lib_ioctl + snd_pcm_lib_malloc_pages + snd_pcm_lib_preallocate_free_for_all + snd_pcm_lib_preallocate_pages + snd_pcm_period_elapsed + snd_pcm_release_substream + snd_soc_component_init_regmap + snd_soc_component_read + snd_soc_dapm_add_routes + snd_soc_dapm_get_enum_double + snd_soc_dapm_new_control + snd_soc_dapm_new_controls + snd_soc_dapm_put_enum_double + snd_soc_info_enum_double + snd_soc_set_runtime_hwparams + snd_soc_unregister_component + +# required by snd-soc-tas6424.ko + regcache_cache_only + snd_soc_get_volsw + snd_soc_put_volsw + +# required by spi-exynosauto.ko + __spi_alloc_controller + spi_controller_resume + spi_controller_suspend + spi_delay_exec + spi_finalize_current_message + spi_register_controller + spi_unregister_controller + +# required by spidev.ko + driver_unregister + find_next_zero_bit + __spi_register_driver + spi_setup + spi_sync + stream_open + +# required by syscon-reboot-mode.ko + syscon_node_to_regmap + +# required by ufs-exynosauto-core.ko + blk_ksm_init_passthrough + device_get_match_data + __traceiter_android_vh_ufs_fill_prdt + __tracepoint_android_vh_ufs_fill_prdt + ufshcd_config_pwr_mode + ufshcd_dme_get_attr + ufshcd_dme_set_attr + ufshcd_link_recovery + ufshcd_pltfrm_init + ufshcd_remove + ufshcd_shutdown + ufshcd_system_resume + ufshcd_system_suspend + +# required by vbufq-be-module.ko + drain_workqueue + +# required by vdriver-lib-module.ko + kset_create_and_add + +# required by vevdev-fe-module.ko + input_alloc_absinfo + input_allocate_device + input_event + input_free_device + input_mt_init_slots + input_register_device + input_unregister_device + +# required by videobuf2-dma-sg.ko + vb2_common_vm_ops + vb2_create_framevec + vb2_destroy_framevec + vm_map_pages + vm_map_ram + vm_unmap_ram + +# required by vlx-clk-ctrl-common-module.ko + vscnprintf + +# required by vlx-hyp-module.ko + ioremap_cache + irq_create_of_mapping + irq_dispose_mapping + irq_find_matching_fwspec + of_irq_find_parent + proc_mkdir + +# required by vlx-last-kmsg-module.ko + proc_set_size + +# required by vlx-prop-module.ko + kobject_uevent + sysfs_create_bin_file + sysfs_remove_bin_file + +# required by vlx-vdmaheap-module.ko + devm_get_free_pages + idr_alloc_cyclic + idr_find + radix_tree_iter_delete + uuid_gen + __vmalloc + +# required by vlx-vipc-module.ko + sigprocmask + +# required by vlx-vmq-module.ko + default_wake_function + remove_wait_queue + +# required by vrpc-module.ko + current_work + +# required by vvideo2-fe-module.ko + __task_pid_nr_ns + vprintk + +# preserved by --additions-only + system_highpri_wq diff --git a/android/abi_gki_aarch64_fips140 b/android/abi_gki_aarch64_fips140 index 05df3848ff15..cf48b6d66aa9 100644 --- a/android/abi_gki_aarch64_fips140 +++ b/android/abi_gki_aarch64_fips140 @@ -1,12 +1,17 @@ [abi_symbol_list] +# commonly used symbols + module_layout + __put_task_struct # required by fips140.ko add_random_ready_callback aead_register_instance + arm64_const_caps_ready bcmp cancel_work_sync __cfi_slowpath cpu_have_feature + cpu_hwcap_keys crypto_aead_decrypt crypto_aead_encrypt crypto_aead_setauthsize @@ -16,11 +21,14 @@ crypto_alg_list crypto_alg_mod_lookup crypto_alg_sem + crypto_alloc_aead crypto_alloc_base crypto_alloc_rng crypto_alloc_shash + crypto_alloc_skcipher crypto_attr_alg_name crypto_check_attr_type + crypto_cipher_decrypt_one crypto_cipher_encrypt_one crypto_cipher_setkey crypto_destroy_tfm @@ -43,6 +51,7 @@ crypto_remove_final crypto_remove_spawns crypto_req_done + crypto_rng_reset crypto_shash_alg_has_setkey crypto_shash_digest crypto_shash_final @@ -77,6 +86,7 @@ kmalloc_caches kmalloc_order_trace kmem_cache_alloc_trace + kmemdup __list_add_valid __list_del_entry_valid memcpy @@ -89,6 +99,7 @@ preempt_schedule_notrace printk queue_work_on + refcount_warn_saturate scatterwalk_ffwd scatterwalk_map_and_copy sg_init_one diff --git a/android/abi_gki_aarch64_galaxy b/android/abi_gki_aarch64_galaxy new file mode 100644 index 000000000000..a6d6c37a2f7a --- /dev/null +++ b/android/abi_gki_aarch64_galaxy @@ -0,0 +1,4492 @@ +[abi_symbol_list] +PDE_DATA +__ClearPageMovable +__SetPageMovable +___pskb_trim +___ratelimit +__alloc_disk_node +__alloc_pages_nodemask +__alloc_percpu +__alloc_percpu_gfp +__alloc_skb +__arch_clear_user +__arch_copy_from_user +__arch_copy_in_user +__arch_copy_to_user +__arm_smccc_hvc +__arm_smccc_smc +__bitmap_andnot +__bitmap_clear +__bitmap_complement +__bitmap_or +__bitmap_set +__bitmap_weight +__bitmap_xor +__blk_mq_debugfs_rq_show +__blk_mq_end_request +__blk_rq_map_sg +__blkdev_issue_discard +__blkdev_issue_zeroout +__cfi_slowpath +__check_object_size +__class_create +__class_register +__clk_determine_rate +__clk_get_hw +__clk_get_name +__clk_hw_register_divider +__clk_hw_register_gate +__clk_hw_register_mux +__clk_is_enabled +__clk_mux_determine_rate_closest +__clocksource_register_scale +__close_fd +__const_udelay +__cpu_active_mask +__cpu_online_mask +__cpu_possible_mask +__cpu_present_mask +__cpufreq_driver_target +__cpuhp_remove_state +__cpuhp_setup_state +__cpuhp_setup_state_cpuslocked +__cpuhp_state_add_instance +__cpuhp_state_remove_instance +__dev_get_by_index +__dev_kfree_skb_any +__devm_alloc_percpu +__devm_drm_dev_alloc +__devm_iio_device_register +__devm_irq_alloc_descs +__devm_of_phy_provider_register +__devm_regmap_init +__devm_regmap_init_i2c +__devm_regmap_init_mmio_clk +__devm_regmap_init_spi +__devm_release_region +__devm_request_region +__devm_reset_control_get +__devm_spi_alloc_controller +__dma_request_channel +__do_once_done +__do_once_start +__drm_atomic_helper_connector_destroy_state +__drm_atomic_helper_connector_duplicate_state +__drm_atomic_helper_connector_reset +__drm_atomic_helper_crtc_destroy_state +__drm_atomic_helper_crtc_duplicate_state +__drm_atomic_helper_crtc_reset +__drm_atomic_helper_plane_destroy_state +__drm_atomic_helper_plane_duplicate_state +__drm_atomic_helper_private_obj_duplicate_state +__drm_atomic_state_free +__drm_dbg +__drm_debug +__drm_err +__drm_printfn_coredump +__drm_printfn_info +__drm_printfn_seq_file +__drm_puts_coredump +__drm_puts_seq_file +__dynamic_dev_dbg +__dynamic_pr_debug +__ethtool_get_link_ksettings +__fdget +__flush_icache_range +__free_pages +__get_free_pages +__get_task_comm +__hrtimer_get_remaining +__hvc_resize +__hwspin_lock_timeout +__hwspin_unlock +__i2c_smbus_xfer +__i2c_transfer +__iio_device_register +__init_rwsem +__init_swait_queue_head +__init_waitqueue_head +__ioread32_copy +__ioremap +__iowrite32_copy +__ipv6_addr_type +__irq_alloc_descs +__irq_domain_add +__irq_set_handler +__kfifo_alloc +__kfifo_free +__kfifo_in +__kfifo_init +__kfifo_out +__kfifo_out_peek +__kfifo_to_user +__kfree_skb +__kmalloc +__kthread_init_worker +__list_add_valid +__list_del_entry_valid +__local_bh_enable_ip +__lock_page +__log_post_read_mmio +__log_read_mmio +__log_write_mmio +__mdiobus_register +__media_device_register +__memcat_p +__memcpy_fromio +__memcpy_toio +__memset_io +__mmc_claim_host +__mmc_send_status +__mmdrop +__module_get +__msecs_to_jiffies +__mutex_init +__napi_alloc_skb +__napi_schedule +__ndelay +__netdev_alloc_skb +__netif_napi_del +__netif_set_xps_queue +__netlink_kernel_create +__next_zones_zonelist +__nla_parse +__nla_validate +__nlmsg_put +__num_online_cpus +__of_reset_control_get +__pci_register_driver +__per_cpu_offset +__percpu_down_read +__percpu_init_rwsem +__platform_driver_probe +__platform_driver_register +__platform_register_drivers +__pm_relax +__pm_runtime_disable +__pm_runtime_idle +__pm_runtime_resume +__pm_runtime_set_status +__pm_runtime_suspend +__pm_runtime_use_autosuspend +__pm_stay_awake +__printk_ratelimit +__pskb_pull_tail +__put_page +__put_task_struct +__rb_erase_color +__rb_insert_augmented +__rcu_read_lock +__rcu_read_unlock +__refrigerator +__register_chrdev +__register_rpmsg_driver +__regmap_init +__release_region +__request_module +__request_percpu_irq +__request_region +__rht_bucket_nested +__rtc_register_device +__scsi_execute +__scsi_iterate_devices +__scsi_print_sense +__sdhci_add_host +__seq_open_private +__serio_register_driver +__serio_register_port +__sg_page_iter_dma_next +__sg_page_iter_next +__sg_page_iter_start +__skb_ext_put +__skb_flow_dissect +__skb_get_hash +__skb_gso_segment +__skb_pad +__spi_alloc_controller +__spi_register_driver +__splice_from_pipe +__spmi_driver_register +__srcu_read_lock +__srcu_read_unlock +__stack_chk_fail +__stack_chk_guard +__sw_hweight16 +__sw_hweight32 +__sw_hweight64 +__sw_hweight8 +__sysfs_match_string +__task_pid_nr_ns +__task_rq_lock +__tasklet_hi_schedule +__tasklet_schedule +__trace_bprintk +__trace_bputs +__trace_printk +__traceiter_android_rvh_account_irq +__traceiter_android_rvh_build_perf_domains +__traceiter_android_rvh_can_migrate_task +__traceiter_android_rvh_check_preempt_wakeup +__traceiter_android_rvh_cpu_cgroup_attach +__traceiter_android_rvh_cpu_cgroup_can_attach +__traceiter_android_rvh_cpu_cgroup_online +__traceiter_android_rvh_cpu_overutilized +__traceiter_android_rvh_cpufreq_transition +__traceiter_android_rvh_dequeue_task +__traceiter_android_rvh_die_kernel_fault +__traceiter_android_rvh_do_mem_abort +__traceiter_android_rvh_do_sp_pc_abort +__traceiter_android_rvh_enqueue_task +__traceiter_android_rvh_find_busiest_queue +__traceiter_android_rvh_find_energy_efficient_cpu +__traceiter_android_rvh_find_lowest_rq +__traceiter_android_rvh_flush_task +__traceiter_android_rvh_irqs_disable +__traceiter_android_rvh_irqs_enable +__traceiter_android_rvh_migrate_queued_task +__traceiter_android_rvh_new_task_stats +__traceiter_android_rvh_pick_next_entity +__traceiter_android_rvh_place_entity +__traceiter_android_rvh_preempt_disable +__traceiter_android_rvh_preempt_enable +__traceiter_android_rvh_replace_next_task_fair +__traceiter_android_rvh_report_bug +__traceiter_android_rvh_resume_cpus +__traceiter_android_rvh_sched_balance_rt +__traceiter_android_rvh_sched_cpu_dying +__traceiter_android_rvh_sched_cpu_starting +__traceiter_android_rvh_sched_exec +__traceiter_android_rvh_sched_fork +__traceiter_android_rvh_sched_fork_init +__traceiter_android_rvh_sched_newidle_balance +__traceiter_android_rvh_sched_nohz_balancer_kick +__traceiter_android_rvh_sched_rebalance_domains +__traceiter_android_rvh_schedule +__traceiter_android_rvh_schedule_bug +__traceiter_android_rvh_select_fallback_rq +__traceiter_android_rvh_select_task_rq_fair +__traceiter_android_rvh_select_task_rq_rt +__traceiter_android_rvh_set_gfp_zone_flags +__traceiter_android_rvh_set_iowait +__traceiter_android_rvh_set_readahead_gfp_mask +__traceiter_android_rvh_set_skip_swapcache_flags +__traceiter_android_rvh_set_task_cpu +__traceiter_android_rvh_tick_entry +__traceiter_android_rvh_try_to_wake_up +__traceiter_android_rvh_try_to_wake_up_success +__traceiter_android_rvh_ttwu_cond +__traceiter_android_rvh_typec_tcpci_chk_contaminant +__traceiter_android_rvh_typec_tcpci_get_vbus +__traceiter_android_rvh_uclamp_eff_get +__traceiter_android_rvh_update_cpu_capacity +__traceiter_android_rvh_update_cpus_allowed +__traceiter_android_rvh_update_misfit_status +__traceiter_android_rvh_util_est_update +__traceiter_android_rvh_wake_up_new_task +__traceiter_android_vh_allow_domain_state +__traceiter_android_vh_arch_set_freq_scale +__traceiter_android_vh_binder_restore_priority +__traceiter_android_vh_binder_set_priority +__traceiter_android_vh_binder_transaction_init +__traceiter_android_vh_binder_wakeup_ilocked +__traceiter_android_vh_cma_alloc_finish +__traceiter_android_vh_cma_alloc_start +__traceiter_android_vh_cpu_idle_enter +__traceiter_android_vh_cpu_idle_exit +__traceiter_android_vh_dump_throttled_rt_tasks +__traceiter_android_vh_enable_thermal_genl_check +__traceiter_android_vh_ep_create_wakeup_source +__traceiter_android_vh_freq_table_limits +__traceiter_android_vh_ftrace_dump_buffer +__traceiter_android_vh_ftrace_format_check +__traceiter_android_vh_ftrace_oops_enter +__traceiter_android_vh_ftrace_oops_exit +__traceiter_android_vh_ftrace_size_check +__traceiter_android_vh_iommu_setup_dma_ops +__traceiter_android_vh_ipi_stop +__traceiter_android_vh_is_fpsimd_save +__traceiter_android_vh_jiffies_update +__traceiter_android_vh_kfree_skb +__traceiter_android_vh_logbuf +__traceiter_android_vh_logbuf_pr_cont +__traceiter_android_vh_meminfo_proc_show +__traceiter_android_vh_pagecache_get_page +__traceiter_android_vh_printk_hotplug +__traceiter_android_vh_ptype_head +__traceiter_android_vh_rmqueue +__traceiter_android_vh_scheduler_tick +__traceiter_android_vh_show_max_freq +__traceiter_android_vh_show_mem +__traceiter_android_vh_show_resume_epoch_val +__traceiter_android_vh_show_suspend_epoch_val +__traceiter_android_vh_timer_calc_index +__traceiter_android_vh_timerfd_create +__traceiter_android_vh_typec_store_partner_src_caps +__traceiter_android_vh_typec_tcpci_override_toggling +__traceiter_android_vh_typec_tcpm_adj_current_limit +__traceiter_android_vh_typec_tcpm_get_timer +__traceiter_android_vh_ufs_check_int_errors +__traceiter_android_vh_ufs_compl_command +__traceiter_android_vh_ufs_fill_prdt +__traceiter_android_vh_ufs_prepare_command +__traceiter_android_vh_ufs_send_command +__traceiter_android_vh_ufs_send_tm_command +__traceiter_android_vh_ufs_send_uic_command +__traceiter_android_vh_ufs_update_sdev +__traceiter_android_vh_ufs_update_sysfs +__traceiter_clock_set_rate +__traceiter_cpu_frequency +__traceiter_dma_fence_emit +__traceiter_dwc3_readl +__traceiter_dwc3_writel +__traceiter_gpu_mem_total +__traceiter_sched_util_est_se_tp +__traceiter_xdp_exception +__tracepoint_android_rvh_account_irq +__tracepoint_android_rvh_build_perf_domains +__tracepoint_android_rvh_can_migrate_task +__tracepoint_android_rvh_check_preempt_wakeup +__tracepoint_android_rvh_cpu_cgroup_attach +__tracepoint_android_rvh_cpu_cgroup_can_attach +__tracepoint_android_rvh_cpu_cgroup_online +__tracepoint_android_rvh_cpu_overutilized +__tracepoint_android_rvh_cpufreq_transition +__tracepoint_android_rvh_dequeue_task +__tracepoint_android_rvh_die_kernel_fault +__tracepoint_android_rvh_do_mem_abort +__tracepoint_android_rvh_do_sp_pc_abort +__tracepoint_android_rvh_enqueue_task +__tracepoint_android_rvh_find_busiest_queue +__tracepoint_android_rvh_find_energy_efficient_cpu +__tracepoint_android_rvh_find_lowest_rq +__tracepoint_android_rvh_flush_task +__tracepoint_android_rvh_irqs_disable +__tracepoint_android_rvh_irqs_enable +__tracepoint_android_rvh_migrate_queued_task +__tracepoint_android_rvh_new_task_stats +__tracepoint_android_rvh_pick_next_entity +__tracepoint_android_rvh_place_entity +__tracepoint_android_rvh_preempt_disable +__tracepoint_android_rvh_preempt_enable +__tracepoint_android_rvh_replace_next_task_fair +__tracepoint_android_rvh_report_bug +__tracepoint_android_rvh_resume_cpus +__tracepoint_android_rvh_sched_balance_rt +__tracepoint_android_rvh_sched_cpu_dying +__tracepoint_android_rvh_sched_cpu_starting +__tracepoint_android_rvh_sched_exec +__tracepoint_android_rvh_sched_fork +__tracepoint_android_rvh_sched_fork_init +__tracepoint_android_rvh_sched_newidle_balance +__tracepoint_android_rvh_sched_nohz_balancer_kick +__tracepoint_android_rvh_sched_rebalance_domains +__tracepoint_android_rvh_schedule +__tracepoint_android_rvh_schedule_bug +__tracepoint_android_rvh_select_fallback_rq +__tracepoint_android_rvh_select_task_rq_fair +__tracepoint_android_rvh_select_task_rq_rt +__tracepoint_android_rvh_set_gfp_zone_flags +__tracepoint_android_rvh_set_iowait +__tracepoint_android_rvh_set_readahead_gfp_mask +__tracepoint_android_rvh_set_skip_swapcache_flags +__tracepoint_android_rvh_set_task_cpu +__tracepoint_android_rvh_tick_entry +__tracepoint_android_rvh_try_to_wake_up +__tracepoint_android_rvh_try_to_wake_up_success +__tracepoint_android_rvh_ttwu_cond +__tracepoint_android_rvh_typec_tcpci_chk_contaminant +__tracepoint_android_rvh_typec_tcpci_get_vbus +__tracepoint_android_rvh_uclamp_eff_get +__tracepoint_android_rvh_update_cpu_capacity +__tracepoint_android_rvh_update_cpus_allowed +__tracepoint_android_rvh_update_misfit_status +__tracepoint_android_rvh_util_est_update +__tracepoint_android_rvh_wake_up_new_task +__tracepoint_android_vh_allow_domain_state +__tracepoint_android_vh_arch_set_freq_scale +__tracepoint_android_vh_binder_restore_priority +__tracepoint_android_vh_binder_set_priority +__tracepoint_android_vh_binder_transaction_init +__tracepoint_android_vh_binder_wakeup_ilocked +__tracepoint_android_vh_cma_alloc_finish +__tracepoint_android_vh_cma_alloc_start +__tracepoint_android_vh_cpu_idle_enter +__tracepoint_android_vh_cpu_idle_exit +__tracepoint_android_vh_dump_throttled_rt_tasks +__tracepoint_android_vh_enable_thermal_genl_check +__tracepoint_android_vh_ep_create_wakeup_source +__tracepoint_android_vh_freq_table_limits +__tracepoint_android_vh_ftrace_dump_buffer +__tracepoint_android_vh_ftrace_format_check +__tracepoint_android_vh_ftrace_oops_enter +__tracepoint_android_vh_ftrace_oops_exit +__tracepoint_android_vh_ftrace_size_check +__tracepoint_android_vh_iommu_setup_dma_ops +__tracepoint_android_vh_ipi_stop +__tracepoint_android_vh_is_fpsimd_save +__tracepoint_android_vh_jiffies_update +__tracepoint_android_vh_kfree_skb +__tracepoint_android_vh_logbuf +__tracepoint_android_vh_logbuf_pr_cont +__tracepoint_android_vh_meminfo_proc_show +__tracepoint_android_vh_pagecache_get_page +__tracepoint_android_vh_printk_hotplug +__tracepoint_android_vh_ptype_head +__tracepoint_android_vh_rmqueue +__tracepoint_android_vh_scheduler_tick +__tracepoint_android_vh_show_max_freq +__tracepoint_android_vh_show_mem +__tracepoint_android_vh_show_resume_epoch_val +__tracepoint_android_vh_show_suspend_epoch_val +__tracepoint_android_vh_timer_calc_index +__tracepoint_android_vh_timerfd_create +__tracepoint_android_vh_typec_store_partner_src_caps +__tracepoint_android_vh_typec_tcpci_override_toggling +__tracepoint_android_vh_typec_tcpm_adj_current_limit +__tracepoint_android_vh_typec_tcpm_get_timer +__tracepoint_android_vh_ufs_check_int_errors +__tracepoint_android_vh_ufs_compl_command +__tracepoint_android_vh_ufs_fill_prdt +__tracepoint_android_vh_ufs_prepare_command +__tracepoint_android_vh_ufs_send_command +__tracepoint_android_vh_ufs_send_tm_command +__tracepoint_android_vh_ufs_send_uic_command +__tracepoint_android_vh_ufs_update_sdev +__tracepoint_android_vh_ufs_update_sysfs +__tracepoint_binder_transaction_received +__tracepoint_clock_set_rate +__tracepoint_cpu_frequency +__tracepoint_cpu_frequency_limits +__tracepoint_cpu_idle +__tracepoint_device_pm_callback_end +__tracepoint_device_pm_callback_start +__tracepoint_dma_fence_emit +__tracepoint_dwc3_ep_queue +__tracepoint_dwc3_readl +__tracepoint_dwc3_writel +__tracepoint_gpu_mem_total +__tracepoint_hrtimer_expire_entry +__tracepoint_hrtimer_expire_exit +__tracepoint_ipi_entry +__tracepoint_ipi_exit +__tracepoint_ipi_raise +__tracepoint_irq_handler_entry +__tracepoint_irq_handler_exit +__tracepoint_pelt_cfs_tp +__tracepoint_pelt_dl_tp +__tracepoint_pelt_irq_tp +__tracepoint_pelt_rt_tp +__tracepoint_pelt_se_tp +__tracepoint_rwmmio_post_read +__tracepoint_rwmmio_read +__tracepoint_rwmmio_write +__tracepoint_sched_cpu_capacity_tp +__tracepoint_sched_overutilized_tp +__tracepoint_sched_switch +__tracepoint_sched_util_est_cfs_tp +__tracepoint_sched_util_est_se_tp +__tracepoint_suspend_resume +__tracepoint_workqueue_execute_end +__tracepoint_workqueue_execute_start +__tracepoint_xdp_exception +__tty_insert_flip_char +__udelay +__uio_register_device +__unregister_chrdev +__update_load_avg_blocked_se +__usb_create_hcd +__usecs_to_jiffies +__v4l2_device_register_subdev_nodes +__video_register_device +__wait_rcu_gp +__wake_up +__wake_up_locked +__wake_up_locked_key +__wake_up_sync +__warn_printk +__xa_alloc +__xa_insert +__xfrm_state_destroy +_atomic_dec_and_lock +_copy_from_iter +_copy_from_iter_full +_copy_to_iter +_ctype +_dev_alert +_dev_crit +_dev_emerg +_dev_err +_dev_info +_dev_notice +_dev_warn +_raw_read_lock +_raw_read_lock_bh +_raw_read_lock_irq +_raw_read_lock_irqsave +_raw_read_unlock +_raw_read_unlock_bh +_raw_read_unlock_irq +_raw_read_unlock_irqrestore +_raw_spin_lock +_raw_spin_lock_bh +_raw_spin_lock_irq +_raw_spin_lock_irqsave +_raw_spin_trylock +_raw_spin_trylock_bh +_raw_spin_unlock +_raw_spin_unlock_bh +_raw_spin_unlock_irq +_raw_spin_unlock_irqrestore +_raw_write_lock +_raw_write_lock_bh +_raw_write_lock_irq +_raw_write_lock_irqsave +_raw_write_unlock +_raw_write_unlock_bh +_raw_write_unlock_irq +_raw_write_unlock_irqrestore +_snd_ctl_add_follower +_snd_pcm_stream_lock_irqsave +_totalram_pages +access_process_vm +ack_all_badblocks +activate_task +add_cpu +add_device_randomness +add_memory +add_memory_subsection +add_taint +add_timer +add_timer_on +add_uevent_var +add_wait_queue +adjust_managed_page_count +alarm_cancel +alarm_init +alarm_start +alarm_start_relative +alarm_try_to_cancel +alarmtimer_get_rtcdev +all_vm_events +alloc_anon_inode +alloc_chrdev_region +alloc_etherdev_mqs +alloc_io_pgtable_ops +alloc_netdev_mqs +alloc_page_buffers +alloc_pages_exact +alloc_skb_with_frags +alloc_workqueue +amba_bustype +amba_driver_register +amba_driver_unregister +amba_release_regions +amba_request_regions +android_debug_per_cpu_symbol +android_debug_symbol +android_rvh_probe_register +anon_inode_getfd +anon_inode_getfile +arch_timer_read_counter +argv_free +argv_split +arm64_const_caps_ready +arm64_use_ng_mappings +async_schedule_node +async_schedule_node_domain +async_synchronize_full_domain +atomic_notifier_call_chain +atomic_notifier_chain_register +atomic_notifier_chain_unregister +autoremove_wake_function +available_idle_cpu +backlight_device_get_by_type +backlight_device_register +backlight_device_set_brightness +backlight_device_unregister +badblocks_clear +badblocks_exit +badblocks_init +badblocks_set +badblocks_show +badblocks_store +balloon_aops +balloon_page_alloc +balloon_page_dequeue +balloon_page_enqueue +bcmp +bd_link_disk_holder +bd_set_nr_sectors +bd_unlink_disk_holder +bdev_check_media_change +bdev_read_only +bdevname +bdget_disk +bdput +bgpio_init +bin2hex +bio_add_page +bio_alloc_bioset +bio_associate_blkg +bio_chain +bio_clone_blkg_association +bio_endio +bio_init +bio_put +bioset_exit +bioset_init +bitmap_allocate_region +bitmap_find_next_zero_area_off +bitmap_from_arr32 +bitmap_parse +bitmap_parselist +bitmap_parselist_user +bitmap_print_to_pagebuf +bitmap_release_region +bitmap_to_arr32 +bitmap_zalloc +blk_alloc_queue +blk_cleanup_queue +blk_execute_rq +blk_execute_rq_nowait +blk_finish_plug +blk_freeze_queue_start +blk_get_queue +blk_get_request +blk_mq_alloc_request +blk_mq_alloc_request_hctx +blk_mq_alloc_tag_set +blk_mq_complete_request +blk_mq_complete_request_remote +blk_mq_debugfs_rq_show +blk_mq_delay_kick_requeue_list +blk_mq_end_request +blk_mq_free_request +blk_mq_free_tag_set +blk_mq_freeze_queue +blk_mq_freeze_queue_wait +blk_mq_freeze_queue_wait_timeout +blk_mq_init_queue +blk_mq_map_queues +blk_mq_pci_map_queues +blk_mq_quiesce_queue +blk_mq_requeue_request +blk_mq_rq_cpu +blk_mq_run_hw_queues +blk_mq_sched_request_inserted +blk_mq_sched_try_insert_merge +blk_mq_sched_try_merge +blk_mq_start_request +blk_mq_start_stopped_hw_queues +blk_mq_stop_hw_queue +blk_mq_tag_to_rq +blk_mq_tagset_busy_iter +blk_mq_tagset_wait_completed_request +blk_mq_unfreeze_queue +blk_mq_unique_tag +blk_mq_unquiesce_queue +blk_mq_update_nr_hw_queues +blk_mq_virtio_map_queues +blk_poll +blk_put_queue +blk_put_request +blk_queue_alignment_offset +blk_queue_bounce_limit +blk_queue_can_use_dma_map_merging +blk_queue_chunk_sectors +blk_queue_dma_alignment +blk_queue_flag_clear +blk_queue_flag_set +blk_queue_flag_test_and_set +blk_queue_io_min +blk_queue_io_opt +blk_queue_logical_block_size +blk_queue_max_discard_sectors +blk_queue_max_discard_segments +blk_queue_max_hw_sectors +blk_queue_max_segment_size +blk_queue_max_segments +blk_queue_max_write_zeroes_sectors +blk_queue_physical_block_size +blk_queue_rq_timeout +blk_queue_split +blk_queue_virt_boundary +blk_queue_write_cache +blk_register_region +blk_rq_map_kern +blk_rq_map_user +blk_rq_map_user_iov +blk_rq_unmap_user +blk_set_queue_dying +blk_set_stacking_limits +blk_start_plug +blk_status_to_errno +blk_sync_queue +blk_unregister_region +blk_update_request +blk_verify_command +blkdev_fsync +blkdev_get_by_dev +blkdev_get_by_path +blkdev_issue_flush +blkdev_put +blocking_notifier_call_chain +blocking_notifier_chain_register +blocking_notifier_chain_unregister +bmap +bpf_dispatcher_xdp_func +bpf_prog_add +bpf_prog_put +bpf_prog_sub +bpf_stats_enabled_key +bpf_trace_run1 +bpf_trace_run10 +bpf_trace_run11 +bpf_trace_run12 +bpf_trace_run2 +bpf_trace_run3 +bpf_trace_run4 +bpf_trace_run5 +bpf_trace_run6 +bpf_trace_run7 +bpf_trace_run8 +bpf_trace_run9 +bpf_warn_invalid_xdp_action +bsearch +bt_err +bt_info +build_skb +bus_find_device +bus_for_each_dev +bus_for_each_drv +bus_register +bus_register_notifier +bus_set_iommu +bus_unregister +bus_unregister_notifier +cache_line_size +call_netdevice_notifiers +call_rcu +call_rcu_tasks +call_rcu_tasks_trace +call_srcu +cancel_delayed_work +cancel_delayed_work_sync +cancel_work_sync +capable +cdev_add +cdev_alloc +cdev_del +cdev_device_add +cdev_device_del +cdev_init +cec_allocate_adapter +cec_delete_adapter +cec_received_msg_ts +cec_register_adapter +cec_s_log_addrs +cec_s_phys_addr +cec_s_phys_addr_from_edid +cec_transmit_attempt_done_ts +cec_transmit_done_ts +cec_unregister_adapter +cgroup_path_ns +cgroup_taskset_first +cgroup_taskset_next +check_preempt_curr +check_zeroed_user +class_create_file_ns +class_destroy +class_find_device +class_for_each_device +class_interface_unregister +class_remove_file_ns +class_unregister +cleancache_register_ops +cleanup_srcu_struct +clear_page +clk_bulk_disable +clk_bulk_enable +clk_bulk_get_all +clk_bulk_prepare +clk_bulk_put_all +clk_bulk_unprepare +clk_disable +clk_enable +clk_fixed_factor_ops +clk_fixed_rate_ops +clk_get +clk_get_parent +clk_get_rate +clk_hw_get_flags +clk_hw_get_name +clk_hw_get_num_parents +clk_hw_get_parent +clk_hw_get_parent_by_index +clk_hw_get_rate +clk_hw_is_enabled +clk_hw_is_prepared +clk_hw_register +clk_hw_register_fixed_factor +clk_hw_round_rate +clk_hw_set_rate_range +clk_hw_unregister +clk_hw_unregister_divider +clk_hw_unregister_fixed_factor +clk_hw_unregister_gate +clk_hw_unregister_mux +clk_notifier_register +clk_notifier_unregister +clk_prepare +clk_put +clk_register +clk_register_clkdev +clk_register_fixed_factor +clk_register_fixed_rate +clk_register_gate +clk_round_rate +clk_set_parent +clk_set_rate +clk_sync_state +clk_unprepare +clk_unregister +clockevents_config_and_register +clocks_calc_mult_shift +cma_alloc +cma_for_each_area +cma_get_name +cma_release +compat_alloc_user_space +compat_only_sysfs_link_entry_to_kobj +compat_ptr_ioctl +complete +complete_all +complete_and_exit +completion_done +component_add +component_bind_all +component_del +component_master_add_with_match +component_master_del +component_match_add_release +component_unbind_all +cond_synchronize_rcu +config_ep_by_speed +config_group_init +config_group_init_type_name +config_item_get +config_item_put +configfs_register_subsystem +configfs_unregister_subsystem +console_drivers +console_printk +console_stop +console_suspend_enabled +console_trylock +console_unlock +consume_skb +contig_page_data +copy_from_kernel_nofault +copy_page +cpu_all_bits +cpu_bit_bitmap +cpu_hwcap_keys +cpu_hwcaps +cpu_irqtime +cpu_is_hotpluggable +cpu_latency_qos_add_request +cpu_latency_qos_remove_request +cpu_latency_qos_request_active +cpu_latency_qos_update_request +cpu_number +cpu_pm_register_notifier +cpu_pm_unregister_notifier +cpu_scale +cpu_subsys +cpu_topology +cpufreq_add_update_util_hook +cpufreq_cpu_get +cpufreq_cpu_get_raw +cpufreq_cpu_put +cpufreq_disable_fast_switch +cpufreq_driver_fast_switch +cpufreq_driver_resolve_freq +cpufreq_enable_boost_support +cpufreq_enable_fast_switch +cpufreq_freq_attr_scaling_available_freqs +cpufreq_freq_attr_scaling_boost_freqs +cpufreq_freq_transition_begin +cpufreq_freq_transition_end +cpufreq_frequency_table_verify +cpufreq_generic_attr +cpufreq_generic_frequency_table_verify +cpufreq_generic_get +cpufreq_generic_suspend +cpufreq_get_driver_data +cpufreq_get_policy +cpufreq_policy_transition_delay_us +cpufreq_quick_get +cpufreq_quick_get_max +cpufreq_register_driver +cpufreq_register_governor +cpufreq_register_notifier +cpufreq_remove_update_util_hook +cpufreq_table_index_unsorted +cpufreq_this_cpu_can_update +cpufreq_unregister_driver +cpufreq_unregister_notifier +cpufreq_update_policy +cpuhp_tasks_frozen +cpuidle_governor_latency_req +cpuidle_register_governor +cpumask_any_but +cpumask_next +cpumask_next_and +cpumask_next_wrap +cpupri_find_fitness +cpus_read_lock +cpus_read_unlock +crc32_le +crc8 +crc8_populate_msb +create_function_device +crypto_aead_encrypt +crypto_aead_setauthsize +crypto_aead_setkey +crypto_alloc_aead +crypto_alloc_base +crypto_alloc_shash +crypto_alloc_skcipher +crypto_cipher_encrypt_one +crypto_cipher_setkey +crypto_comp_compress +crypto_comp_decompress +crypto_destroy_tfm +crypto_has_alg +crypto_register_alg +crypto_register_rngs +crypto_register_scomp +crypto_shash_digest +crypto_shash_final +crypto_shash_setkey +crypto_shash_update +crypto_skcipher_decrypt +crypto_skcipher_encrypt +crypto_skcipher_setkey +crypto_unregister_alg +crypto_unregister_rngs +crypto_unregister_scomp +css_next_child +csum_ipv6_magic +csum_partial +csum_tcpudp_nofold +current_time +current_work +d_add +d_alloc_name +d_delete +d_make_root +d_path +dapm_pinctrl_event +dapm_regulator_event +datagram_poll +deactivate_task +debugfs_attr_read +debugfs_attr_write +debugfs_create_atomic_t +debugfs_create_blob +debugfs_create_bool +debugfs_create_dir +debugfs_create_file +debugfs_create_file_unsafe +debugfs_create_regset32 +debugfs_create_size_t +debugfs_create_symlink +debugfs_create_u16 +debugfs_create_u32 +debugfs_create_u64 +debugfs_create_u8 +debugfs_create_ulong +debugfs_create_x32 +debugfs_create_x64 +debugfs_create_x8 +debugfs_file_get +debugfs_file_put +debugfs_lookup +debugfs_print_regs32 +debugfs_remove +dec_zone_page_state +default_llseek +deferred_free +del_gendisk +del_timer +del_timer_sync +delayed_work_timer_fn +desc_to_gpio +destroy_workqueue +dev_alloc_name +dev_close +dev_coredumpm +dev_coredumpv +dev_driver_string +dev_err_probe +dev_fwnode +dev_get_by_index +dev_get_by_name +dev_get_regmap +dev_get_stats +dev_mc_sync_multiple +dev_mc_unsync +dev_open +dev_pm_clear_wake_irq +dev_pm_domain_attach +dev_pm_domain_attach_by_name +dev_pm_domain_detach +dev_pm_genpd_add_notifier +dev_pm_genpd_remove_notifier +dev_pm_genpd_set_next_wakeup +dev_pm_genpd_set_performance_state +dev_pm_opp_add +dev_pm_opp_adjust_voltage +dev_pm_opp_disable +dev_pm_opp_enable +dev_pm_opp_find_freq_ceil +dev_pm_opp_find_freq_exact +dev_pm_opp_find_freq_floor +dev_pm_opp_free_cpufreq_table +dev_pm_opp_get_freq +dev_pm_opp_get_level +dev_pm_opp_get_max_transition_latency +dev_pm_opp_get_opp_count +dev_pm_opp_get_opp_table +dev_pm_opp_get_sharing_cpus +dev_pm_opp_get_suspend_opp_freq +dev_pm_opp_get_voltage +dev_pm_opp_init_cpufreq_table +dev_pm_opp_of_add_table +dev_pm_opp_of_cpumask_add_table +dev_pm_opp_of_cpumask_remove_table +dev_pm_opp_of_find_icc_paths +dev_pm_opp_of_get_sharing_cpus +dev_pm_opp_of_register_em +dev_pm_opp_of_remove_table +dev_pm_opp_put +dev_pm_opp_put_clkname +dev_pm_opp_put_opp_table +dev_pm_opp_put_regulators +dev_pm_opp_register_notifier +dev_pm_opp_remove_all_dynamic +dev_pm_opp_set_bw +dev_pm_opp_set_clkname +dev_pm_opp_set_rate +dev_pm_opp_set_regulators +dev_pm_opp_set_sharing_cpus +dev_pm_opp_set_supported_hw +dev_pm_opp_unregister_notifier +dev_pm_qos_add_notifier +dev_pm_qos_add_request +dev_pm_qos_expose_latency_tolerance +dev_pm_qos_hide_latency_tolerance +dev_pm_qos_read_value +dev_pm_qos_remove_notifier +dev_pm_qos_remove_request +dev_pm_qos_update_request +dev_pm_qos_update_user_latency_tolerance +dev_pm_set_dedicated_wake_irq +dev_printk +dev_printk_emit +dev_queue_xmit +dev_set_mtu +dev_set_name +dev_uc_sync_multiple +dev_uc_unsync +devfreq_add_device +devfreq_add_governor +devfreq_cooling_unregister +devfreq_get_devfreq_by_phandle +devfreq_monitor_resume +devfreq_monitor_start +devfreq_monitor_stop +devfreq_monitor_suspend +devfreq_recommended_opp +devfreq_register_opp_notifier +devfreq_remove_device +devfreq_remove_governor +devfreq_resume_device +devfreq_suspend_device +devfreq_unregister_opp_notifier +devfreq_update_interval +device_add +device_add_disk +device_add_groups +device_attach +device_bind_driver +device_create +device_create_bin_file +device_create_file +device_create_with_groups +device_del +device_destroy +device_find_child +device_for_each_child +device_get_dma_attr +device_get_mac_address +device_get_match_data +device_get_named_child_node +device_get_next_child_node +device_init_wakeup +device_initialize +device_link_add +device_link_del +device_match_fwnode +device_match_name +device_match_of_node +device_property_present +device_property_read_string +device_property_read_string_array +device_property_read_u16_array +device_property_read_u32_array +device_property_read_u8_array +device_register +device_release_driver +device_remove_bin_file +device_remove_file +device_remove_file_self +device_remove_groups +device_set_wakeup_capable +device_set_wakeup_enable +device_show_bool +device_show_int +device_store_bool +device_store_int +device_unregister +device_wakeup_disable +device_wakeup_enable +devm_add_action +devm_backlight_device_register +devm_backlight_device_unregister +devm_blk_ksm_init +devm_clk_bulk_get +devm_clk_bulk_get_all +devm_clk_bulk_get_optional +devm_clk_get +devm_clk_get_optional +devm_clk_hw_register +devm_clk_hw_register_clkdev +devm_clk_put +devm_clk_register +devm_devfreq_add_device +devm_devfreq_register_notifier +devm_devfreq_unregister_notifier +devm_device_add_group +devm_device_add_groups +devm_device_remove_group +devm_drm_panel_bridge_add_typed +devm_extcon_dev_allocate +devm_extcon_dev_register +devm_extcon_dev_unregister +devm_extcon_register_notifier +devm_free_irq +devm_free_percpu +devm_gen_pool_create +devm_get_clk_from_child +devm_gpio_free +devm_gpio_request +devm_gpio_request_one +devm_gpiochip_add_data_with_key +devm_gpiod_get +devm_gpiod_get_array +devm_gpiod_get_index +devm_gpiod_get_optional +devm_gpiod_put_array +devm_hwrng_register +devm_hwspin_lock_register +devm_i2c_new_dummy_device +devm_iio_channel_get +devm_iio_device_alloc +devm_input_allocate_device +devm_ioremap +devm_ioremap_resource +devm_ioremap_wc +devm_iounmap +devm_kasprintf +devm_kfree +devm_kmalloc +devm_kmemdup +devm_kstrdup +devm_kstrdup_const +devm_kvasprintf +devm_led_classdev_register_ext +devm_mbox_controller_register +devm_memremap +devm_mfd_add_devices +devm_nvmem_cell_get +devm_nvmem_device_get +devm_nvmem_register +devm_of_clk_add_hw_provider +devm_of_icc_get +devm_of_iomap +devm_of_platform_populate +devm_of_pwm_get +devm_pci_alloc_host_bridge +devm_phy_create +devm_phy_get +devm_phy_put +devm_pinctrl_get +devm_pinctrl_put +devm_pinctrl_register +devm_pinctrl_register_and_init +devm_platform_get_and_ioremap_resource +devm_platform_ioremap_resource +devm_platform_ioremap_resource_byname +devm_power_supply_register +devm_pwm_put +devm_regmap_add_irq_chip +devm_regmap_del_irq_chip +devm_regmap_field_alloc +devm_regulator_bulk_get +devm_regulator_get +devm_regulator_get_exclusive +devm_regulator_get_optional +devm_regulator_put +devm_regulator_register +devm_regulator_register_notifier +devm_request_any_context_irq +devm_request_threaded_irq +devm_reset_control_array_get +devm_reset_controller_register +devm_rtc_allocate_device +devm_rtc_device_register +devm_snd_dmaengine_pcm_register +devm_snd_soc_register_card +devm_snd_soc_register_component +devm_spi_register_controller +devm_thermal_of_cooling_device_register +devm_thermal_zone_of_sensor_register +devm_thermal_zone_of_sensor_unregister +devm_usb_get_phy +devm_usb_get_phy_by_node +devm_usb_get_phy_by_phandle +devm_watchdog_register_device +devres_add +devres_alloc_node +devres_free +devres_release +disable_irq +disable_irq_nosync +disable_percpu_irq +disk_end_io_acct +disk_start_io_acct +divider_get_val +divider_recalc_rate +divider_ro_round_rate_parent +divider_round_rate_parent +dma_alloc_attrs +dma_async_device_register +dma_async_device_unregister +dma_async_tx_descriptor_init +dma_buf_attach +dma_buf_begin_cpu_access +dma_buf_begin_cpu_access_partial +dma_buf_detach +dma_buf_dynamic_attach +dma_buf_end_cpu_access +dma_buf_end_cpu_access_partial +dma_buf_export +dma_buf_fd +dma_buf_get +dma_buf_get_flags +dma_buf_map_attachment +dma_buf_mmap +dma_buf_move_notify +dma_buf_pin +dma_buf_put +dma_buf_unmap_attachment +dma_buf_unpin +dma_buf_vmap +dma_buf_vunmap +dma_contiguous_default_area +dma_fence_add_callback +dma_fence_array_create +dma_fence_array_ops +dma_fence_context_alloc +dma_fence_default_wait +dma_fence_enable_sw_signaling +dma_fence_free +dma_fence_get_status +dma_fence_get_stub +dma_fence_init +dma_fence_match_context +dma_fence_release +dma_fence_remove_callback +dma_fence_signal +dma_fence_signal_locked +dma_fence_wait_any_timeout +dma_fence_wait_timeout +dma_free_attrs +dma_get_merge_boundary +dma_get_required_mask +dma_get_sgtable_attrs +dma_get_slave_caps +dma_get_slave_channel +dma_heap_add +dma_heap_buffer_alloc +dma_heap_buffer_free +dma_heap_find +dma_heap_get_dev +dma_heap_get_drvdata +dma_heap_get_name +dma_heap_put +dma_map_page_attrs +dma_map_resource +dma_map_sg_attrs +dma_max_mapping_size +dma_mmap_attrs +dma_pool_alloc +dma_pool_create +dma_pool_destroy +dma_pool_free +dma_release_channel +dma_request_chan +dma_resv_add_excl_fence +dma_resv_add_shared_fence +dma_resv_fini +dma_resv_get_fences_rcu +dma_resv_init +dma_resv_reserve_shared +dma_resv_test_signaled_rcu +dma_resv_wait_timeout_rcu +dma_set_coherent_mask +dma_set_mask +dma_sync_sg_for_cpu +dma_sync_sg_for_device +dma_sync_single_for_cpu +dma_sync_single_for_device +dma_unmap_page_attrs +dma_unmap_resource +dma_unmap_sg_attrs +dmabuf_page_pool_alloc +dmabuf_page_pool_create +dmabuf_page_pool_destroy +dmabuf_page_pool_free +dmaengine_unmap_put +dmam_alloc_attrs +dmam_free_coherent +dmam_pool_create +do_SAK +do_exit +do_trace_rcu_torture_read +do_wait_intr +do_wait_intr_irq +down +down_interruptible +down_read +down_read_killable +down_read_trylock +down_timeout +down_trylock +down_write +downgrade_write +dput +drain_workqueue +driver_create_file +driver_find_device +driver_register +driver_remove_file +driver_unregister +drm_add_edid_modes +drm_add_modes_noedid +drm_atomic_add_affected_connectors +drm_atomic_add_affected_planes +drm_atomic_commit +drm_atomic_get_connector_state +drm_atomic_get_crtc_state +drm_atomic_get_new_connector_for_encoder +drm_atomic_get_plane_state +drm_atomic_get_private_obj_state +drm_atomic_helper_bridge_destroy_state +drm_atomic_helper_bridge_duplicate_state +drm_atomic_helper_bridge_reset +drm_atomic_helper_check +drm_atomic_helper_check_modeset +drm_atomic_helper_check_plane_state +drm_atomic_helper_check_planes +drm_atomic_helper_cleanup_planes +drm_atomic_helper_commit +drm_atomic_helper_commit_cleanup_done +drm_atomic_helper_commit_duplicated_state +drm_atomic_helper_commit_hw_done +drm_atomic_helper_commit_modeset_disables +drm_atomic_helper_commit_modeset_enables +drm_atomic_helper_commit_planes +drm_atomic_helper_commit_tail +drm_atomic_helper_connector_destroy_state +drm_atomic_helper_connector_duplicate_state +drm_atomic_helper_connector_reset +drm_atomic_helper_crtc_destroy_state +drm_atomic_helper_crtc_duplicate_state +drm_atomic_helper_crtc_reset +drm_atomic_helper_damage_merged +drm_atomic_helper_dirtyfb +drm_atomic_helper_disable_plane +drm_atomic_helper_disable_planes_on_crtc +drm_atomic_helper_duplicate_state +drm_atomic_helper_fake_vblank +drm_atomic_helper_page_flip +drm_atomic_helper_plane_destroy_state +drm_atomic_helper_plane_duplicate_state +drm_atomic_helper_plane_reset +drm_atomic_helper_prepare_planes +drm_atomic_helper_set_config +drm_atomic_helper_setup_commit +drm_atomic_helper_shutdown +drm_atomic_helper_swap_state +drm_atomic_helper_update_legacy_modeset_state +drm_atomic_helper_update_plane +drm_atomic_helper_wait_for_dependencies +drm_atomic_helper_wait_for_fences +drm_atomic_helper_wait_for_flip_done +drm_atomic_helper_wait_for_vblanks +drm_atomic_normalize_zpos +drm_atomic_private_obj_fini +drm_atomic_private_obj_init +drm_atomic_set_crtc_for_connector +drm_atomic_set_crtc_for_plane +drm_atomic_set_fb_for_plane +drm_atomic_set_fence_for_plane +drm_atomic_set_mode_for_crtc +drm_atomic_state_alloc +drm_atomic_state_clear +drm_atomic_state_default_clear +drm_atomic_state_default_release +drm_atomic_state_init +drm_bridge_add +drm_bridge_attach +drm_bridge_chain_disable +drm_bridge_chain_enable +drm_bridge_chain_mode_set +drm_bridge_chain_post_disable +drm_bridge_chain_pre_enable +drm_bridge_hpd_notify +drm_bridge_remove +drm_client_init +drm_client_modeset_commit_locked +drm_client_register +drm_compat_ioctl +drm_connector_attach_dp_subconnector_property +drm_connector_attach_edid_property +drm_connector_attach_encoder +drm_connector_cleanup +drm_connector_has_possible_encoder +drm_connector_init +drm_connector_init_with_ddc +drm_connector_list_iter_begin +drm_connector_list_iter_end +drm_connector_list_iter_next +drm_connector_register +drm_connector_set_tile_property +drm_connector_unregister +drm_connector_update_edid_property +drm_crtc_arm_vblank_event +drm_crtc_cleanup +drm_crtc_enable_color_mgmt +drm_crtc_from_index +drm_crtc_handle_vblank +drm_crtc_helper_set_config +drm_crtc_helper_set_mode +drm_crtc_init +drm_crtc_init_with_planes +drm_crtc_send_vblank_event +drm_crtc_set_max_vblank_count +drm_crtc_vblank_count +drm_crtc_vblank_count_and_time +drm_crtc_vblank_get +drm_crtc_vblank_helper_get_vblank_timestamp +drm_crtc_vblank_off +drm_crtc_vblank_on +drm_crtc_vblank_put +drm_crtc_vblank_reset +drm_crtc_wait_one_vblank +drm_cvt_mode +drm_debugfs_create_files +drm_detect_hdmi_monitor +drm_detect_monitor_audio +drm_dev_alloc +drm_dev_dbg +drm_dev_enter +drm_dev_exit +drm_dev_get +drm_dev_printk +drm_dev_put +drm_dev_register +drm_dev_set_unique +drm_dev_unplug +drm_dev_unregister +drm_display_mode_to_videomode +drm_do_get_edid +drm_dp_atomic_find_vcpi_slots +drm_dp_atomic_release_vcpi_slots +drm_dp_aux_init +drm_dp_aux_register +drm_dp_aux_unregister +drm_dp_bw_code_to_link_rate +drm_dp_calc_pbn_mode +drm_dp_channel_eq_ok +drm_dp_check_act_status +drm_dp_clock_recovery_ok +drm_dp_dpcd_read +drm_dp_dpcd_read_link_status +drm_dp_dpcd_write +drm_dp_find_vcpi_slots +drm_dp_get_adjust_request_pre_emphasis +drm_dp_get_adjust_request_voltage +drm_dp_get_edid_quirks +drm_dp_link_rate_to_bw_code +drm_dp_link_train_channel_eq_delay +drm_dp_link_train_clock_recovery_delay +drm_dp_mst_allocate_vcpi +drm_dp_mst_deallocate_vcpi +drm_dp_mst_detect_port +drm_dp_mst_get_edid +drm_dp_mst_get_port_malloc +drm_dp_mst_hpd_irq +drm_dp_mst_put_port_malloc +drm_dp_mst_reset_vcpi_slots +drm_dp_mst_topology_mgr_destroy +drm_dp_mst_topology_mgr_init +drm_dp_mst_topology_mgr_set_mst +drm_dp_send_power_updown_phy +drm_dp_set_subconnector_property +drm_dp_update_payload_part1 +drm_dp_update_payload_part2 +drm_edid_block_valid +drm_edid_duplicate +drm_edid_get_monitor_name +drm_edid_header_is_valid +drm_edid_is_valid +drm_edid_to_sad +drm_edid_to_speaker_allocation +drm_encoder_cleanup +drm_encoder_init +drm_event_cancel_free +drm_event_reserve_init +drm_event_reserve_init_locked +drm_fb_cma_get_gem_obj +drm_flip_work_cleanup +drm_flip_work_commit +drm_flip_work_init +drm_flip_work_queue +drm_format_info +drm_framebuffer_cleanup +drm_framebuffer_init +drm_framebuffer_lookup +drm_framebuffer_remove +drm_framebuffer_unregister_private +drm_gem_cma_dumb_create_internal +drm_gem_cma_free_object +drm_gem_cma_mmap +drm_gem_cma_prime_get_sg_table +drm_gem_cma_prime_import_sg_table +drm_gem_cma_prime_mmap +drm_gem_cma_prime_vmap +drm_gem_cma_prime_vunmap +drm_gem_cma_vm_ops +drm_gem_create_mmap_offset +drm_gem_dmabuf_mmap +drm_gem_dmabuf_release +drm_gem_dmabuf_vmap +drm_gem_dmabuf_vunmap +drm_gem_fb_create +drm_gem_fb_create_handle +drm_gem_fb_destroy +drm_gem_fb_get_obj +drm_gem_fb_prepare_fb +drm_gem_free_mmap_offset +drm_gem_get_pages +drm_gem_handle_create +drm_gem_lock_reservations +drm_gem_map_attach +drm_gem_map_detach +drm_gem_map_dma_buf +drm_gem_mmap +drm_gem_mmap_obj +drm_gem_object_free +drm_gem_object_init +drm_gem_object_lookup +drm_gem_object_put_locked +drm_gem_object_release +drm_gem_prime_export +drm_gem_prime_fd_to_handle +drm_gem_prime_handle_to_fd +drm_gem_prime_import +drm_gem_prime_import_dev +drm_gem_prime_mmap +drm_gem_private_object_init +drm_gem_put_pages +drm_gem_shmem_create +drm_gem_shmem_free_object +drm_gem_shmem_get_sg_table +drm_gem_shmem_mmap +drm_gem_shmem_pin +drm_gem_shmem_print_info +drm_gem_shmem_unpin +drm_gem_shmem_vmap +drm_gem_shmem_vunmap +drm_gem_unlock_reservations +drm_gem_unmap_dma_buf +drm_gem_vm_close +drm_gem_vm_open +drm_get_connector_status_name +drm_get_edid +drm_get_format_info +drm_get_format_name +drm_handle_vblank +drm_hdmi_avi_infoframe_from_display_mode +drm_helper_connector_dpms +drm_helper_disable_unused_functions +drm_helper_force_disable_all +drm_helper_hpd_irq_event +drm_helper_mode_fill_fb_struct +drm_helper_probe_single_connector_modes +drm_helper_resume_force_mode +drm_ioctl +drm_irq_install +drm_irq_uninstall +drm_is_current_master +drm_kms_helper_hotplug_event +drm_kms_helper_is_poll_worker +drm_kms_helper_poll_disable +drm_kms_helper_poll_enable +drm_kms_helper_poll_fini +drm_kms_helper_poll_init +drm_match_cea_mode +drm_mm_init +drm_mm_insert_node_in_range +drm_mm_print +drm_mm_remove_node +drm_mm_takedown +drm_mode_config_cleanup +drm_mode_config_helper_resume +drm_mode_config_helper_suspend +drm_mode_config_reset +drm_mode_convert_to_umode +drm_mode_convert_umode +drm_mode_copy +drm_mode_create +drm_mode_create_dp_colorspace_property +drm_mode_create_scaling_mode_property +drm_mode_create_tile_group +drm_mode_crtc_set_gamma_size +drm_mode_debug_printmodeline +drm_mode_destroy +drm_mode_duplicate +drm_mode_equal +drm_mode_equal_no_clocks +drm_mode_get_tile_group +drm_mode_is_420_only +drm_mode_match +drm_mode_object_find +drm_mode_object_get +drm_mode_object_put +drm_mode_probed_add +drm_mode_set_crtcinfo +drm_mode_set_name +drm_mode_vrefresh +drm_modeset_acquire_fini +drm_modeset_acquire_init +drm_modeset_backoff +drm_modeset_drop_locks +drm_modeset_lock +drm_modeset_lock_all +drm_modeset_lock_all_ctx +drm_modeset_lock_init +drm_modeset_unlock +drm_modeset_unlock_all +drm_need_swiotlb +drm_object_attach_property +drm_object_property_set_value +drm_of_component_match_add +drm_of_find_possible_crtcs +drm_open +drm_panel_add +drm_panel_disable +drm_panel_enable +drm_panel_get_modes +drm_panel_init +drm_panel_prepare +drm_panel_remove +drm_panel_unprepare +drm_plane_cleanup +drm_plane_create_alpha_property +drm_plane_create_blend_mode_property +drm_plane_create_rotation_property +drm_plane_create_zpos_property +drm_plane_enable_fb_damage_clips +drm_poll +drm_prime_gem_destroy +drm_prime_pages_to_sg +drm_prime_sg_to_page_addr_arrays +drm_printf +drm_property_blob_get +drm_property_blob_put +drm_property_create +drm_property_create_bitmask +drm_property_create_blob +drm_property_create_bool +drm_property_create_enum +drm_property_create_range +drm_property_create_signed_range +drm_property_lookup_blob +drm_property_replace_blob +drm_puts +drm_read +drm_rect_calc_hscale +drm_rect_calc_vscale +drm_rect_clip_scaled +drm_rect_intersect +drm_release +drm_rotation_simplify +drm_send_event +drm_send_event_locked +drm_set_preferred_mode +drm_simple_encoder_init +drm_state_dump +drm_syncobj_add_point +drm_syncobj_create +drm_syncobj_find +drm_syncobj_find_fence +drm_syncobj_free +drm_syncobj_get_fd +drm_syncobj_get_handle +drm_syncobj_replace_fence +drm_sysfs_hotplug_event +drm_universal_plane_init +drm_vblank_init +drm_vma_node_allow +drm_vma_node_is_allowed +drm_vma_node_revoke +drm_wait_one_vblank +drm_writeback_connector_init +drm_writeback_queue_job +drm_writeback_signal_completion +drmm_kmalloc +drmm_mode_config_init +dst_release +dump_backtrace +dump_stack +dup_iter +dw_handle_msi_irq +dw_pcie_host_init +dw_pcie_msi_init +dw_pcie_own_conf_map_bus +dw_pcie_read +dw_pcie_setup_rc +dw_pcie_write +dwc3_send_gadget_ep_cmd +dwc3_stop_active_transfer +edac_device_add_device +edac_device_alloc_ctl_info +edac_device_alloc_index +edac_device_del_device +edac_device_free_ctl_info +edac_device_handle_ce_count +edac_device_handle_ue_count +efi +efi_tpm_final_log_size +elevator_alloc +elv_bio_merge_ok +elv_rb_add +elv_rb_del +elv_rb_find +elv_rb_former_request +elv_rb_latter_request +elv_register +elv_rqhash_add +elv_rqhash_del +elv_unregister +emergency_restart +enable_irq +enable_percpu_irq +eth_commit_mac_addr_change +eth_mac_addr +eth_platform_get_mac_address +eth_prepare_mac_addr_change +eth_type_trans +eth_validate_addr +ether_setup +ethtool_op_get_link +ethtool_op_get_ts_info +ethtool_virtdev_set_link_ksettings +event_triggers_call +eventfd_ctx_fdget +eventfd_ctx_fileget +eventfd_ctx_put +eventfd_ctx_remove_wait_queue +eventfd_signal +extcon_find_edev_by_node +extcon_get_edev_by_phandle +extcon_get_edev_name +extcon_get_extcon_dev +extcon_get_property +extcon_get_state +extcon_register_notifier +extcon_set_property +extcon_set_property_capability +extcon_set_state_sync +extcon_unregister_notifier +fasync_helper +fd_install +fget +file_path +file_ra_state_init +filp_close +filp_open_block +find_get_pid +find_last_bit +find_next_bit +find_next_zero_bit +find_snd_usb_substream +find_task_by_vpid +find_vma +find_vpid +finish_wait +firmware_request_nowarn +fixed_size_llseek +flow_keys_basic_dissector +flush_dcache_page +flush_delayed_work +flush_signals +flush_work +flush_workqueue +fput +frame_vector_create +frame_vector_destroy +frame_vector_to_pages +free_buffer_head +free_io_pgtable_ops +free_irq +free_netdev +free_pages +free_pages_exact +free_percpu +free_percpu_irq +freezing_slow_path +freq_qos_add_request +freq_qos_remove_request +freq_qos_update_request +freq_scale +fs_bio_set +fsync_bdev +ftrace_dump +full_name_hash +fwnode_find_reference +fwnode_get_name +fwnode_get_named_child_node +fwnode_get_next_child_node +fwnode_gpiod_get_index +fwnode_handle_get +fwnode_handle_put +fwnode_property_present +fwnode_property_read_string +fwnode_property_read_u32_array +fwnode_usb_role_switch_get +gcd +gen_pool_add_owner +gen_pool_alloc_algo_owner +gen_pool_avail +gen_pool_best_fit +gen_pool_create +gen_pool_destroy +gen_pool_dma_alloc_align +gen_pool_dma_zalloc_align +gen_pool_first_fit_align +gen_pool_first_fit_order_align +gen_pool_free_owner +gen_pool_has_addr +gen_pool_set_algo +gen_pool_size +gen_pool_virt_to_phys +generic_delete_inode +generic_device_group +generic_file_llseek +generic_file_read_iter +generic_handle_irq +generic_iommu_put_resv_regions +generic_mii_ioctl +generic_perform_write +generic_write_checks +genl_notify +genl_register_family +genl_unregister_family +genlmsg_put +genphy_resume +get_cpu_device +get_cpu_idle_time +get_cpu_idle_time_us +get_cpu_iowait_time_us +get_device +get_device_system_crosststamp +get_governor_parent_kobj +get_next_ino +get_option +get_options +get_pid_task +get_random_bytes +get_random_bytes_arch +get_random_u32 +get_random_u64 +get_sg_io_hdr +get_state_synchronize_rcu +get_task_exe_file +get_task_mm +get_task_pid +get_thermal_instance +get_tree_single +get_unmapped_area +get_unused_fd_flags +get_user_pages +get_user_pages_fast +get_user_pages_remote +get_vaddr_frames +get_zeroed_page +getboottime64 +gfp_zone +gic_nonsecure_priorities +glob_match +gnss_allocate_device +gnss_deregister_device +gnss_insert_raw +gnss_put_device +gnss_register_device +gov_attr_set_get +gov_attr_set_init +gov_attr_set_put +governor_sysfs_ops +gpio_free +gpio_free_array +gpio_request +gpio_request_one +gpio_to_desc +gpiochip_add_data_with_key +gpiochip_add_pin_range +gpiochip_find +gpiochip_generic_config +gpiochip_generic_free +gpiochip_generic_request +gpiochip_get_data +gpiochip_line_is_valid +gpiochip_lock_as_irq +gpiochip_populate_parent_fwspec_fourcell +gpiochip_remove +gpiochip_unlock_as_irq +gpiod_cansleep +gpiod_count +gpiod_direction_input +gpiod_direction_output +gpiod_direction_output_raw +gpiod_get_optional +gpiod_get_raw_value +gpiod_get_raw_value_cansleep +gpiod_get_value +gpiod_get_value_cansleep +gpiod_set_consumer_name +gpiod_set_debounce +gpiod_set_raw_value +gpiod_set_raw_value_cansleep +gpiod_set_value +gpiod_set_value_cansleep +gpiod_to_chip +gpiod_to_irq +gro_cells_destroy +gro_cells_init +gro_cells_receive +gserial_alloc_line +gserial_connect +gserial_disconnect +guid_gen +handle_bad_irq +handle_edge_irq +handle_fasteoi_ack_irq +handle_fasteoi_irq +handle_level_irq +handle_nested_irq +handle_simple_irq +handle_sysrq +hash_digest_size +hashlen_string +have_governor_per_policy +hci_alloc_dev +hci_free_dev +hci_recv_frame +hci_register_dev +hci_unregister_dev +hdmi_audio_infoframe_init +hdmi_audio_infoframe_pack +hdmi_avi_infoframe_init +hdmi_avi_infoframe_pack +hdmi_infoframe_pack +hex2bin +hex_dump_to_buffer +hex_to_bin +hmm_range_fault +hrtimer_active +hrtimer_cancel +hrtimer_forward +hrtimer_init +hrtimer_init_sleeper +hrtimer_sleeper_start_expires +hrtimer_start_range_ns +hrtimer_try_to_cancel +hvc_alloc +hvc_instantiate +hvc_kick +hvc_poll +hvc_remove +hwrng_register +hwrng_unregister +hwspin_lock_free +hwspin_lock_request_specific +hypervisor_kobj +i2c_adapter_type +i2c_add_adapter +i2c_add_numbered_adapter +i2c_bit_add_bus +i2c_bit_add_numbered_bus +i2c_bus_type +i2c_client_type +i2c_del_adapter +i2c_del_driver +i2c_for_each_dev +i2c_generic_scl_recovery +i2c_get_adapter +i2c_get_device_id +i2c_get_dma_safe_msg_buf +i2c_match_id +i2c_new_ancillary_device +i2c_new_client_device +i2c_new_dummy_device +i2c_new_scanned_device +i2c_parse_fw_timings +i2c_put_adapter +i2c_put_dma_safe_msg_buf +i2c_recover_bus +i2c_register_driver +i2c_smbus_read_byte +i2c_smbus_read_byte_data +i2c_smbus_read_i2c_block_data +i2c_smbus_read_word_data +i2c_smbus_write_byte +i2c_smbus_write_byte_data +i2c_smbus_write_i2c_block_data +i2c_smbus_write_word_data +i2c_smbus_xfer +i2c_transfer +i2c_transfer_buffer_flags +i2c_unregister_device +i2c_verify_adapter +i2c_verify_client +icc_disable +icc_enable +icc_get +icc_link_create +icc_node_add +icc_node_create +icc_node_del +icc_node_destroy +icc_nodes_remove +icc_provider_add +icc_provider_del +icc_put +icc_set_bw +icc_set_tag +icc_std_aggregate +icc_sync_state +ida_alloc_range +ida_destroy +ida_free +idr_alloc +idr_alloc_cyclic +idr_alloc_u32 +idr_destroy +idr_find +idr_for_each +idr_get_next +idr_preload +idr_remove +idr_replace +ieee802154_alloc_hw +ieee802154_free_hw +ieee802154_register_hw +ieee802154_rx_irqsafe +ieee802154_unregister_hw +ieee802154_wake_queue +ieee802154_xmit_complete +iio_buffer_init +iio_buffer_put +iio_channel_get +iio_channel_get_all +iio_channel_release +iio_device_alloc +iio_device_attach_buffer +iio_device_free +iio_device_unregister +iio_push_to_buffers +iio_read_channel_processed +iio_read_channel_raw +import_iovec +in4_pton +in6_pton +in_aton +in_egroup_p +inc_zone_page_state +inet_proto_csum_replace4 +init_dummy_netdev +init_iova_domain +init_net +init_on_free +init_pid_ns +init_pseudo +init_srcu_struct +init_task +init_timer_key +init_uts_ns +init_wait_entry +input_alloc_absinfo +input_allocate_device +input_close_device +input_event +input_ff_create +input_ff_destroy +input_free_device +input_mt_assign_slots +input_mt_destroy_slots +input_mt_drop_unused +input_mt_init_slots +input_mt_report_finger_count +input_mt_report_pointer_emulation +input_mt_report_slot_state +input_mt_sync_frame +input_open_device +input_register_device +input_register_handle +input_register_handler +input_set_abs_params +input_set_capability +input_set_timestamp +input_unregister_device +input_unregister_handle +input_unregister_handler +int_pow +int_sqrt +interval_tree_insert +interval_tree_iter_first +interval_tree_iter_next +interval_tree_remove +invalidate_bdev +invalidate_mapping_pages +io_schedule_timeout +iomem_resource +iommu_alloc_resv_region +iommu_attach_device +iommu_attach_group +iommu_aux_attach_device +iommu_aux_detach_device +iommu_aux_get_pasid +iommu_detach_device +iommu_detach_group +iommu_dev_enable_feature +iommu_dev_feature_enabled +iommu_device_register +iommu_device_sysfs_add +iommu_device_sysfs_remove +iommu_device_unlink +iommu_device_unregister +iommu_dma_enable_best_fit_algo +iommu_dma_get_resv_regions +iommu_dma_reserve_iova +iommu_domain_alloc +iommu_domain_free +iommu_domain_get_attr +iommu_domain_set_attr +iommu_fwspec_add_ids +iommu_fwspec_free +iommu_get_dma_cookie +iommu_get_domain_for_dev +iommu_get_msi_cookie +iommu_group_alloc +iommu_group_for_each_dev +iommu_group_get +iommu_group_get_iommudata +iommu_group_put +iommu_group_ref_get +iommu_group_set_iommudata +iommu_group_set_name +iommu_iova_to_phys +iommu_map +iommu_map_sg +iommu_present +iommu_put_dma_cookie +iommu_register_device_fault_handler +iommu_report_device_fault +iommu_set_fault_handler +iommu_unmap +iommu_unregister_device_fault_handler +iounmap +iov_iter_bvec +iov_iter_kvec +ip_compute_csum +ip_send_check +ipi_desc_get +iput +ipv6_ext_hdr +ipv6_find_hdr +ipv6_skip_exthdr +irq_chip_ack_parent +irq_chip_disable_parent +irq_chip_enable_parent +irq_chip_eoi_parent +irq_chip_get_parent_state +irq_chip_mask_parent +irq_chip_retrigger_hierarchy +irq_chip_set_affinity_parent +irq_chip_set_parent_state +irq_chip_set_type_parent +irq_chip_set_vcpu_affinity_parent +irq_chip_set_wake_parent +irq_chip_unmask_parent +irq_create_fwspec_mapping +irq_create_mapping_affinity +irq_create_of_mapping +irq_dispose_mapping +irq_domain_alloc_irqs_parent +irq_domain_create_hierarchy +irq_domain_free_irqs_common +irq_domain_free_irqs_parent +irq_domain_get_irq_data +irq_domain_remove +irq_domain_set_hwirq_and_chip +irq_domain_set_info +irq_domain_simple_ops +irq_domain_update_bus_token +irq_domain_xlate_onecell +irq_domain_xlate_onetwocell +irq_domain_xlate_twocell +irq_find_mapping +irq_find_matching_fwspec +irq_get_irq_data +irq_get_irqchip_state +irq_modify_status +irq_of_parse_and_map +irq_set_affinity_hint +irq_set_affinity_notifier +irq_set_chained_handler_and_data +irq_set_chip +irq_set_chip_and_handler_name +irq_set_chip_data +irq_set_handler_data +irq_set_irq_type +irq_set_irq_wake +irq_set_irqchip_state +irq_set_parent +irq_to_desc +irq_work_queue +irq_work_queue_on +irq_work_sync +is_dma_buf_file +is_vmalloc_addr +jiffies +jiffies64_to_msecs +jiffies_64_to_clock_t +jiffies_to_msecs +jiffies_to_usecs +kasan_flag_enabled +kasprintf +kern_mount +kern_unmount +kernel_bind +kernel_connect +kernel_cpustat +kernel_getsockname +kernel_kobj +kernel_power_off +kernel_recvmsg +kernel_restart +kernel_sendmsg +kernel_sigaction +kernfs_find_and_get_ns +kernfs_notify +kernfs_put +kfree +kfree_const +kfree_sensitive +kfree_skb +kick_all_cpus_sync +kill_anon_super +kill_fasync +kill_litter_super +kimage_vaddr +kimage_voffset +kiocb_set_cancel_fn +kmalloc_caches +kmalloc_order +kmalloc_order_trace +kmem_cache_alloc +kmem_cache_alloc_trace +kmem_cache_create +kmem_cache_create_usercopy +kmem_cache_destroy +kmem_cache_free +kmemdup +kmemdup_nul +kmsg_dump_get_line +kmsg_dump_rewind +kobj_sysfs_ops +kobject_add +kobject_create_and_add +kobject_del +kobject_get +kobject_init +kobject_init_and_add +kobject_put +kobject_set_name +kobject_uevent +kobject_uevent_env +krealloc +kset_create_and_add +ksize +ksoftirqd +kstat +kstat_irqs_cpu +kstat_irqs_usr +kstrdup +kstrdup_const +kstrdup_quotable_cmdline +kstrndup +kstrtobool +kstrtobool_from_user +kstrtoint +kstrtoint_from_user +kstrtol_from_user +kstrtoll +kstrtos8 +kstrtos8_from_user +kstrtou16 +kstrtou16_from_user +kstrtou8 +kstrtou8_from_user +kstrtouint +kstrtouint_from_user +kstrtoul_from_user +kstrtoull +kstrtoull_from_user +ksys_sync_helper +kthread_bind +kthread_bind_mask +kthread_cancel_delayed_work_sync +kthread_cancel_work_sync +kthread_create_on_node +kthread_create_worker +kthread_delayed_work_timer_fn +kthread_destroy_worker +kthread_flush_work +kthread_flush_worker +kthread_mod_delayed_work +kthread_park +kthread_parkme +kthread_queue_delayed_work +kthread_queue_work +kthread_should_park +kthread_should_stop +kthread_stop +kthread_unpark +kthread_unuse_mm +kthread_use_mm +kthread_worker_fn +ktime_add_safe +ktime_get +ktime_get_coarse_with_offset +ktime_get_mono_fast_ns +ktime_get_raw +ktime_get_raw_ts64 +ktime_get_real_seconds +ktime_get_real_ts64 +ktime_get_seconds +ktime_get_ts64 +ktime_get_with_offset +kvasprintf +kvfree +kvfree_call_rcu +kvmalloc_node +led_classdev_flash_register_ext +led_classdev_flash_unregister +led_classdev_register_ext +led_classdev_unregister +led_trigger_event +led_trigger_register_simple +led_trigger_unregister_simple +list_sort +llist_add_batch +llist_reverse_order +lock_sock_nested +log_abnormal_wakeup_reason +log_buf_addr_get +log_buf_len_get +log_threaded_irq_wakeup_reason +loops_per_jiffy +lzo1x_1_compress +lzo1x_decompress_safe +lzorle1x_1_compress +mac_pton +match_string +mbox_chan_received_data +mbox_chan_txdone +mbox_client_txdone +mbox_controller_register +mbox_controller_unregister +mbox_free_channel +mbox_request_channel +mbox_send_message +mdiobus_alloc_size +mdiobus_free +mdiobus_unregister +media_device_cleanup +media_device_init +media_device_unregister +media_entity_pads_init +memblock_end_of_DRAM +memblock_free +memchr +memchr_inv +memcmp +memcpy +memdup_user +memdup_user_nul +memmove +memory_block_size_bytes +memory_read_from_buffer +memparse +mempool_alloc +mempool_alloc_slab +mempool_create +mempool_create_node +mempool_destroy +mempool_exit +mempool_free +mempool_free_slab +mempool_init +mempool_kfree +mempool_kmalloc +memremap +memset +memset64 +memstart_addr +memunmap +mfd_add_devices +mfd_remove_devices +migrate_swap +mii_check_media +mii_ethtool_get_link_ksettings +mii_ethtool_gset +mii_ethtool_set_link_ksettings +mii_link_ok +mii_nway_restart +mipi_dsi_attach +mipi_dsi_compression_mode +mipi_dsi_create_packet +mipi_dsi_dcs_read +mipi_dsi_dcs_set_column_address +mipi_dsi_dcs_set_display_brightness +mipi_dsi_dcs_set_page_address +mipi_dsi_dcs_set_tear_off +mipi_dsi_dcs_write_buffer +mipi_dsi_detach +mipi_dsi_device_register_full +mipi_dsi_device_unregister +mipi_dsi_driver_register_full +mipi_dsi_driver_unregister +mipi_dsi_host_register +mipi_dsi_host_unregister +mipi_dsi_packet_format_is_long +mipi_dsi_picture_parameter_set +misc_deregister +misc_register +mktime64 +mm_trace_rss_stat +mmc_add_host +mmc_alloc_host +mmc_app_cmd +mmc_calc_max_discard +mmc_can_erase +mmc_can_gpio_cd +mmc_can_secure_erase_trim +mmc_can_trim +mmc_cmdq_disable +mmc_cmdq_enable +mmc_cqe_post_req +mmc_cqe_recovery +mmc_cqe_request_done +mmc_cqe_start_req +mmc_detect_card_removed +mmc_detect_change +mmc_erase +mmc_erase_group_aligned +mmc_flush_cache +mmc_free_host +mmc_get_card +mmc_get_ext_csd +mmc_gpio_get_cd +mmc_gpio_get_ro +mmc_gpiod_request_cd +mmc_gpiod_request_cd_irq +mmc_gpiod_request_ro +mmc_hw_reset +mmc_of_parse +mmc_of_parse_voltage +mmc_put_card +mmc_register_driver +mmc_regulator_get_supply +mmc_regulator_set_ocr +mmc_regulator_set_vqmmc +mmc_release_host +mmc_remove_host +mmc_request_done +mmc_retune_pause +mmc_retune_release +mmc_retune_unpause +mmc_run_bkops +mmc_sanitize +mmc_send_status +mmc_send_tuning +mmc_set_data_timeout +mmc_start_request +mmc_switch +mmc_unregister_driver +mmc_wait_for_cmd +mmc_wait_for_req +mmput +mmu_interval_notifier_insert +mmu_interval_notifier_remove +mmu_interval_read_begin +mmu_notifier_synchronize +mod_delayed_work_on +mod_node_page_state +mod_timer +module_layout +module_put +msleep +msleep_interruptible +mutex_is_locked +mutex_lock +mutex_lock_interruptible +mutex_trylock +mutex_trylock_recursive +mutex_unlock +name_to_dev_t +names_cachep +napi_complete_done +napi_consume_skb +napi_disable +napi_gro_flush +napi_gro_receive +napi_schedule_prep +net_namespace_list +net_ratelimit +netdev_change_features +netdev_err +netdev_increment_features +netdev_info +netdev_lower_state_changed +netdev_master_upper_dev_link +netdev_notify_peers +netdev_pick_tx +netdev_rx_handler_register +netdev_rx_handler_unregister +netdev_state_change +netdev_update_features +netdev_upper_dev_link +netdev_upper_dev_unlink +netdev_warn +netif_carrier_off +netif_carrier_on +netif_device_attach +netif_device_detach +netif_napi_add +netif_receive_skb +netif_receive_skb_list +netif_rx +netif_rx_ni +netif_schedule_queue +netif_set_real_num_rx_queues +netif_set_real_num_tx_queues +netif_stacked_transfer_operstate +netif_tx_stop_all_queues +netif_tx_wake_queue +netlink_ack +netlink_broadcast +netlink_capable +netlink_has_listeners +netlink_kernel_release +netlink_register_notifier +netlink_unicast +netlink_unregister_notifier +new_inode +nf_conntrack_destroy +nla_append +nla_find +nla_memcpy +nla_put +nla_put_64bit +nla_put_nohdr +nla_reserve +nla_reserve_64bit +nla_strlcpy +no_llseek +no_seek_end_llseek +nonseekable_open +noop_llseek +nr_cpu_ids +nr_ipi_get +nr_irqs +ns_capable +ns_to_timespec64 +nsec_to_clock_t +nsecs_to_jiffies +nvdimm_bus_register +nvdimm_bus_unregister +nvdimm_pmem_region_create +nvmem_cell_get +nvmem_cell_put +nvmem_cell_read +nvmem_cell_read_u32 +nvmem_cell_write +nvmem_device_put +nvmem_device_read +nvmem_device_write +of_address_to_resource +of_alias_get_highest_id +of_alias_get_id +of_clk_add_hw_provider +of_clk_add_provider +of_clk_del_provider +of_clk_get +of_clk_get_by_name +of_clk_get_from_provider +of_clk_get_parent_count +of_clk_get_parent_name +of_clk_hw_onecell_get +of_clk_hw_simple_get +of_clk_set_defaults +of_clk_src_onecell_get +of_clk_src_simple_get +of_count_phandle_with_args +of_cpu_node_to_id +of_cpufreq_cooling_register +of_devfreq_cooling_register +of_devfreq_cooling_register_power +of_device_get_match_data +of_device_is_available +of_device_is_compatible +of_device_modalias +of_device_request_module +of_device_uevent_modalias +of_dma_configure_id +of_dma_controller_free +of_dma_controller_register +of_dma_is_coherent +of_drm_find_bridge +of_drm_find_panel +of_find_all_nodes +of_find_compatible_node +of_find_device_by_node +of_find_i2c_adapter_by_node +of_find_i2c_device_by_node +of_find_matching_node_and_match +of_find_mipi_dsi_host_by_node +of_find_node_by_name +of_find_node_by_phandle +of_find_node_by_type +of_find_node_opts_by_path +of_find_node_with_property +of_find_property +of_fwnode_ops +of_genpd_add_provider_onecell +of_genpd_add_provider_simple +of_genpd_del_provider +of_get_address +of_get_child_by_name +of_get_compatible_child +of_get_cpu_node +of_get_dma_window +of_get_named_gpio_flags +of_get_next_available_child +of_get_next_child +of_get_next_parent +of_get_parent +of_get_property +of_get_regulator_init_data +of_graph_get_endpoint_by_regs +of_graph_get_next_endpoint +of_graph_get_port_parent +of_graph_get_remote_endpoint +of_graph_get_remote_node +of_graph_get_remote_port +of_graph_get_remote_port_parent +of_graph_is_present +of_graph_parse_endpoint +of_hwspin_lock_get_id +of_i2c_get_board_info +of_icc_get +of_icc_xlate_onecell +of_iomap +of_irq_find_parent +of_irq_get +of_irq_get_byname +of_irq_parse_one +of_machine_is_compatible +of_match_device +of_match_node +of_modalias_node +of_n_addr_cells +of_n_size_cells +of_node_name_eq +of_nvmem_device_get +of_parse_phandle +of_parse_phandle_with_args +of_parse_phandle_with_fixed_args +of_phandle_iterator_init +of_phandle_iterator_next +of_phy_simple_xlate +of_platform_depopulate +of_platform_device_create +of_platform_device_destroy +of_platform_populate +of_prop_next_string +of_prop_next_u32 +of_property_count_elems_of_size +of_property_match_string +of_property_read_string +of_property_read_string_helper +of_property_read_u32_index +of_property_read_u64 +of_property_read_u64_index +of_property_read_variable_u16_array +of_property_read_variable_u32_array +of_property_read_variable_u64_array +of_property_read_variable_u8_array +of_pwm_xlate_with_flags +of_reserved_mem_device_init_by_idx +of_reserved_mem_device_release +of_reserved_mem_lookup +of_reset_control_array_get +of_root +of_thermal_get_ntrips +of_thermal_get_trip_points +of_thermal_is_trip_valid +of_translate_address +of_usb_get_phy_mode +of_usb_host_tpl_support +on_each_cpu +oops_in_progress +orderly_poweroff +overflowuid +page_endio +page_mapping +page_reporting_register +page_reporting_unregister +panic +panic_notifier_list +panic_timeout +param_array_ops +param_get_int +param_get_string +param_get_uint +param_get_ullong +param_ops_bint +param_ops_bool +param_ops_byte +param_ops_charp +param_ops_hexint +param_ops_int +param_ops_long +param_ops_short +param_ops_string +param_ops_uint +param_ops_ullong +param_ops_ulong +param_ops_ushort +param_set_bool +param_set_copystring +param_set_int +param_set_uint +part_end_io_acct +part_start_io_acct +passthru_features_check +pause_cpus +pci_alloc_irq_vectors_affinity +pci_assign_resource +pci_assign_unassigned_bus_resources +pci_bus_resource_n +pci_bus_type +pci_clear_master +pci_d3cold_disable +pci_dev_present +pci_dev_put +pci_device_group +pci_device_is_present +pci_disable_device +pci_disable_msi +pci_enable_atomic_ops_to_root +pci_enable_device +pci_enable_device_mem +pci_enable_msi +pci_enable_wake +pci_find_bus +pci_find_capability +pci_find_ext_capability +pci_find_next_capability +pci_free_irq +pci_free_irq_vectors +pci_generic_config_read +pci_generic_config_write +pci_get_device +pci_get_domain_bus_and_slot +pci_get_slot +pci_host_probe +pci_intx +pci_iomap +pci_iomap_range +pci_ioremap_bar +pci_irq_get_affinity +pci_irq_vector +pci_load_and_free_saved_state +pci_load_saved_state +pci_map_rom +pci_match_id +pci_msi_create_irq_domain +pci_msi_mask_irq +pci_msi_unmask_irq +pci_msix_vec_count +pci_read_config_byte +pci_read_config_dword +pci_read_config_word +pci_release_region +pci_release_regions +pci_release_resource +pci_release_selected_regions +pci_request_irq +pci_request_region +pci_request_regions +pci_request_selected_regions +pci_rescan_bus +pci_resize_resource +pci_restore_msi_state +pci_restore_state +pci_save_state +pci_select_bars +pci_set_master +pci_set_mwi +pci_set_power_state +pci_store_saved_state +pci_unmap_rom +pci_unregister_driver +pci_wake_from_d3 +pci_walk_bus +pci_write_config_byte +pci_write_config_dword +pci_write_config_word +pcibios_resource_to_bus +pcie_aspm_enabled +pcie_bandwidth_available +pcie_capability_read_word +pcie_capability_write_word +pcie_get_mps +pcie_get_speed_cap +pcim_enable_device +per_cpu_ptr_to_phys +percpu_down_write +percpu_ref_exit +percpu_ref_init +percpu_ref_is_zero +percpu_ref_kill_and_confirm +percpu_ref_switch_to_atomic_sync +percpu_ref_switch_to_percpu +percpu_up_write +perf_aux_output_begin +perf_aux_output_end +perf_aux_output_flag +perf_event_addr_filters_sync +perf_event_create_kernel_counter +perf_event_disable +perf_event_enable +perf_event_pause +perf_event_read_local +perf_event_read_value +perf_event_release_kernel +perf_event_update_userpage +perf_get_aux +perf_pmu_migrate_context +perf_pmu_register +perf_pmu_unregister +perf_trace_buf_alloc +perf_trace_run_bpf_submit +pfn_valid +phy_calibrate +phy_configure +phy_connect +phy_disconnect +phy_do_ioctl_running +phy_ethtool_get_link_ksettings +phy_ethtool_nway_reset +phy_ethtool_set_link_ksettings +phy_exit +phy_init +phy_pm_runtime_get_sync +phy_pm_runtime_put_sync +phy_power_off +phy_power_on +phy_print_status +phy_set_mode_ext +phy_start +phy_stop +pick_highest_pushable_task +pid_nr_ns +pid_task +pin_get_name +pin_user_pages +pin_user_pages_fast +pin_user_pages_remote +pinconf_generic_dt_free_map +pinconf_generic_dt_node_to_map +pinctrl_add_gpio_range +pinctrl_dev_get_drvdata +pinctrl_enable +pinctrl_force_default +pinctrl_force_sleep +pinctrl_get +pinctrl_lookup_state +pinctrl_pm_select_default_state +pinctrl_pm_select_idle_state +pinctrl_pm_select_sleep_state +pinctrl_put +pinctrl_remove_gpio_range +pinctrl_select_default_state +pinctrl_select_state +pinctrl_utils_free_map +pipe_lock +pipe_unlock +pktgen_xfrm_outer_mode_output +platform_add_devices +platform_bus_type +platform_device_add +platform_device_add_data +platform_device_add_properties +platform_device_add_resources +platform_device_alloc +platform_device_del +platform_device_put +platform_device_register +platform_device_register_full +platform_device_unregister +platform_driver_unregister +platform_find_device_by_driver +platform_get_irq +platform_get_irq_byname +platform_get_irq_byname_optional +platform_get_irq_optional +platform_get_resource +platform_get_resource_byname +platform_irq_count +pm_clk_add +pm_clk_create +pm_clk_destroy +pm_clk_resume +pm_clk_suspend +pm_generic_resume +pm_generic_runtime_resume +pm_generic_runtime_suspend +pm_generic_suspend +pm_genpd_add_subdomain +pm_genpd_init +pm_genpd_remove +pm_genpd_remove_subdomain +pm_power_off +pm_relax +pm_runtime_allow +pm_runtime_autosuspend_expiration +pm_runtime_barrier +pm_runtime_enable +pm_runtime_forbid +pm_runtime_force_resume +pm_runtime_force_suspend +pm_runtime_get_if_active +pm_runtime_irq_safe +pm_runtime_no_callbacks +pm_runtime_set_autosuspend_delay +pm_stay_awake +pm_suspend_global_flags +pm_system_wakeup +pm_wakeup_dev_event +pm_wakeup_ws_event +policy_has_boost_freq +power_supply_changed +power_supply_get_by_name +power_supply_get_by_phandle_array +power_supply_get_drvdata +power_supply_get_property +power_supply_is_system_supplied +power_supply_put +power_supply_reg_notifier +power_supply_register +power_supply_set_property +power_supply_unreg_notifier +power_supply_unregister +prandom_bytes +prandom_u32 +preempt_schedule +preempt_schedule_notrace +prepare_to_wait +prepare_to_wait_event +print_hex_dump +printk +printk_deferred +printk_timed_ratelimit +proc_create +proc_create_data +proc_create_single_data +proc_dointvec +proc_dointvec_minmax +proc_dostring +proc_douintvec_minmax +proc_mkdir +proc_mkdir_data +proc_remove +proc_set_size +proc_set_user +proc_symlink +proto_register +proto_unregister +ps2_begin_command +ps2_cmd_aborted +ps2_command +ps2_drain +ps2_end_command +ps2_handle_ack +ps2_handle_response +ps2_init +ps2_sendbyte +ps2_sliced_command +pskb_expand_head +pstore_register +pstore_unregister +put_device +put_disk +put_iova_domain +put_pid +put_sg_io_hdr +put_unused_fd +put_vaddr_frames +pwm_apply_state +pwm_get_chip_data +pwm_set_chip_data +pwmchip_add +pwmchip_remove +qcom_smem_state_get +qcom_smem_state_register +qcom_smem_state_unregister +qcom_smem_state_update_bits +qdisc_reset +queue_delayed_work_on +queue_work_on +radix_tree_delete +radix_tree_insert +radix_tree_iter_delete +radix_tree_iter_resume +radix_tree_lookup +radix_tree_maybe_preload +radix_tree_next_chunk +radix_tree_tagged +rational_best_approximation +raw_notifier_call_chain +raw_notifier_chain_register +raw_notifier_chain_unregister +rb_erase +rb_first +rb_first_postorder +rb_insert_color +rb_last +rb_next +rb_next_postorder +rb_prev +rb_replace_node +rcu_barrier +rcu_barrier_tasks +rcu_barrier_tasks_trace +rcu_bind_current_to_nocb +rcu_cpu_stall_suppress +rcu_cpu_stall_suppress_at_boot +rcu_expedite_gp +rcu_force_quiescent_state +rcu_fwd_progress_check +rcu_get_gp_kthreads_prio +rcu_get_gp_seq +rcu_gp_is_expedited +rcu_gp_is_normal +rcu_gp_set_torture_wait +rcu_inkernel_boot_has_ended +rcu_is_watching +rcu_jiffies_till_stall_check +rcu_read_unlock_trace_special +rcu_unexpedite_gp +rcutorture_get_gp_data +rcuwait_wake_up +rdev_get_drvdata +rdev_get_id +reboot_mode +reciprocal_value +refcount_dec_and_lock +refcount_dec_and_mutex_lock +refcount_dec_not_one +refcount_warn_saturate +refresh_frequency_limits +regcache_cache_bypass +regcache_cache_only +regcache_drop_region +regcache_mark_dirty +regcache_sync +regcache_sync_region +register_blkdev +register_chrdev_region +register_console +register_die_notifier +register_filesystem +register_ftrace_export +register_inet6addr_notifier +register_inetaddr_notifier +register_kernel_break_hook +register_kprobe +register_kretprobe +register_memory_notifier +register_module_notifier +register_net_sysctl +register_netdev +register_netdevice +register_netdevice_notifier +register_netevent_notifier +register_oom_notifier +register_pernet_device +register_pernet_subsys +register_pm_notifier +register_reboot_notifier +register_restart_handler +register_shrinker +register_syscore_ops +register_sysctl +register_sysctl_table +register_virtio_device +register_virtio_driver +register_vmap_purge_notifier +regmap_add_irq_chip +regmap_async_complete +regmap_bulk_read +regmap_bulk_write +regmap_check_range_table +regmap_del_irq_chip +regmap_exit +regmap_field_read +regmap_field_update_bits_base +regmap_get_device +regmap_irq_get_domain +regmap_irq_get_virq +regmap_mmio_detach_clk +regmap_multi_reg_write +regmap_multi_reg_write_bypassed +regmap_raw_read +regmap_raw_write +regmap_raw_write_async +regmap_read +regmap_register_patch +regmap_update_bits_base +regmap_write +regulator_allow_bypass +regulator_bulk_disable +regulator_bulk_enable +regulator_bulk_get +regulator_count_voltages +regulator_disable +regulator_disable_deferred +regulator_disable_regmap +regulator_enable +regulator_enable_regmap +regulator_force_disable +regulator_get +regulator_get_current_limit +regulator_get_drvdata +regulator_get_mode +regulator_get_optional +regulator_get_voltage +regulator_get_voltage_rdev +regulator_get_voltage_sel_regmap +regulator_is_enabled +regulator_is_enabled_regmap +regulator_is_supported_voltage +regulator_list_voltage_linear +regulator_list_voltage_linear_range +regulator_list_voltage_table +regulator_map_voltage_ascend +regulator_map_voltage_linear +regulator_notifier_call_chain +regulator_put +regulator_register +regulator_register_notifier +regulator_set_current_limit +regulator_set_load +regulator_set_mode +regulator_set_voltage +regulator_set_voltage_sel_regmap +regulator_unregister +regulator_unregister_notifier +release_firmware +release_pages +release_sock +remap_pfn_range +remap_vmalloc_range +remove_cpu +remove_memory_subsection +remove_proc_entry +remove_wait_queue +report_iommu_fault +request_any_context_irq +request_firmware +request_firmware_direct +request_firmware_into_buf +request_firmware_nowait +request_threaded_irq +resched_curr +reservation_ww_class +reset_control_assert +reset_control_deassert +reset_control_put +reset_control_reset +resume_cpus +return_address +revalidate_disk_size +rfkill_alloc +rfkill_destroy +rfkill_find_type +rfkill_init_sw_state +rfkill_register +rfkill_set_sw_state +rfkill_unregister +rhashtable_destroy +rhashtable_init +rhashtable_insert_slow +rht_bucket_nested +rht_bucket_nested_insert +rndis_deregister +rndis_free_response +rndis_get_next_response +rndis_msg_parser +rndis_register +rndis_set_host_mac +rndis_set_param_dev +rndis_set_param_medium +rndis_set_param_vendor +rndis_signal_connect +rndis_uninit +root_task_group +round_jiffies_relative +round_jiffies_up +rpmsg_get_signals +rpmsg_poll +rpmsg_register_device +rpmsg_send +rpmsg_set_signals +rpmsg_trysend +rpmsg_unregister_device +rproc_add +rproc_add_subdev +rproc_alloc +rproc_boot +rproc_coredump_add_custom_segment +rproc_coredump_add_segment +rproc_coredump_set_elf_info +rproc_coredump_using_sections +rproc_del +rproc_elf_get_boot_addr +rproc_free +rproc_get_by_child +rproc_get_by_phandle +rproc_put +rproc_remove_subdev +rproc_report_crash +rproc_shutdown +rps_needed +rt_mutex_lock +rt_mutex_trylock +rt_mutex_unlock +rtc_class_close +rtc_class_open +rtc_read_time +rtc_set_time +rtc_time64_to_tm +rtc_tm_to_time64 +rtc_update_irq +rtc_valid_tm +rtc_year_days +rtnl_is_locked +rtnl_link_register +rtnl_link_unregister +rtnl_lock +rtnl_register_module +rtnl_trylock +rtnl_unicast +rtnl_unlock +rtnl_unregister +runqueues +sb800_prefetch +sbitmap_queue_min_shallow_depth +sched_clock +sched_feat_keys +sched_feat_names +sched_set_fifo +sched_set_fifo_low +sched_set_normal +sched_setattr +sched_setattr_nocheck +sched_setscheduler +sched_setscheduler_nocheck +sched_show_task +sched_trace_cfs_rq_avg +sched_trace_cfs_rq_cpu +sched_trace_cfs_rq_path +sched_trace_rd_span +sched_trace_rq_avg_dl +sched_trace_rq_avg_irq +sched_trace_rq_avg_rt +sched_trace_rq_cpu +sched_uclamp_used +schedule +schedule_hrtimeout +schedule_timeout +schedule_timeout_interruptible +schedule_timeout_uninterruptible +scnprintf +scsi_autopm_get_device +scsi_autopm_put_device +scsi_block_requests +scsi_block_when_processing_errors +scsi_command_size_tbl +scsi_compat_ioctl +scsi_device_get +scsi_device_put +scsi_device_quiesce +scsi_eh_ready_devs +scsi_ioctl +scsi_ioctl_block_when_processing_errors +scsi_normalize_sense +scsi_print_sense_hdr +scsi_register_interface +scsi_remove_device +scsi_unblock_requests +sdev_prefix_printk +sdhci_add_host +sdhci_cleanup_host +sdhci_cqe_disable +sdhci_cqe_enable +sdhci_cqe_irq +sdhci_enable_clk +sdhci_get_property +sdhci_pltfm_free +sdhci_pltfm_init +sdhci_remove_host +sdhci_reset +sdhci_set_bus_width +sdhci_set_power_noreg +sdhci_setup_host +sdio_claim_host +sdio_disable_func +sdio_enable_func +sdio_f0_readb +sdio_f0_writeb +sdio_get_host_pm_caps +sdio_memcpy_fromio +sdio_memcpy_toio +sdio_readsb +sdio_register_driver +sdio_release_host +sdio_set_block_size +sdio_set_host_pm_flags +sdio_signal_irq +sdio_unregister_driver +sdio_writesb +securityfs_create_dir +securityfs_create_file +securityfs_remove +seq_buf_printf +seq_file_path +seq_hex_dump +seq_list_next +seq_list_start +seq_lseek +seq_open +seq_printf +seq_putc +seq_puts +seq_read +seq_release +seq_release_private +seq_vprintf +seq_write +serdev_device_close +serdev_device_open +serdev_device_set_baudrate +serdev_device_set_flow_control +serdev_device_wait_until_sent +serdev_device_write +serdev_device_write_wakeup +serio_close +serio_interrupt +serio_open +serio_reconnect +serio_rescan +serio_unregister_child_port +serio_unregister_driver +serio_unregister_port +set_blocksize +set_capacity_revalidate_and_notify +set_cpus_allowed_ptr +set_disk_ro +set_freezable +set_normalized_timespec64 +set_page_dirty +set_page_dirty_lock +set_task_cpu +set_user_nice +sg_alloc_table +sg_alloc_table_from_pages +sg_free_table +sg_init_one +sg_init_table +sg_miter_next +sg_miter_start +sg_miter_stop +sg_nents_for_len +sg_next +sg_pcopy_from_buffer +sg_pcopy_to_buffer +sg_scsi_ioctl +sg_zero_buffer +sgl_alloc +sgl_free +shmem_truncate_range +show_rcu_gp_kthreads +show_regs +si_mem_available +si_meminfo +si_swapinfo +sigprocmask +simple_attr_open +simple_attr_read +simple_attr_release +simple_attr_write +simple_dir_inode_operations +simple_dir_operations +simple_open +simple_read_from_buffer +simple_statfs +simple_strtol +simple_strtoll +simple_strtoul +simple_strtoull +simple_write_to_buffer +single_open +single_open_size +single_release +sk_alloc +sk_free +skb_add_rx_frag +skb_append_pagefrags +skb_checksum +skb_clone +skb_coalesce_rx_frag +skb_copy +skb_copy_bits +skb_copy_datagram_iter +skb_copy_expand +skb_copy_ubufs +skb_dequeue +skb_dequeue_tail +skb_ensure_writable +skb_free_datagram +skb_page_frag_refill +skb_partial_csum_set +skb_pull +skb_push +skb_put +skb_queue_head +skb_queue_purge +skb_queue_tail +skb_realloc_headroom +skb_recv_datagram +skb_set_owner_w +skb_store_bits +skb_to_sgvec +skb_trim +skb_tstamp_tx +skb_unlink +skip_spaces +smp_call_function +smp_call_function_any +smp_call_function_many +smp_call_function_single +smp_call_on_cpu +smpboot_register_percpu_thread +smpboot_unregister_percpu_thread +snd_card_disconnect +snd_card_free +snd_card_new +snd_card_register +snd_card_rw_proc_new +snd_component_add +snd_compr_stop_error +snd_ctl_add +snd_ctl_add_vmaster_hook +snd_ctl_apply_vmaster_followers +snd_ctl_boolean_mono_info +snd_ctl_boolean_stereo_info +snd_ctl_enum_info +snd_ctl_find_id +snd_ctl_make_virtual_master +snd_ctl_new1 +snd_ctl_notify +snd_ctl_remove +snd_ctl_remove_id +snd_ctl_sync_vmaster +snd_device_disconnect +snd_device_free +snd_device_new +snd_dma_alloc_pages +snd_dma_free_pages +snd_dmaengine_pcm_prepare_slave_config +snd_hwdep_new +snd_info_create_card_entry +snd_info_create_module_entry +snd_info_free_entry +snd_info_register +snd_interval_refine +snd_jack_new +snd_jack_report +snd_jack_set_key +snd_pci_quirk_lookup +snd_pcm_add_chmap_ctls +snd_pcm_alt_chmaps +snd_pcm_create_iec958_consumer_hw_params +snd_pcm_format_physical_width +snd_pcm_format_width +snd_pcm_hw_constraint_eld +snd_pcm_hw_constraint_integer +snd_pcm_hw_constraint_list +snd_pcm_hw_constraint_minmax +snd_pcm_hw_constraint_msbits +snd_pcm_hw_constraint_step +snd_pcm_hw_limit_rates +snd_pcm_hw_rule_add +snd_pcm_lib_default_mmap +snd_pcm_lib_free_pages +snd_pcm_lib_ioctl +snd_pcm_lib_malloc_pages +snd_pcm_lib_preallocate_free_for_all +snd_pcm_lib_preallocate_pages +snd_pcm_new +snd_pcm_period_elapsed +snd_pcm_rate_range_to_bits +snd_pcm_set_managed_buffer_all +snd_pcm_set_ops +snd_pcm_set_sync +snd_pcm_std_chmaps +snd_pcm_stream_lock +snd_pcm_stream_unlock +snd_pcm_stream_unlock_irqrestore +snd_soc_add_card_controls +snd_soc_add_component_controls +snd_soc_add_dai_controls +snd_soc_bytes_info_ext +snd_soc_bytes_tlv_callback +snd_soc_card_get_kcontrol +snd_soc_card_jack_new +snd_soc_component_async_complete +snd_soc_component_disable_pin +snd_soc_component_exit_regmap +snd_soc_component_force_enable_pin +snd_soc_component_init_regmap +snd_soc_component_read +snd_soc_component_set_jack +snd_soc_component_set_pll +snd_soc_component_set_sysclk +snd_soc_component_update_bits +snd_soc_component_update_bits_async +snd_soc_component_write +snd_soc_dai_get_channel_map +snd_soc_dai_link_set_capabilities +snd_soc_dai_set_bclk_ratio +snd_soc_dai_set_channel_map +snd_soc_dai_set_fmt +snd_soc_dai_set_pll +snd_soc_dai_set_sysclk +snd_soc_dai_set_tdm_slot +snd_soc_dapm_add_routes +snd_soc_dapm_disable_pin +snd_soc_dapm_disable_pin_unlocked +snd_soc_dapm_enable_pin +snd_soc_dapm_force_enable_pin +snd_soc_dapm_force_enable_pin_unlocked +snd_soc_dapm_get_enum_double +snd_soc_dapm_get_pin_status +snd_soc_dapm_get_pin_switch +snd_soc_dapm_get_volsw +snd_soc_dapm_ignore_suspend +snd_soc_dapm_info_pin_switch +snd_soc_dapm_kcontrol_dapm +snd_soc_dapm_kcontrol_widget +snd_soc_dapm_mixer_update_power +snd_soc_dapm_mux_update_power +snd_soc_dapm_new_control +snd_soc_dapm_new_controls +snd_soc_dapm_new_widgets +snd_soc_dapm_put_enum_double +snd_soc_dapm_put_pin_switch +snd_soc_dapm_put_volsw +snd_soc_dapm_sync +snd_soc_dapm_sync_unlocked +snd_soc_dapm_weak_routes +snd_soc_find_dai +snd_soc_get_enum_double +snd_soc_get_pcm_runtime +snd_soc_get_volsw +snd_soc_get_volsw_range +snd_soc_get_volsw_sx +snd_soc_get_xr_sx +snd_soc_info_enum_double +snd_soc_info_multi_ext +snd_soc_info_volsw +snd_soc_info_volsw_range +snd_soc_info_volsw_sx +snd_soc_info_xr_sx +snd_soc_jack_add_gpios +snd_soc_jack_report +snd_soc_lookup_component +snd_soc_new_compress +snd_soc_of_get_dai_link_codecs +snd_soc_of_get_dai_name +snd_soc_of_parse_audio_routing +snd_soc_of_parse_audio_simple_widgets +snd_soc_of_parse_aux_devs +snd_soc_of_parse_card_name +snd_soc_of_parse_daifmt +snd_soc_of_parse_node_prefix +snd_soc_of_parse_tdm_slot +snd_soc_of_put_dai_link_codecs +snd_soc_params_to_bclk +snd_soc_params_to_frame_size +snd_soc_pm_ops +snd_soc_put_enum_double +snd_soc_put_volsw +snd_soc_put_volsw_range +snd_soc_put_volsw_sx +snd_soc_put_xr_sx +snd_soc_register_card +snd_soc_register_component +snd_soc_rtdcom_lookup +snd_soc_runtime_calc_hw +snd_soc_runtime_set_dai_fmt +snd_soc_set_runtime_hwparams +snd_soc_tplg_component_load +snd_soc_tplg_component_remove +snd_soc_tplg_widget_bind_event +snd_soc_unregister_card +snd_soc_unregister_component +snd_usb_enable_audio_stream +snd_vendor_set_ops +snprintf +soc_device_register +soc_device_unregister +sock_alloc_send_skb +sock_create_kern +sock_gettstamp +sock_i_uid +sock_init_data +sock_no_accept +sock_no_listen +sock_no_mmap +sock_no_sendpage +sock_no_shutdown +sock_no_socketpair +sock_queue_rcv_skb +sock_register +sock_release +sock_setsockopt +sock_unregister +sock_wfree +softnet_data +sort +spi_bus_lock +spi_bus_type +spi_bus_unlock +spi_controller_resume +spi_controller_suspend +spi_delay_exec +spi_finalize_current_message +spi_finalize_current_transfer +spi_get_next_queued_message +spi_register_controller +spi_setup +spi_sync +spi_sync_locked +spi_unregister_controller +split_page +spmi_controller_add +spmi_controller_alloc +spmi_controller_remove +spmi_ext_register_read +spmi_ext_register_readl +spmi_ext_register_write +spmi_ext_register_writel +spmi_register_read +spmi_register_write +spmi_register_zero_write +sprint_symbol +sprintf +srcu_barrier +srcu_batches_completed +srcu_init_notifier_head +srcu_notifier_call_chain +srcu_notifier_chain_register +srcu_notifier_chain_unregister +srcu_torture_stats_print +srcutorture_get_gp_data +sscanf +stack_trace_print +stack_trace_save +stack_trace_save_tsk +static_key_disable +static_key_disable_cpuslocked +static_key_slow_dec +static_key_slow_inc +stop_machine +stop_one_cpu_nowait +stpcpy +strcasecmp +strcat +strchr +strchrnul +strcmp +strcpy +strcspn +stream_open +strim +string_get_size +strlcat +strlcpy +strlen +strncasecmp +strncat +strnchr +strncmp +strncpy +strncpy_from_user +strndup_user +strnlen +strnstr +strpbrk +strrchr +strreplace +strscpy +strsep +strspn +strstr +submit_bh +submit_bio +submit_bio_wait +subsys_system_register +swiotlb_nr_tbl +sync_blockdev +sync_file_create +sync_file_get_fence +synchronize_irq +synchronize_net +synchronize_rcu +synchronize_rcu_expedited +synchronize_rcu_tasks +synchronize_rcu_tasks_trace +synchronize_srcu +synchronize_srcu_expedited +sys_tz +syscon_node_to_regmap +syscon_regmap_lookup_by_phandle +sysctl_sched_features +sysctl_sched_latency +sysctl_vals +sysfs_add_file_to_group +sysfs_add_link_to_group +sysfs_create_bin_file +sysfs_create_file_ns +sysfs_create_files +sysfs_create_group +sysfs_create_groups +sysfs_create_link +sysfs_emit +sysfs_emit_at +sysfs_notify +sysfs_remove_bin_file +sysfs_remove_file_from_group +sysfs_remove_file_ns +sysfs_remove_files +sysfs_remove_group +sysfs_remove_groups +sysfs_remove_link +sysfs_remove_link_from_group +sysfs_streq +sysfs_update_group +sysrq_mask +system_freezable_wq +system_freezing_cnt +system_highpri_wq +system_long_wq +system_power_efficient_wq +system_state +system_unbound_wq +system_wq +task_active_pid_ns +task_groups +task_may_not_preempt +task_rq_lock +tasklet_init +tasklet_kill +tasklet_setup +tasklist_lock +tcpci_get_tcpm_port +tcpci_irq +tcpci_register_port +tcpci_unregister_port +tcpm_cc_change +tcpm_is_toggling +tcpm_pd_hard_reset +tcpm_pd_receive +tcpm_pd_transmit_complete +tcpm_sink_frs +tcpm_sourcing_vbus +tcpm_update_sink_capabilities +tcpm_vbus_change +thermal_cdev_update +thermal_cooling_device_register +thermal_cooling_device_unregister +thermal_of_cooling_device_register +thermal_pressure +thermal_zone_device_disable +thermal_zone_device_enable +thermal_zone_device_is_enabled +thermal_zone_device_register +thermal_zone_device_unregister +thermal_zone_device_update +thermal_zone_get_slope +thermal_zone_get_temp +thermal_zone_get_zone_by_name +thermal_zone_of_sensor_register +thermal_zone_of_sensor_unregister +thread_group_cputime_adjusted +tick_nohz_get_idle_calls_cpu +tick_nohz_get_sleep_length +time64_to_tm +timecounter_init +timecounter_read +timer_unstable_counter_workaround +topology_set_thermal_pressure +total_swapcache_pages +trace_clock_local +trace_event_buffer_commit +trace_event_buffer_reserve +trace_event_ignore_this_pid +trace_event_raw_init +trace_event_reg +trace_handle_return +trace_output_call +trace_print_array_seq +trace_print_flags_seq +trace_print_hex_seq +trace_print_symbols_seq +trace_raw_output_prep +trace_seq_printf +trace_seq_putc +tracepoint_probe_register +tracepoint_probe_register_prio +tracepoint_probe_unregister +tracing_off +try_module_get +try_to_del_timer_sync +try_wait_for_completion +ttm_bo_bulk_move_lru_tail +ttm_bo_device_init +ttm_bo_device_release +ttm_bo_dma_acc_size +ttm_bo_evict_mm +ttm_bo_eviction_valuable +ttm_bo_glob +ttm_bo_init_reserved +ttm_bo_kmap +ttm_bo_kunmap +ttm_bo_lock_delayed_workqueue +ttm_bo_mem_space +ttm_bo_mmap +ttm_bo_mmap_obj +ttm_bo_move_accel_cleanup +ttm_bo_move_memcpy +ttm_bo_move_to_lru_tail +ttm_bo_move_ttm +ttm_bo_put +ttm_bo_unlock_delayed_workqueue +ttm_bo_validate +ttm_dma_page_alloc_debugfs +ttm_dma_populate +ttm_dma_tt_fini +ttm_dma_unpopulate +ttm_eu_backoff_reservation +ttm_eu_fence_buffer_objects +ttm_eu_reserve_buffers +ttm_page_alloc_debugfs +ttm_populate_and_map_pages +ttm_range_man_fini +ttm_range_man_init +ttm_resource_free +ttm_resource_manager_force_list_clean +ttm_resource_manager_init +ttm_sg_tt_init +ttm_tt_destroy_common +ttm_tt_populate +ttm_tt_set_placement_caching +ttm_unmap_and_unpopulate_pages +tty_flip_buffer_push +tty_insert_flip_string_fixed_flag +tty_kref_put +tty_port_tty_get +tty_termios_baud_rate +tty_termios_encode_baud_rate +typec_altmode_get_partner +typec_altmode_update_active +typec_get_drvdata +typec_partner_register_altmode +typec_port_register_altmode +typec_register_partner +typec_register_port +typec_set_data_role +typec_set_pwr_opmode +typec_set_pwr_role +typec_switch_get_drvdata +typec_switch_register +typec_switch_unregister +typec_unregister_altmode +typec_unregister_partner +typec_unregister_port +uart_add_one_port +uart_console_device +uart_console_write +uart_get_baud_rate +uart_insert_char +uart_parse_options +uart_register_driver +uart_remove_one_port +uart_resume_port +uart_set_options +uart_suspend_port +uart_try_toggle_sysrq +uart_unregister_driver +uart_update_timeout +uart_write_wakeup +uclamp_eff_value +ucsi_connector_change +ucsi_create +ucsi_destroy +ucsi_get_drvdata +ucsi_register +ucsi_set_drvdata +ucsi_unregister +udp4_hwcsum +ufshcd_auto_hibern8_update +ufshcd_bkops_ctrl +ufshcd_dme_get_attr +ufshcd_dme_set_attr +ufshcd_dump_regs +ufshcd_fixup_dev_quirks +ufshcd_get_local_unipro_ver +ufshcd_get_pwr_dev_param +ufshcd_hold +ufshcd_map_desc_id_to_length +ufshcd_pltfrm_init +ufshcd_pltfrm_resume +ufshcd_pltfrm_runtime_idle +ufshcd_pltfrm_runtime_resume +ufshcd_pltfrm_runtime_suspend +ufshcd_pltfrm_shutdown +ufshcd_pltfrm_suspend +ufshcd_query_attr +ufshcd_query_attr_retry +ufshcd_query_descriptor_retry +ufshcd_query_flag +ufshcd_query_flag_retry +ufshcd_read_desc_param +ufshcd_release +ufshcd_remove +ufshcd_shutdown +ufshcd_system_resume +ufshcd_system_suspend +ufshcd_uic_hibern8_enter +ufshcd_uic_hibern8_exit +uio_unregister_device +unlock_page +unmap_mapping_range +unpin_user_page +unregister_blkdev +unregister_chrdev_region +unregister_console +unregister_die_notifier +unregister_filesystem +unregister_ftrace_export +unregister_inet6addr_notifier +unregister_inetaddr_notifier +unregister_kprobe +unregister_kretprobe +unregister_module_notifier +unregister_netdev +unregister_netdevice_many +unregister_netdevice_notifier +unregister_netdevice_queue +unregister_netevent_notifier +unregister_oom_notifier +unregister_pernet_device +unregister_pernet_subsys +unregister_pm_notifier +unregister_reboot_notifier +unregister_restart_handler +unregister_rpmsg_driver +unregister_shrinker +unregister_syscore_ops +unregister_sysctl_table +unregister_virtio_device +unregister_virtio_driver +unregister_vmap_purge_notifier +up +up_read +up_write +update_devfreq +update_rq_clock +usb_add_function +usb_add_gadget +usb_add_gadget_udc +usb_add_hcd +usb_add_phy_dev +usb_alloc_coherent +usb_alloc_dev +usb_alloc_urb +usb_amd_dev_put +usb_amd_prefetch_quirk +usb_amd_pt_check_port +usb_amd_quirk_pll_check +usb_amd_quirk_pll_disable +usb_amd_quirk_pll_enable +usb_asmedia_modifyflowcontrol +usb_assign_descriptors +usb_autopm_get_interface +usb_autopm_put_interface +usb_bulk_msg +usb_calc_bus_time +usb_choose_configuration +usb_composite_setup_continue +usb_control_msg +usb_copy_descriptors +usb_create_hcd +usb_debug_root +usb_decode_ctrl +usb_del_gadget_udc +usb_deregister +usb_disable_xhci_ports +usb_disabled +usb_enable_autosuspend +usb_enable_intel_xhci_ports +usb_ep_alloc_request +usb_ep_autoconfig +usb_ep_clear_halt +usb_ep_dequeue +usb_ep_disable +usb_ep_enable +usb_ep_fifo_flush +usb_ep_fifo_status +usb_ep_free_request +usb_ep_queue +usb_ep_set_halt +usb_ep_set_maxpacket_limit +usb_find_common_endpoints +usb_free_all_descriptors +usb_free_coherent +usb_free_urb +usb_function_register +usb_function_unregister +usb_gadget_giveback_request +usb_gadget_map_request_by_dev +usb_gadget_probe_driver +usb_gadget_set_state +usb_gadget_udc_reset +usb_gadget_unmap_request_by_dev +usb_gadget_unregister_driver +usb_gadget_vbus_connect +usb_gadget_vbus_disconnect +usb_gadget_vbus_draw +usb_gadget_wakeup +usb_get_dr_mode +usb_get_gadget_udc_name +usb_get_maximum_speed +usb_get_urb +usb_gstrings_attach +usb_hc_died +usb_hcd_check_unlink_urb +usb_hcd_end_port_resume +usb_hcd_giveback_urb +usb_hcd_irq +usb_hcd_is_primary_hcd +usb_hcd_link_urb_to_ep +usb_hcd_map_urb_for_dma +usb_hcd_pci_pm_ops +usb_hcd_pci_probe +usb_hcd_pci_remove +usb_hcd_pci_shutdown +usb_hcd_platform_shutdown +usb_hcd_poll_rh_status +usb_hcd_resume_root_hub +usb_hcd_start_port_resume +usb_hcd_unlink_urb_from_ep +usb_hcds_loaded +usb_hub_clear_tt_buffer +usb_hub_find_child +usb_ifnum_to_if +usb_initialize_gadget +usb_interface_id +usb_kill_urb +usb_otg_state_string +usb_phy_set_charger_current +usb_poison_urb +usb_put_dev +usb_put_function_instance +usb_put_hcd +usb_register_driver +usb_register_notify +usb_remove_hcd +usb_remove_phy +usb_role_switch_find_by_fwnode +usb_role_switch_get +usb_role_switch_get_drvdata +usb_role_switch_put +usb_role_switch_register +usb_role_switch_set_role +usb_role_switch_unregister +usb_root_hub_lost_power +usb_set_device_state +usb_speed_string +usb_string_id +usb_submit_urb +usb_unregister_notify +usb_wakeup_notification +usbnet_change_mtu +usbnet_disconnect +usbnet_get_drvinfo +usbnet_get_endpoints +usbnet_get_link +usbnet_get_link_ksettings +usbnet_get_msglevel +usbnet_get_stats64 +usbnet_link_change +usbnet_nway_reset +usbnet_open +usbnet_probe +usbnet_read_cmd +usbnet_read_cmd_nopm +usbnet_resume +usbnet_set_link_ksettings +usbnet_set_msglevel +usbnet_skb_return +usbnet_start_xmit +usbnet_stop +usbnet_suspend +usbnet_tx_timeout +usbnet_unlink_rx_urbs +usbnet_update_max_qlen +usbnet_write_cmd +usbnet_write_cmd_async +usbnet_write_cmd_nopm +usleep_range +uuid_gen +uuid_null +uuid_parse +v4l2_compat_ioctl32 +v4l2_ctrl_find +v4l2_ctrl_handler_free +v4l2_ctrl_handler_init_class +v4l2_ctrl_handler_setup +v4l2_ctrl_log_status +v4l2_ctrl_new_custom +v4l2_ctrl_new_std +v4l2_ctrl_new_std_menu +v4l2_device_register +v4l2_device_register_subdev +v4l2_device_set_name +v4l2_device_unregister +v4l2_device_unregister_subdev +v4l2_event_dequeue +v4l2_event_pending +v4l2_event_queue +v4l2_event_queue_fh +v4l2_event_subscribe +v4l2_event_unsubscribe +v4l2_fh_add +v4l2_fh_del +v4l2_fh_exit +v4l2_fh_init +v4l2_fh_open +v4l2_fh_release +v4l2_i2c_subdev_init +v4l2_m2m_buf_queue +v4l2_m2m_buf_remove +v4l2_m2m_ctx_init +v4l2_m2m_ctx_release +v4l2_m2m_dqbuf +v4l2_m2m_fop_mmap +v4l2_m2m_fop_poll +v4l2_m2m_get_curr_priv +v4l2_m2m_get_vq +v4l2_m2m_init +v4l2_m2m_ioctl_dqbuf +v4l2_m2m_ioctl_querybuf +v4l2_m2m_ioctl_reqbufs +v4l2_m2m_ioctl_streamoff +v4l2_m2m_ioctl_streamon +v4l2_m2m_job_finish +v4l2_m2m_mmap +v4l2_m2m_next_buf +v4l2_m2m_poll +v4l2_m2m_qbuf +v4l2_m2m_querybuf +v4l2_m2m_release +v4l2_m2m_reqbufs +v4l2_m2m_streamoff +v4l2_m2m_streamon +v4l2_m2m_try_schedule +v4l2_s_ctrl +v4l2_subdev_call_wrappers +v4l2_subdev_init +v4l_bound_align_image +vabits_actual +vb2_buffer_done +vb2_common_vm_ops +vb2_create_framevec +vb2_destroy_framevec +vb2_dqbuf +vb2_fop_mmap +vb2_fop_poll +vb2_fop_read +vb2_fop_release +vb2_ioctl_create_bufs +vb2_ioctl_dqbuf +vb2_ioctl_expbuf +vb2_ioctl_qbuf +vb2_ioctl_querybuf +vb2_ioctl_reqbufs +vb2_ioctl_streamoff +vb2_ioctl_streamon +vb2_mmap +vb2_ops_wait_finish +vb2_ops_wait_prepare +vb2_plane_cookie +vb2_plane_vaddr +vb2_poll +vb2_prepare_buf +vb2_qbuf +vb2_querybuf +vb2_queue_init +vb2_queue_release +vb2_reqbufs +vb2_streamoff +vb2_streamon +vb2_vmalloc_memops +vb2_wait_for_all_buffers +vchan_dma_desc_free_list +vchan_find_desc +vchan_init +vchan_tx_desc_free +vchan_tx_submit +vfree +vfs_fsync_range +video_devdata +video_device_alloc +video_device_release +video_device_release_empty +video_ioctl2 +video_unregister_device +virtio_check_driver_offered_feature +virtio_config_changed +virtio_device_freeze +virtio_device_restore +virtio_max_dma_size +virtio_transport_connect +virtio_transport_deliver_tap_pkt +virtio_transport_destruct +virtio_transport_dgram_allow +virtio_transport_dgram_bind +virtio_transport_dgram_dequeue +virtio_transport_dgram_enqueue +virtio_transport_do_socket_init +virtio_transport_free_pkt +virtio_transport_notify_buffer_size +virtio_transport_notify_poll_in +virtio_transport_notify_poll_out +virtio_transport_notify_recv_init +virtio_transport_notify_recv_post_dequeue +virtio_transport_notify_recv_pre_block +virtio_transport_notify_recv_pre_dequeue +virtio_transport_notify_send_init +virtio_transport_notify_send_post_enqueue +virtio_transport_notify_send_pre_block +virtio_transport_notify_send_pre_enqueue +virtio_transport_recv_pkt +virtio_transport_release +virtio_transport_shutdown +virtio_transport_stream_allow +virtio_transport_stream_dequeue +virtio_transport_stream_enqueue +virtio_transport_stream_has_data +virtio_transport_stream_has_space +virtio_transport_stream_is_active +virtio_transport_stream_rcvhiwat +virtqueue_add_inbuf +virtqueue_add_inbuf_ctx +virtqueue_add_outbuf +virtqueue_add_sgs +virtqueue_detach_unused_buf +virtqueue_disable_cb +virtqueue_enable_cb +virtqueue_enable_cb_delayed +virtqueue_enable_cb_prepare +virtqueue_get_avail_addr +virtqueue_get_buf +virtqueue_get_buf_ctx +virtqueue_get_desc_addr +virtqueue_get_used_addr +virtqueue_get_vring_size +virtqueue_is_broken +virtqueue_kick +virtqueue_kick_prepare +virtqueue_notify +virtqueue_poll +vm_event_states +vm_get_page_prot +vm_insert_page +vm_iomap_memory +vm_map_pages +vm_map_ram +vm_mmap +vm_munmap +vm_node_stat +vm_unmap_ram +vm_zone_stat +vmalloc +vmalloc_nr_pages +vmalloc_to_page +vmalloc_to_pfn +vmalloc_user +vmap +vmemdup_user +vmf_insert_mixed +vmf_insert_pfn +vmf_insert_pfn_prot +vprintk +vring_create_virtqueue +vring_del_virtqueue +vring_interrupt +vring_new_virtqueue +vring_transport_features +vscnprintf +vsnprintf +vsock_core_register +vsock_core_unregister +vsock_for_each_connected_socket +vsprintf +vunmap +vzalloc +vzalloc_node +wait_for_completion +wait_for_completion_interruptible +wait_for_completion_interruptible_timeout +wait_for_completion_io_timeout +wait_for_completion_killable +wait_for_completion_killable_timeout +wait_for_completion_timeout +wait_woken +wake_up_if_idle +wake_up_process +wakeup_source_add +wakeup_source_create +wakeup_source_destroy +wakeup_source_register +wakeup_source_remove +wakeup_source_unregister +watchdog_init_timeout +watchdog_register_device +watchdog_set_restart_priority +watchdog_unregister_device +wireless_send_event +woken_wake_function +work_busy +ww_mutex_lock +ww_mutex_lock_interruptible +ww_mutex_unlock +xa_destroy +xa_erase +xa_find +xa_find_after +xa_load +xa_store +xdp_convert_zc_to_xdp_frame +xdp_do_flush +xdp_do_redirect +xdp_return_frame +xdp_return_frame_rx_napi +xdp_rxq_info_reg +xdp_rxq_info_reg_mem_model +xdp_rxq_info_unreg +xdp_warn +xfrm_state_lookup_byspi +xfrm_stateonly_find +xhci_add_endpoint +xhci_address_device +xhci_alloc_command +xhci_alloc_erst +xhci_check_trb_in_td_math +xhci_free_command +xhci_free_erst +xhci_gen_setup +xhci_get_endpoint_index +xhci_get_ep_ctx +xhci_get_slot_ctx +xhci_handle_event +xhci_init_driver +xhci_initialize_ring_info +xhci_link_segments +xhci_queue_stop_endpoint +xhci_resume +xhci_ring_alloc +xhci_ring_cmd_db +xhci_ring_free +xhci_run +xhci_segment_free +xhci_suspend +xhci_trb_virt_to_dma +xhci_update_erst_dequeue +xhci_vendor_get_ops +zone_watermark_ok +zone_watermark_ok_safe diff --git a/android/abi_gki_aarch64_generic b/android/abi_gki_aarch64_generic index b040326ef571..f7b519e42ac4 100644 --- a/android/abi_gki_aarch64_generic +++ b/android/abi_gki_aarch64_generic @@ -24,6 +24,8 @@ amba_driver_unregister android_rvh_probe_register anon_inode_getfd + arc4_crypt + arc4_setkey __arch_clear_user __arch_copy_from_user __arch_copy_in_user @@ -66,6 +68,7 @@ blkdev_put blk_execute_rq_nowait blk_get_request + blk_ksm_init_passthrough blk_put_request blk_queue_flag_clear blk_queue_flag_set @@ -105,6 +108,7 @@ bus_unregister bus_unregister_notifier cache_line_size + call_rcu cancel_delayed_work cancel_delayed_work_sync cancel_work_sync @@ -115,35 +119,6 @@ cdev_device_add cdev_device_del cdev_init - __cfg80211_alloc_event_skb - __cfg80211_alloc_reply_skb - cfg80211_chandef_create - cfg80211_ch_switch_notify - cfg80211_connect_done - cfg80211_del_sta_sinfo - cfg80211_disconnected - cfg80211_external_auth_request - cfg80211_find_elem_match - cfg80211_get_bss - cfg80211_ibss_joined - cfg80211_inform_bss_frame_data - cfg80211_mgmt_tx_status - cfg80211_michael_mic_failure - cfg80211_new_sta - cfg80211_port_authorized - cfg80211_put_bss - cfg80211_ready_on_channel - cfg80211_remain_on_channel_expired - cfg80211_roamed - cfg80211_rx_mgmt_khz - cfg80211_scan_done - cfg80211_sched_scan_results - cfg80211_sched_scan_stopped - cfg80211_sched_scan_stopped_rtnl - __cfg80211_send_event_skb - cfg80211_unlink_bss - cfg80211_unregister_wdev - cfg80211_vendor_cmd_reply __cfi_slowpath __check_object_size __class_create @@ -254,6 +229,8 @@ cpus_read_lock cpus_read_unlock cpu_subsys + crc32_be + crc32_le crc8 crc8_populate_msb crypto_aead_decrypt @@ -263,19 +240,24 @@ crypto_alloc_aead crypto_alloc_base crypto_alloc_shash + crypto_alloc_skcipher crypto_alloc_sync_skcipher crypto_comp_compress crypto_comp_decompress crypto_destroy_tfm + __crypto_memneq crypto_register_alg crypto_register_scomp crypto_shash_digest crypto_shash_finup crypto_shash_setkey + crypto_shash_update + crypto_skcipher_decrypt crypto_skcipher_encrypt crypto_skcipher_setkey crypto_unregister_alg crypto_unregister_scomp + __crypto_xor csum_ipv6_magic csum_tcpudp_nofold _ctype @@ -293,6 +275,7 @@ debugfs_create_x32 debugfs_lookup debugfs_remove + debugfs_rename dec_zone_page_state default_llseek deferred_free @@ -302,11 +285,14 @@ del_timer_sync desc_to_gpio destroy_workqueue + dev_alloc_name + dev_change_net_namespace dev_close _dev_crit dev_driver_string _dev_emerg _dev_err + dev_fetch_sw_netstats devfreq_add_device devfreq_add_governor devfreq_monitor_resume @@ -319,12 +305,16 @@ devfreq_unregister_opp_notifier devfreq_update_interval dev_fwnode + __dev_get_by_index + dev_get_by_index dev_get_by_name + device_add device_add_disk device_add_groups device_create device_create_file device_create_with_groups + device_del device_destroy device_find_child device_for_each_child @@ -340,6 +330,7 @@ device_register device_remove_file device_remove_groups + device_rename device_set_wakeup_capable device_set_wakeup_enable device_unregister @@ -419,6 +410,8 @@ devm_thermal_zone_of_sensor_unregister devm_usb_get_phy_by_phandle _dev_notice + dev_pm_domain_attach_by_name + dev_pm_domain_detach dev_pm_opp_add dev_pm_opp_disable dev_pm_opp_find_freq_ceil @@ -435,6 +428,7 @@ dev_pm_opp_set_regulators dev_pm_qos_read_value dev_pm_qos_update_request + dev_printk dev_printk_emit dev_queue_xmit devres_add @@ -552,6 +546,7 @@ __drm_atomic_helper_crtc_destroy_state __drm_atomic_helper_crtc_duplicate_state __drm_atomic_helper_crtc_reset + drm_atomic_helper_disable_all drm_atomic_helper_disable_plane drm_atomic_helper_duplicate_state drm_atomic_helper_fake_vblank @@ -572,8 +567,11 @@ drm_atomic_normalize_zpos drm_atomic_private_obj_fini drm_atomic_private_obj_init + drm_atomic_set_crtc_for_connector drm_atomic_set_crtc_for_plane drm_atomic_set_fb_for_plane + drm_atomic_set_mode_for_crtc + drm_atomic_set_mode_prop_for_crtc drm_atomic_state_alloc drm_atomic_state_clear __drm_atomic_state_free @@ -641,10 +639,12 @@ drmm_mode_config_init drm_mode_config_reset drm_mode_convert_to_umode + drm_mode_copy drm_mode_duplicate drm_mode_equal drm_mode_equal_no_clocks drm_mode_object_find + drm_mode_object_get drm_mode_object_put drm_mode_probed_add drm_modeset_acquire_fini @@ -714,6 +714,9 @@ emergency_restart enable_irq enable_percpu_irq + ether_setup + eth_mac_addr + ethtool_op_get_link eth_type_trans eventfd_ctx_fdget eventfd_ctx_put @@ -743,6 +746,7 @@ find_vma finish_wait flush_dcache_page + flush_delayed_work flush_work flush_workqueue fput @@ -769,6 +773,7 @@ generic_file_llseek generic_handle_irq generic_iommu_put_resv_regions + genlmsg_multicast_allns genlmsg_put genl_register_family genl_unregister_family @@ -787,6 +792,8 @@ get_device __get_free_pages get_governor_parent_kobj + get_net_ns_by_fd + get_net_ns_by_pid get_pid_task get_random_bytes get_random_bytes_arch @@ -854,6 +861,9 @@ hrtimer_sleeper_start_expires hrtimer_start_range_ns hrtimer_try_to_cancel + __hw_addr_init + __hw_addr_sync + __hw_addr_unsync hwrng_register hwrng_unregister i2c_adapter_type @@ -882,16 +892,15 @@ idr_destroy idr_find idr_for_each + idr_get_next idr_preload idr_remove - ieee80211_channel_to_freq_khz - ieee80211_freq_khz_to_channel - ieee80211_get_channel_khz iio_device_unregister import_iovec in6_pton in_aton inc_zone_page_state + inet_csk_get_port init_dummy_netdev init_net init_pseudo @@ -899,6 +908,7 @@ __init_swait_queue_head init_task init_timer_key + init_uts_ns init_wait_entry __init_waitqueue_head input_allocate_device @@ -987,9 +997,14 @@ kasprintf kernel_cpustat kernel_kobj + kernel_param_lock + kernel_param_unlock kernel_restart kern_mount kern_unmount + key_create_or_update + key_put + keyring_alloc __kfifo_alloc __kfifo_free __kfifo_in @@ -998,6 +1013,7 @@ kfree kfree_sensitive kfree_skb + kfree_skb_list kill_anon_super kill_fasync kimage_voffset @@ -1053,11 +1069,13 @@ kthread_stop kthread_worker_fn ktime_get + ktime_get_coarse_with_offset ktime_get_mono_fast_ns ktime_get_raw ktime_get_raw_ts64 ktime_get_real_seconds ktime_get_real_ts64 + ktime_get_seconds ktime_get_ts64 ktime_get_with_offset kvfree @@ -1076,6 +1094,8 @@ log_threaded_irq_wakeup_reason __log_write_mmio loops_per_jiffy + lru_cache_disable + lru_cache_enable lzo1x_1_compress lzo1x_decompress_safe lzorle1x_1_compress @@ -1143,19 +1163,31 @@ __napi_schedule napi_schedule_prep __netdev_alloc_skb + netdev_err + netdev_info + netdev_set_default_ethtool_ops netdev_state_change netdev_update_features + netif_carrier_off + netif_carrier_on netif_napi_add __netif_napi_del netif_receive_skb + netif_receive_skb_list netif_rx netif_rx_ni + netif_tx_stop_all_queues netif_tx_wake_queue + netlink_broadcast __netlink_kernel_create netlink_kernel_release + netlink_register_notifier netlink_unicast + netlink_unregister_notifier + net_ns_type_operations net_ratelimit nla_append + nla_find nla_memcpy __nla_parse nla_put @@ -1163,6 +1195,7 @@ nla_put_nohdr nla_reserve nla_strlcpy + __nla_validate __nlmsg_put no_llseek nonseekable_open @@ -1311,6 +1344,7 @@ phy_init phy_power_off phy_power_on + pid_task pinconf_generic_dt_free_map pinconf_generic_dt_node_to_map pinctrl_add_gpio_range @@ -1397,9 +1431,12 @@ proc_remove pskb_expand_head __pskb_pull_tail + ___pskb_trim put_device put_disk + __put_net __put_page + put_pid put_sg_io_hdr __put_task_struct put_unused_fd @@ -1436,6 +1473,7 @@ rb_next rb_prev rb_replace_node + rcu_barrier __rcu_read_lock __rcu_read_unlock rdev_get_drvdata @@ -1457,6 +1495,8 @@ register_netdev register_netdevice register_netdevice_notifier + register_oom_notifier + register_pernet_device register_pernet_subsys register_pm_notifier register_reboot_notifier @@ -1500,7 +1540,6 @@ regulator_set_voltage regulator_set_voltage_sel_regmap regulator_unregister - regulatory_hint release_firmware __release_region remap_pfn_range @@ -1517,11 +1556,24 @@ return_address revalidate_disk_size rfkill_alloc + rfkill_blocked rfkill_destroy rfkill_init_sw_state + rfkill_pause_polling rfkill_register + rfkill_resume_polling + rfkill_set_hw_state rfkill_unregister + rhashtable_free_and_destroy + rhashtable_insert_slow + rhltable_init + __rht_bucket_nested + rht_bucket_nested + rht_bucket_nested_insert root_task_group + round_jiffies + round_jiffies_relative + round_jiffies_up rps_needed rtc_class_close rtc_class_open @@ -1611,10 +1663,20 @@ single_open single_open_size single_release + skb_add_rx_frag skb_checksum + skb_checksum_help skb_clone + skb_clone_sk + skb_complete_wifi_ack skb_copy + skb_copy_bits + skb_copy_expand skb_dequeue + skb_dequeue_tail + skb_ensure_writable + __skb_get_hash + __skb_gso_segment skb_pull skb_push skb_put @@ -1704,6 +1766,8 @@ snd_soc_unregister_component snprintf soc_device_register + __sock_create + sock_release sock_wfree softnet_data sort @@ -1729,6 +1793,7 @@ sscanf __stack_chk_fail __stack_chk_guard + static_key_disable static_key_slow_dec static_key_slow_inc stop_machine @@ -1761,14 +1826,17 @@ submit_bio submit_bio_wait subsys_system_register + __sw_hweight16 __sw_hweight32 __sw_hweight64 + __sw_hweight8 sync_file_create sync_file_get_fence synchronize_irq synchronize_net synchronize_rcu syscon_regmap_lookup_by_phandle + sysctl_sched_features sysctl_sched_latency sysfs_add_file_to_group sysfs_create_file_ns @@ -1786,6 +1854,7 @@ sysfs_streq sysfs_update_group sysrq_mask + system_freezable_wq system_freezing_cnt system_highpri_wq system_long_wq @@ -1829,6 +1898,7 @@ time64_to_tm topology_set_thermal_pressure _totalram_pages + __trace_bputs trace_event_buffer_commit trace_event_buffer_reserve trace_event_ignore_this_pid @@ -1843,14 +1913,17 @@ __traceiter_android_rvh_find_energy_efficient_cpu __traceiter_android_rvh_irqs_disable __traceiter_android_rvh_irqs_enable + __traceiter_android_rvh_pci_d3_sleep __traceiter_android_rvh_post_init_entity_util_avg __traceiter_android_rvh_preempt_disable __traceiter_android_rvh_preempt_enable + __traceiter_android_rvh_sched_fork __traceiter_android_rvh_select_task_rq_rt __traceiter_android_rvh_set_iowait __traceiter_android_rvh_typec_tcpci_chk_contaminant __traceiter_android_rvh_typec_tcpci_get_vbus __traceiter_android_rvh_uclamp_eff_get + __traceiter_android_rvh_ufs_reprogram_all_keys __traceiter_android_rvh_util_est_update __traceiter_android_vh_arch_set_freq_scale __traceiter_android_vh_cma_alloc_finish @@ -1865,6 +1938,9 @@ __traceiter_android_vh_of_i2c_get_board_info __traceiter_android_vh_pagecache_get_page __traceiter_android_vh_rmqueue + __traceiter_android_vh_setscheduler_uclamp + __traceiter_android_vh_snd_compr_use_pause_in_drain + __traceiter_android_vh_sound_usb_support_cpu_suspend __traceiter_android_vh_thermal_pm_notify_suspend __traceiter_android_vh_timerfd_create __traceiter_android_vh_typec_store_partner_src_caps @@ -1887,6 +1963,8 @@ __traceiter_dwc3_readl __traceiter_dwc3_writel __traceiter_gpu_mem_total + __traceiter_mm_vmscan_direct_reclaim_begin + __traceiter_mm_vmscan_direct_reclaim_end __traceiter_pelt_cfs_tp __traceiter_pelt_dl_tp __traceiter_pelt_irq_tp @@ -1910,14 +1988,17 @@ __tracepoint_android_rvh_find_energy_efficient_cpu __tracepoint_android_rvh_irqs_disable __tracepoint_android_rvh_irqs_enable + __tracepoint_android_rvh_pci_d3_sleep __tracepoint_android_rvh_post_init_entity_util_avg __tracepoint_android_rvh_preempt_disable __tracepoint_android_rvh_preempt_enable + __tracepoint_android_rvh_sched_fork __tracepoint_android_rvh_select_task_rq_rt __tracepoint_android_rvh_set_iowait __tracepoint_android_rvh_typec_tcpci_chk_contaminant __tracepoint_android_rvh_typec_tcpci_get_vbus __tracepoint_android_rvh_uclamp_eff_get + __tracepoint_android_rvh_ufs_reprogram_all_keys __tracepoint_android_rvh_util_est_update __tracepoint_android_vh_arch_set_freq_scale __tracepoint_android_vh_cma_alloc_finish @@ -1932,6 +2013,9 @@ __tracepoint_android_vh_of_i2c_get_board_info __tracepoint_android_vh_pagecache_get_page __tracepoint_android_vh_rmqueue + __tracepoint_android_vh_setscheduler_uclamp + __tracepoint_android_vh_snd_compr_use_pause_in_drain + __tracepoint_android_vh_sound_usb_support_cpu_suspend __tracepoint_android_vh_thermal_pm_notify_suspend __tracepoint_android_vh_timerfd_create __tracepoint_android_vh_typec_store_partner_src_caps @@ -1954,6 +2038,8 @@ __tracepoint_dwc3_readl __tracepoint_dwc3_writel __tracepoint_gpu_mem_total + __tracepoint_mm_vmscan_direct_reclaim_begin + __tracepoint_mm_vmscan_direct_reclaim_end __tracepoint_pelt_cfs_tp __tracepoint_pelt_dl_tp __tracepoint_pelt_irq_tp @@ -2023,8 +2109,11 @@ unregister_inet6addr_notifier unregister_inetaddr_notifier unregister_netdev + unregister_netdevice_many unregister_netdevice_notifier unregister_netdevice_queue + unregister_oom_notifier + unregister_pernet_device unregister_pernet_subsys unregister_pm_notifier unregister_reboot_notifier @@ -2132,6 +2221,7 @@ vb2_streamon vb2_vmalloc_memops vb2_wait_for_all_buffers + verify_pkcs7_signature vfree video_devdata video_device_alloc @@ -2183,11 +2273,7 @@ watchdog_register_device watchdog_set_restart_priority watchdog_unregister_device - wiphy_apply_custom_regulatory - wiphy_free - wiphy_new_nm - wiphy_register - wiphy_unregister + wireless_nlevent_flush woken_wake_function work_busy __xfrm_state_destroy @@ -2202,6 +2288,7 @@ xhci_handle_event xhci_init_driver xhci_resume + xhci_ring_alloc xhci_ring_free xhci_run xhci_suspend diff --git a/android/abi_gki_aarch64_hikey960 b/android/abi_gki_aarch64_hikey960 index 2515273bd123..93f48f3642bd 100644 --- a/android/abi_gki_aarch64_hikey960 +++ b/android/abi_gki_aarch64_hikey960 @@ -166,12 +166,6 @@ ida_alloc_range ida_destroy ida_free - ieee80211_channel_to_freq_khz - ieee80211_connection_loss - ieee80211_find_sta - ieee80211_get_hdrlen_from_skb - ieee80211_queue_delayed_work - ieee80211_stop_rx_ba_session __init_swait_queue_head init_timer_key init_wait_entry @@ -1225,17 +1219,10 @@ tcpci_unregister_port # required by wl18xx.ko - __cfg80211_alloc_event_skb - __cfg80211_send_event_skb - ieee80211_radar_detected kstrtou8_from_user # required by wlcore.ko bcmp - __cfg80211_alloc_reply_skb - cfg80211_find_elem_match - cfg80211_find_vendor_elem - cfg80211_vendor_cmd_reply complete_all consume_skb device_create_bin_file @@ -1244,40 +1231,6 @@ dev_pm_set_dedicated_wake_irq disable_irq_nosync get_random_u32 - ieee80211_alloc_hw_nm - ieee80211_ap_probereq_get - ieee80211_beacon_get_tim - ieee80211_chswitch_done - ieee80211_cqm_beacon_loss_notify - ieee80211_cqm_rssi_notify - ieee80211_csa_finish - ieee80211_free_hw - ieee80211_free_txskb - ieee80211_freq_khz_to_channel - ieee80211_hdrlen - ieee80211_iterate_active_interfaces_atomic - ieee80211_iterate_interfaces - ieee80211_nullfunc_get - ieee80211_probereq_get - ieee80211_proberesp_get - ieee80211_pspoll_get - ieee80211_queue_work - ieee80211_ready_on_channel - ieee80211_register_hw - ieee80211_remain_on_channel_expired - ieee80211_report_low_ack - ieee80211_restart_hw - ieee80211_rx_napi - ieee80211_scan_completed - ieee80211_sched_scan_results - ieee80211_sched_scan_stopped - ieee80211_sta_ps_transition - ieee80211_stop_queue - ieee80211_stop_queues - ieee80211_tx_status - ieee80211_unregister_hw - ieee80211_wake_queue - ieee80211_wake_queues jiffies_to_msecs jiffies_to_usecs __local_bh_enable_ip @@ -1286,14 +1239,12 @@ no_seek_end_llseek _raw_spin_trylock request_firmware_nowait - rfc1042_header skb_dequeue skb_push skb_put skb_queue_head skb_trim vscnprintf - wiphy_to_ieee80211_hw # required by wlcore_sdio.ko platform_device_add diff --git a/android/abi_gki_aarch64_mtk b/android/abi_gki_aarch64_mtk index 1150db28bc95..e9ae312bbb69 100644 --- a/android/abi_gki_aarch64_mtk +++ b/android/abi_gki_aarch64_mtk @@ -19,20 +19,24 @@ alloc_pages_exact __alloc_pages_nodemask __alloc_percpu + __alloc_percpu_gfp __alloc_skb alloc_workqueue android_debug_symbol android_rvh_probe_register anon_inode_getfd anon_inode_getfile - __arch_clear_user + arc4_crypt + arc4_setkey __arch_copy_from_user __arch_copy_to_user arch_timer_read_counter arm64_const_caps_ready arm64_use_ng_mappings + __arm_smccc_hvc __arm_smccc_smc arp_tbl + async_schedule_node atomic_notifier_call_chain atomic_notifier_chain_register atomic_notifier_chain_unregister @@ -40,15 +44,17 @@ bcmp bdget_disk bdput + bio_add_pc_page + bio_alloc_bioset bio_endio + bio_put + bio_reset __bitmap_andnot __bitmap_clear - __bitmap_equal bitmap_find_free_region bitmap_find_next_zero_area_off bitmap_free bitmap_from_arr32 - __bitmap_or bitmap_print_to_pagebuf bitmap_release_region __bitmap_set @@ -57,6 +63,13 @@ bitmap_zalloc blk_alloc_queue blk_cleanup_queue + blk_execute_rq + blk_execute_rq_nowait + blk_get_request + blk_mq_free_request + blk_mq_sched_mark_restart_hctx + blk_mq_start_request + blk_put_request blk_queue_flag_clear blk_queue_flag_set blk_queue_io_min @@ -65,9 +78,12 @@ blk_queue_max_discard_sectors blk_queue_max_write_zeroes_sectors blk_queue_physical_block_size + blk_rq_append_bio blocking_notifier_call_chain blocking_notifier_chain_register blocking_notifier_chain_unregister + bpf_trace_run10 + bpf_trace_run12 bpf_trace_run1 bpf_trace_run2 bpf_trace_run3 @@ -80,7 +96,7 @@ bus_register bus_set_iommu bus_unregister - cache_line_size + call_rcu cancel_delayed_work cancel_delayed_work_sync cancel_work_sync @@ -90,38 +106,6 @@ cdev_device_add cdev_device_del cdev_init - __cfg80211_alloc_event_skb - __cfg80211_alloc_reply_skb - cfg80211_cac_event - cfg80211_chandef_create - cfg80211_ch_switch_notify - cfg80211_classify8021d - cfg80211_connect_done - cfg80211_del_sta_sinfo - cfg80211_disconnected - cfg80211_external_auth_request - cfg80211_find_elem_match - cfg80211_ft_event - cfg80211_get_bss - cfg80211_inform_bss_data - cfg80211_inform_bss_frame_data - cfg80211_mgmt_tx_status - cfg80211_michael_mic_failure - cfg80211_new_sta - cfg80211_pmksa_candidate_notify - cfg80211_put_bss - cfg80211_radar_event - cfg80211_ready_on_channel - cfg80211_remain_on_channel_expired - cfg80211_roamed - cfg80211_rx_mgmt_khz - cfg80211_scan_done - cfg80211_sched_scan_results - cfg80211_sched_scan_stopped - __cfg80211_send_event_skb - cfg80211_tdls_oper_request - cfg80211_unlink_bss - cfg80211_vendor_cmd_reply __cfi_slowpath __check_object_size check_preempt_curr @@ -131,7 +115,6 @@ class_for_each_device __class_register class_unregister - clear_page __ClearPageMovable clk_bulk_disable clk_bulk_enable @@ -169,18 +152,24 @@ clk_unprepare clocks_calc_mult_shift __close_fd + cma_alloc + cma_release compat_alloc_user_space compat_ptr_ioctl complete complete_all completion_done component_add + component_add_typed component_bind_all component_del component_master_add_with_match component_master_del component_match_add_release + component_match_add_typed component_unbind_all + config_ep_by_speed + config_group_init_type_name console_drivers console_suspend_enabled console_unlock @@ -195,11 +184,13 @@ cpu_bit_bitmap cpufreq_add_update_util_hook cpufreq_cpu_get + cpufreq_cpu_put cpufreq_disable_fast_switch cpufreq_driver_fast_switch cpufreq_driver_resolve_freq __cpufreq_driver_target cpufreq_enable_fast_switch + cpufreq_frequency_table_get_index cpufreq_generic_attr cpufreq_generic_frequency_table_verify cpufreq_get_policy @@ -235,23 +226,40 @@ __cpu_possible_mask __cpu_present_mask cpu_scale + cpus_read_lock + cpus_read_unlock cpu_subsys cpu_topology + crc32_be crc32_le crc8 crc8_populate_msb + crypto_aead_decrypt + crypto_aead_encrypt + crypto_aead_setauthsize + crypto_aead_setkey + crypto_alloc_aead crypto_alloc_base crypto_alloc_shash + crypto_alloc_skcipher crypto_comp_compress crypto_comp_decompress crypto_destroy_tfm crypto_has_alg + __crypto_memneq crypto_register_alg crypto_register_scomp + crypto_shash_digest crypto_shash_final + crypto_shash_finup + crypto_shash_setkey crypto_shash_update + crypto_skcipher_decrypt + crypto_skcipher_encrypt + crypto_skcipher_setkey crypto_unregister_alg crypto_unregister_scomp + __crypto_xor _ctype dapm_clock_event dapm_kcontrol_get_value @@ -266,13 +274,14 @@ debugfs_create_file debugfs_create_regset32 debugfs_create_symlink + debugfs_create_u16 debugfs_create_u32 debugfs_create_u64 debugfs_create_u8 debugfs_create_x32 debugfs_lookup debugfs_remove - debug_locks_off + debugfs_rename dec_zone_page_state default_llseek deferred_free @@ -281,35 +290,39 @@ del_timer del_timer_sync destroy_workqueue + dev_alloc_name dev_base_lock + dev_change_net_namespace + dev_close dev_driver_string _dev_emerg _dev_err dev_err_probe - devfreq_add_device + dev_fetch_sw_netstats devfreq_add_governor - devfreq_cooling_unregister devfreq_get_devfreq_by_phandle devfreq_monitor_resume devfreq_monitor_start devfreq_monitor_stop devfreq_monitor_suspend devfreq_recommended_opp - devfreq_register_opp_notifier devfreq_remove_device devfreq_remove_governor devfreq_resume_device devfreq_suspend_device - devfreq_unregister_opp_notifier devfreq_update_interval dev_fwnode - dev_get_by_name + __dev_get_by_index + dev_get_by_index dev_get_regmap dev_get_stats + device_add device_add_disk device_create device_create_bin_file device_create_file + device_create_with_groups + device_del device_destroy device_for_each_child device_get_child_node_count @@ -320,18 +333,22 @@ device_link_add device_link_remove device_property_present + device_property_read_string device_property_read_u32_array device_register device_remove_bin_file device_remove_file device_rename device_set_of_node_from_dev + device_show_bool + device_store_bool device_unregister _dev_info __dev_kfree_skb_any __devm_alloc_percpu devm_blk_ksm_init devm_clk_bulk_get + devm_clk_bulk_get_optional devm_clk_get devm_clk_get_optional devm_clk_register @@ -344,19 +361,24 @@ devm_extcon_register_notifier devm_free_irq devm_fwnode_pwm_get + devm_gpiochip_add_data_with_key devm_gpiod_get devm_gpiod_get_index + devm_gpiod_get_optional devm_gpiod_put devm_gpio_free devm_gpio_request devm_gpio_request_one + devm_hwrng_register devm_i2c_new_dummy_device devm_iio_channel_get + devm_iio_channel_get_all devm_iio_device_alloc __devm_iio_device_register devm_input_allocate_device devm_ioremap devm_ioremap_resource + devm_ioremap_wc devm_kasprintf devm_kfree devm_kmalloc @@ -376,6 +398,7 @@ devm_pinctrl_get devm_pinctrl_put devm_pinctrl_register_and_init + devm_platform_get_and_ioremap_resource devm_platform_ioremap_resource devm_platform_ioremap_resource_byname devm_power_supply_get_by_phandle @@ -386,7 +409,9 @@ __devm_regmap_init_i2c __devm_regmap_init_mmio_clk devm_regulator_get + devm_regulator_get_exclusive devm_regulator_get_optional + devm_regulator_put devm_regulator_register devm_regulator_register_notifier devm_regulator_unregister_notifier @@ -400,12 +425,14 @@ devm_thermal_zone_of_sensor_register devm_watchdog_register_device _dev_notice + dev_pm_domain_attach_by_id + dev_pm_domain_attach_by_name + dev_pm_domain_detach dev_pm_genpd_add_notifier dev_pm_genpd_set_performance_state dev_pm_opp_add dev_pm_opp_find_freq_ceil dev_pm_opp_find_freq_ceil_by_volt - dev_pm_opp_find_freq_exact dev_pm_opp_find_freq_floor dev_pm_opp_get_freq dev_pm_opp_get_level @@ -417,9 +444,7 @@ dev_pm_opp_of_remove_table dev_pm_opp_put dev_pm_opp_put_opp_table - dev_pm_opp_put_regulators dev_pm_opp_remove_all_dynamic - dev_pm_opp_set_regulators dev_pm_qos_update_request dev_printk dev_queue_xmit @@ -446,7 +471,6 @@ dma_buf_fd dma_buf_get dma_buf_map_attachment - dma_buf_mmap dmabuf_page_pool_alloc dmabuf_page_pool_create dmabuf_page_pool_destroy @@ -459,10 +483,8 @@ dma_fence_context_alloc dma_fence_default_wait dma_fence_free - dma_fence_get_status dma_fence_init dma_fence_release - dma_fence_remove_callback dma_fence_signal dma_fence_signal_locked dma_fence_signal_timestamp_locked @@ -470,10 +492,16 @@ dma_free_attrs dma_get_sgtable_attrs dma_heap_add + dma_heap_buffer_alloc + dma_heap_bufferfd_alloc + dma_heap_find dma_heap_get_dev + dma_heap_get_drvdata dma_heap_get_name + dma_heap_put dmam_alloc_attrs dma_map_page_attrs + dma_map_resource dma_map_sg_attrs dmam_free_coherent dma_mmap_attrs @@ -482,29 +510,30 @@ dma_pool_destroy dma_pool_free dma_resv_wait_timeout_rcu + dma_run_dependencies dma_set_coherent_mask dma_set_mask dma_sync_sg_for_cpu dma_sync_sg_for_device dma_sync_single_for_cpu - dma_sync_single_for_device dma_unmap_page_attrs + dma_unmap_resource dma_unmap_sg_attrs do_exit do_wait_intr_irq down - downgrade_write down_interruptible down_read - down_read_trylock down_timeout down_trylock down_write d_path dput + drain_workqueue driver_create_file driver_remove_file driver_unregister + drm_add_edid_modes drm_add_modes_noedid drm_atomic_add_affected_connectors drm_atomic_get_crtc_state @@ -542,6 +571,7 @@ drm_connector_attach_encoder drm_connector_cleanup drm_connector_init + drm_connector_update_edid_property drm_crtc_cleanup drm_crtc_handle_vblank drm_crtc_init_with_planes @@ -555,6 +585,16 @@ drm_dev_put drm_dev_register drm_dev_unregister + drm_dp_aux_init + drm_dp_aux_register + drm_dp_channel_eq_ok + drm_dp_clock_recovery_ok + drm_dp_dpcd_read + drm_dp_dpcd_write + drm_dp_link_train_channel_eq_delay + drm_dp_link_train_clock_recovery_delay + drm_edid_duplicate + drm_edid_to_sad drm_encoder_cleanup drm_encoder_init __drm_err @@ -577,8 +617,8 @@ drm_gem_prime_fd_to_handle drm_gem_prime_handle_to_fd drm_gem_prime_import - drm_gem_private_object_init drm_gem_vm_close + drm_get_edid drm_helper_hpd_irq_event drm_helper_mode_fill_fb_struct drm_helper_probe_single_connector_modes @@ -634,7 +674,12 @@ eth_header_cache eth_header_cache_update eth_header_parse + eth_mac_addr + eth_platform_get_mac_address + ethtool_op_get_link + ethtool_op_get_ts_info eth_type_trans + eth_validate_addr event_triggers_call extcon_get_edev_by_phandle extcon_get_state @@ -642,6 +687,7 @@ failure_tracking fd_install fget + find_get_pid find_last_bit find_next_bit find_next_zero_bit @@ -658,6 +704,10 @@ font_vga_8x16 for_each_kernel_tracepoint fput + frame_vector_create + frame_vector_destroy + frame_vector_to_pages + frame_vector_to_pfns free_irq free_netdev __free_pages @@ -670,19 +720,37 @@ freq_qos_add_request freq_qos_remove_request freq_qos_update_request + fs_bio_set + fsg_common_create_luns + fsg_common_set_cdev + fsg_common_set_inquiry_string + fsg_common_set_sysfs + fsg_config_from_params fsync_bdev + fwnode_device_is_available + fwnode_get_name + fwnode_graph_get_next_endpoint + fwnode_graph_get_port_parent + fwnode_graph_get_remote_endpoint + fwnode_graph_get_remote_port_parent + fwnode_graph_parse_endpoint fwnode_handle_get fwnode_handle_put + fwnode_property_get_reference_args fwnode_property_present fwnode_property_read_string fwnode_property_read_u32_array + fwnode_property_read_u64_array gcd generic_file_llseek generic_handle_irq generic_iommu_put_resv_regions + generic_mii_ioctl + genlmsg_multicast_allns genlmsg_put genl_register_family genl_unregister_family + genphy_resume gen_pool_add_owner gen_pool_alloc_algo_owner gen_pool_avail @@ -694,24 +762,28 @@ gen_pool_set_algo gen_pool_size gen_pool_virt_to_phys + getboottime64 get_cpu_device get_cpu_idle_time get_cpu_idle_time_us get_cpu_iowait_time_us get_device get_each_dmabuf + get_freelist_nr_pages __get_free_pages get_governor_parent_kobj get_kernel_pages + get_net_ns_by_fd + get_net_ns_by_pid + get_pid_task get_random_bytes get_random_u32 __get_task_comm get_task_exe_file get_task_mm get_unused_fd_flags - get_user_pages - get_user_pages_fast get_user_pages_remote + get_vaddr_frames get_zeroed_page gic_nonsecure_priorities gov_attr_set_get @@ -725,11 +797,13 @@ gpiochip_lock_as_irq gpiochip_unlock_as_irq gpiod_direction_input + gpiod_direction_output gpiod_direction_output_raw gpiod_get_raw_value + gpiod_get_value_cansleep gpiod_set_debounce - gpiod_set_raw_value gpiod_set_value + gpiod_set_value_cansleep gpiod_to_irq gpio_free gpio_request @@ -737,24 +811,23 @@ gpio_to_desc handle_level_irq handle_nested_irq + handle_simple_irq hashlen_string have_governor_per_policy - hci_alloc_dev - hci_free_dev - hci_recv_frame - hci_register_dev - hci_unregister_dev hex_asc - hex_dump_to_buffer hrtimer_active hrtimer_cancel hrtimer_forward hrtimer_init hrtimer_start_range_ns hrtimer_try_to_cancel + __hw_addr_init + __hw_addr_sync + __hw_addr_unsync i2c_add_adapter i2c_del_adapter i2c_del_driver + i2c_get_adapter i2c_get_dma_safe_msg_buf i2c_put_dma_safe_msg_buf i2c_register_driver @@ -762,8 +835,10 @@ i2c_smbus_read_i2c_block_data i2c_smbus_write_byte_data i2c_smbus_write_i2c_block_data + i2c_smbus_write_word_data i2c_transfer i2c_transfer_buffer_flags + i2c_unregister_device icc_link_create icc_node_add icc_node_create @@ -774,19 +849,21 @@ icc_put icc_set_bw icc_sync_state + ida_alloc_range + ida_destroy + ida_free idr_alloc idr_destroy idr_find idr_for_each idr_get_next idr_remove - ieee80211_channel_to_freq_khz - ieee80211_freq_khz_to_channel - ieee80211_get_channel_khz + iio_alloc_pollfunc iio_buffer_init iio_buffer_put iio_channel_get iio_channel_release + iio_dealloc_pollfunc iio_device_attach_buffer __iio_device_register iio_device_unregister @@ -796,8 +873,10 @@ iio_read_channel_attribute iio_read_channel_processed iio_read_channel_raw + iio_trigger_notify_done inc_zone_page_state in_egroup_p + inet_csk_get_port init_net init_pseudo __init_rwsem @@ -816,7 +895,6 @@ input_set_abs_params input_set_capability input_unregister_device - iomem_resource iommu_alloc_resv_region iommu_device_register iommu_device_sysfs_add @@ -829,19 +907,23 @@ iommu_group_alloc iommu_group_ref_get iommu_iova_to_phys + iommu_map iommu_map_sg iommu_present iommu_put_dma_cookie iommu_unmap __ioremap + ioremap_cache iounmap iput ipv6_skip_exthdr irq_create_mapping_affinity irq_create_of_mapping + irq_dispose_mapping __irq_domain_add irq_domain_remove irq_domain_simple_ops + irq_domain_xlate_onetwocell irq_domain_xlate_twocell irq_find_mapping irq_get_irqchip_state @@ -850,14 +932,18 @@ irq_of_parse_and_map irq_set_affinity_hint irq_set_chained_handler_and_data + irq_set_chip irq_set_chip_and_handler_name irq_set_chip_data irq_set_irq_type irq_set_irq_wake + irq_set_parent irq_to_desc irq_work_queue irq_work_sync + is_dma_buf_file is_vmalloc_addr + iterate_fd jiffies jiffies_to_msecs jiffies_to_usecs @@ -865,22 +951,27 @@ kasprintf kernel_cpustat kernel_kobj + kernel_param_lock + kernel_param_unlock kernel_power_off kernel_restart kernel_sigaction kernfs_path_from_node kern_mount kern_unmount + key_create_or_update + key_put + keyring_alloc __kfifo_alloc __kfifo_free __kfifo_in - __kfifo_init __kfifo_out __kfifo_to_user kfree kfree_const kfree_sensitive kfree_skb + kfree_skb_list kill_anon_super kimage_vaddr kimage_voffset @@ -892,19 +983,21 @@ kmem_cache_create kmem_cache_destroy kmem_cache_free + kmemdup + kobject_add kobject_create_and_add kobject_del + kobject_get + kobject_init kobject_init_and_add kobject_put kobject_uevent kobject_uevent_env krealloc - kset_find_obj kstrdup kstrdup_const kstrndup kstrtobool - kstrtobool_from_user kstrtoint kstrtoint_from_user kstrtol_from_user @@ -934,10 +1027,11 @@ kthread_stop kthread_worker_fn ktime_get + ktime_get_coarse_with_offset ktime_get_mono_fast_ns - ktime_get_raw ktime_get_raw_ts64 ktime_get_real_ts64 + ktime_get_seconds ktime_get_ts64 ktime_get_with_offset kvfree @@ -968,6 +1062,9 @@ lzo1x_1_compress lzo1x_decompress_safe lzorle1x_1_compress + match_hex + match_int + match_token mbox_chan_received_data mbox_client_txdone mbox_controller_register @@ -975,16 +1072,37 @@ mbox_free_channel mbox_request_channel mbox_send_message + mdiobus_alloc_size + mdiobus_free + __mdiobus_register + mdiobus_unregister + media_create_intf_link + media_create_pad_link + media_device_cleanup media_device_init __media_device_register media_device_unregister + media_devnode_create + media_devnode_remove media_entity_pads_init + media_entity_remote_pad + media_entity_remove_links + __media_entity_setup_link + media_graph_walk_next + media_graph_walk_start + media_pipeline_start + media_pipeline_stop + media_request_get_by_fd + media_request_object_complete + media_request_put memblock_end_of_DRAM + memchr memcmp memcpy __memcpy_fromio __memcpy_toio memmove + memory_read_from_buffer memparse memremap memset64 @@ -993,12 +1111,20 @@ memstart_addr memunmap migrate_swap + mii_check_media + mii_ethtool_get_link_ksettings + mii_ethtool_gset + mii_ethtool_set_link_ksettings + mii_link_ok + mii_nway_restart mipi_dsi_attach mipi_dsi_dcs_read + mipi_dsi_dcs_write mipi_dsi_dcs_write_buffer mipi_dsi_detach mipi_dsi_driver_register_full mipi_dsi_driver_unregister + mipi_dsi_generic_read mipi_dsi_generic_write mipi_dsi_host_register mipi_dsi_host_unregister @@ -1013,6 +1139,7 @@ mmc_free_host mmc_gpio_get_cd mmc_gpio_get_ro + mmc_hw_reset mmc_of_parse mmc_regulator_get_supply mmc_regulator_set_ocr @@ -1020,13 +1147,11 @@ mmc_remove_host mmc_request_done mmc_send_tuning - __mmdrop mmput mod_delayed_work_on mod_timer mod_timer_pending module_layout - module_put __msecs_to_jiffies msleep msleep_interruptible @@ -1045,30 +1170,42 @@ nd_tbl netdev_alloc_frag __netdev_alloc_skb + netdev_err + netdev_info + netdev_set_default_ethtool_ops + netdev_warn netif_carrier_off netif_carrier_on netif_napi_add netif_receive_skb + netif_receive_skb_list netif_rx netif_rx_ni netif_tx_stop_all_queues netif_tx_wake_queue + netlink_broadcast __netlink_kernel_create - netlink_kernel_release + netlink_register_notifier netlink_unicast + netlink_unregister_notifier net_namespace_list + net_ns_type_operations + net_ratelimit nf_register_net_hooks nf_unregister_net_hooks + nla_find + nla_memcpy __nla_parse + nla_put_64bit nla_put - nla_put_nohdr + nla_reserve + __nla_validate __nlmsg_put no_llseek nonseekable_open nr_cpu_ids nsecs_to_jiffies ns_to_timespec64 - n_tty_ioctl_helper __num_online_cpus nvmem_cell_get nvmem_cell_put @@ -1089,7 +1226,6 @@ of_clk_src_simple_get of_count_phandle_with_args of_cpu_node_to_id - of_devfreq_cooling_register_power of_device_get_match_data of_device_is_available of_device_is_compatible @@ -1104,6 +1240,7 @@ of_find_device_by_node of_find_matching_node_and_match of_find_node_by_name + of_find_node_by_phandle of_find_node_opts_by_path of_find_node_with_property of_find_property @@ -1119,6 +1256,7 @@ of_get_next_parent of_get_parent of_get_property + of_get_regulator_init_data of_graph_get_next_endpoint of_graph_get_remote_node of_graph_get_remote_port_parent @@ -1172,10 +1310,8 @@ param_get_uint param_get_ulong param_ops_bool - param_ops_byte param_ops_charp param_ops_int - param_ops_string param_ops_uint param_set_bool param_set_charp @@ -1184,6 +1320,10 @@ pause_cpus PDE_DATA __per_cpu_offset + perf_event_create_kernel_counter + perf_event_disable + perf_event_enable + perf_event_release_kernel perf_event_update_userpage perf_pmu_migrate_context perf_pmu_register @@ -1191,13 +1331,22 @@ perf_trace_buf_alloc perf_trace_run_bpf_submit pfn_valid + phy_connect + phy_disconnect + phy_do_ioctl_running + phy_ethtool_get_link_ksettings + phy_ethtool_nway_reset + phy_ethtool_set_link_ksettings phy_exit phy_get phy_init phy_power_off phy_power_on + phy_print_status phy_put phy_set_mode_ext + phy_start + phy_stop pid_task pinconf_generic_parse_dt_config pinctrl_dev_get_drvdata @@ -1212,18 +1361,23 @@ pinctrl_utils_add_map_configs pinctrl_utils_free_map pinctrl_utils_reserve_map + pin_user_pages pin_user_pages_fast platform_bus_type platform_device_add + platform_device_add_data platform_device_alloc + platform_device_del platform_device_put platform_device_register platform_device_register_full platform_device_unregister __platform_driver_register platform_driver_unregister + platform_find_device_by_driver platform_get_irq platform_get_irq_byname + platform_get_irq_byname_optional platform_get_irq_optional platform_get_resource platform_get_resource_byname @@ -1257,24 +1411,36 @@ power_supply_get_by_name power_supply_get_drvdata power_supply_get_property + power_supply_put power_supply_register power_supply_reg_notifier power_supply_set_property + prandom_bytes + prandom_u32 preempt_schedule preempt_schedule_notrace prepare_to_wait_event print_hex_dump printk + printk_deferred proc_create proc_create_data + proc_create_single_data proc_mkdir proc_remove proc_set_user + pskb_expand_head + __pskb_pull_tail + ___pskb_trim put_device put_disk + __put_net __put_page + put_pid + put_task_stack __put_task_struct put_unused_fd + put_vaddr_frames pwm_apply_state pwmchip_add pwmchip_remove @@ -1286,9 +1452,11 @@ raw_notifier_chain_unregister _raw_read_lock _raw_read_lock_bh + _raw_read_lock_irqsave _raw_read_trylock _raw_read_unlock _raw_read_unlock_bh + _raw_read_unlock_irqrestore _raw_spin_lock _raw_spin_lock_bh _raw_spin_lock_irq @@ -1308,8 +1476,7 @@ rb_first rb_insert_color rb_next - rb_prev - rb_replace_node + rcu_barrier rcu_idle_enter rcu_idle_exit __rcu_read_lock @@ -1317,6 +1484,7 @@ rdev_get_dev rdev_get_drvdata rdev_get_id + rdev_get_regmap refcount_warn_saturate __refrigerator regcache_cache_only @@ -1326,12 +1494,15 @@ __register_chrdev register_chrdev_region register_die_notifier + register_inet6addr_notifier register_inetaddr_notifier register_kprobe register_module_notifier register_netdev register_netdevice register_netdevice_notifier + register_oom_notifier + register_pernet_device register_pernet_subsys register_pm_notifier register_reboot_notifier @@ -1346,6 +1517,8 @@ regmap_field_update_bits_base __regmap_init regmap_irq_get_domain + regmap_raw_read + regmap_raw_write regmap_read regmap_update_bits_base regmap_write @@ -1355,6 +1528,8 @@ regulator_enable regulator_enable_regmap regulator_get + regulator_get_current_limit_regmap + regulator_get_mode regulator_get_optional regulator_get_voltage regulator_get_voltage_sel_regmap @@ -1365,20 +1540,21 @@ regulator_list_voltage_linear_range regulator_list_voltage_table regulator_map_voltage_iterate + regulator_map_voltage_linear regulator_map_voltage_linear_range regulator_notifier_call_chain regulator_put + regulator_set_active_discharge_regmap regulator_set_current_limit + regulator_set_current_limit_regmap regulator_set_mode regulator_set_voltage regulator_set_voltage_sel_regmap regulator_set_voltage_time regulator_set_voltage_time_sel regulator_sync_voltage - regulatory_hint release_firmware release_pages - __release_region remap_pfn_range remap_vmalloc_range remove_proc_entry @@ -1387,7 +1563,6 @@ request_firmware request_firmware_nowait __request_percpu_irq - __request_region request_threaded_irq reset_control_assert reset_control_deassert @@ -1395,8 +1570,27 @@ reset_control_reset resume_cpus revalidate_disk_size + rfkill_alloc + rfkill_blocked + rfkill_destroy + rfkill_pause_polling + rfkill_register + rfkill_resume_polling + rfkill_set_hw_state + rfkill_unregister + rhashtable_free_and_destroy + rhashtable_insert_slow + rhltable_init + __rht_bucket_nested + rht_bucket_nested + rht_bucket_nested_insert + root_task_group + round_jiffies + round_jiffies_relative + round_jiffies_up rpmsg_create_ept rpmsg_destroy_ept + rpmsg_find_device rpmsg_register_device rpmsg_send rpmsg_trysend @@ -1404,9 +1598,14 @@ rproc_add rproc_add_subdev rproc_alloc + rproc_boot rproc_del rproc_free + rproc_get_by_phandle + rproc_put rproc_remove_subdev + rproc_report_crash + rproc_shutdown rps_needed rtc_ktime_to_tm rtc_nvmem_register @@ -1420,38 +1619,33 @@ rtnl_lock rtnl_unlock runqueues + __sbitmap_queue_get sched_clock sched_feat_keys sched_setattr_nocheck sched_set_normal sched_setscheduler + sched_setscheduler_nocheck sched_uclamp_used schedule schedule_timeout - schedutil_cpu_util scmi_driver_register scmi_driver_unregister + scmi_protocol_register scnprintf - sdio_claim_host - sdio_claim_irq - sdio_disable_func - sdio_enable_func - sdio_f0_readb - sdio_f0_writeb - sdio_get_host_pm_caps - sdio_readb - sdio_readl - sdio_readsb - sdio_register_driver - sdio_release_host - sdio_release_irq - sdio_set_block_size - sdio_set_host_pm_flags + scsi_autopm_get_device + scsi_autopm_put_device + scsi_block_requests + scsi_command_size_tbl + scsi_device_get + scsi_device_put + scsi_device_quiesce + __scsi_execute + __scsi_iterate_devices + scsi_normalize_sense + scsi_print_sense_hdr + scsi_unblock_requests sdio_signal_irq - sdio_unregister_driver - sdio_writeb - sdio_writel - sdio_writesb send_sig seq_hex_dump seq_lseek @@ -1491,7 +1685,6 @@ sg_next __sg_page_iter_next __sg_page_iter_start - shmem_file_setup si_mem_available simple_attr_open simple_attr_read @@ -1503,17 +1696,26 @@ single_open single_release skb_add_rx_frag + skb_checksum_help + skb_clone + skb_clone_sk + skb_complete_wifi_ack skb_copy + skb_copy_bits + skb_copy_expand skb_dequeue + skb_ensure_writable + __skb_get_hash + __skb_gso_segment skb_pull - skb_pull_rcsum skb_push skb_put skb_queue_head skb_queue_purge skb_queue_tail - skb_realloc_headroom skb_trim + smp_call_function + snd_card_add_dev_attr snd_ctl_boolean_mono_info snd_jack_set_key snd_pcm_format_physical_width @@ -1533,9 +1735,13 @@ snd_soc_card_jack_new snd_soc_component_exit_regmap snd_soc_component_init_regmap + snd_soc_component_read + snd_soc_component_update_bits + snd_soc_component_write snd_soc_dai_set_sysclk snd_soc_dapm_add_routes snd_soc_dapm_disable_pin + snd_soc_dapm_enable_pin snd_soc_dapm_get_enum_double snd_soc_dapm_get_pin_switch snd_soc_dapm_get_volsw @@ -1545,6 +1751,7 @@ snd_soc_dapm_put_enum_double snd_soc_dapm_put_pin_switch snd_soc_dapm_put_volsw + snd_soc_dapm_sync snd_soc_get_volsw snd_soc_info_enum_double snd_soc_info_volsw @@ -1561,6 +1768,8 @@ snprintf soc_device_register soc_device_unregister + __sock_create + sock_release sort __spi_alloc_controller spi_bus_type @@ -1584,17 +1793,21 @@ srcu_notifier_call_chain srcu_notifier_chain_register srcu_notifier_chain_unregister + __srcu_read_unlock sscanf __stack_chk_fail __stack_chk_guard stack_trace_save static_key_slow_dec static_key_slow_inc + stop_one_cpu_nowait + stpcpy strcasecmp strchr strcmp strcpy strcspn + strim strlcat strlcpy strlen @@ -1605,26 +1818,25 @@ strncpy_from_user strnlen strnstr - strpbrk strrchr strreplace strscpy strsep - strspn strstr suspend_set_ops + __sw_hweight16 __sw_hweight32 __sw_hweight64 + __sw_hweight8 sync_file_create sync_file_get_fence synchronize_irq synchronize_net synchronize_rcu + synchronize_srcu syscon_node_to_regmap syscon_regmap_lookup_by_compatible syscon_regmap_lookup_by_phandle - syscore_resume - syscore_suspend sysfs_create_bin_file sysfs_create_file_ns sysfs_create_group @@ -1636,9 +1848,9 @@ sysfs_remove_link sysfs_streq system_freezable_power_efficient_wq + system_freezable_wq system_freezing_cnt system_highpri_wq - system_long_wq system_power_efficient_wq system_state system_unbound_wq @@ -1649,7 +1861,11 @@ tasklet_init tasklet_kill __tasklet_schedule + tasklet_setup + tasklist_lock __task_pid_nr_ns + __task_rq_lock + task_sched_runtime thermal_cooling_device_unregister thermal_of_cooling_device_register thermal_zone_get_temp @@ -1668,11 +1884,17 @@ trace_event_raw_init trace_event_reg trace_handle_return + __traceiter_android_rvh_after_enqueue_task + __traceiter_android_rvh_cpu_overutilized __traceiter_android_rvh_dequeue_task + __traceiter_android_rvh_dequeue_task_fair __traceiter_android_rvh_enqueue_task + __traceiter_android_rvh_enqueue_task_fair __traceiter_android_rvh_find_busiest_group __traceiter_android_rvh_find_energy_efficient_cpu __traceiter_android_rvh_finish_prio_fork + __traceiter_android_rvh_media_device_setup_link + __traceiter_android_rvh_new_task_stats __traceiter_android_rvh_prepare_prio_fork __traceiter_android_rvh_rtmutex_prepare_setprio __traceiter_android_rvh_sched_newidle_balance @@ -1680,6 +1902,10 @@ __traceiter_android_rvh_setscheduler __traceiter_android_rvh_set_user_nice __traceiter_android_rvh_tick_entry + __traceiter_android_rvh_uclamp_eff_get + __traceiter_android_rvh_v4l2subdev_set_fmt + __traceiter_android_rvh_v4l2subdev_set_frame_interval + __traceiter_android_rvh_v4l2subdev_set_selection __traceiter_android_vh_alter_futex_plist_add __traceiter_android_vh_alter_rwsem_list_add __traceiter_android_vh_arch_set_freq_scale @@ -1687,25 +1913,61 @@ __traceiter_android_vh_binder_set_priority __traceiter_android_vh_binder_transaction_init __traceiter_android_vh_cgroup_set_task + __traceiter_android_vh_check_bpf_syscall + __traceiter_android_vh_check_file_open + __traceiter_android_vh_check_mmap_file + __traceiter_android_vh_clear_mask_adjust + __traceiter_android_vh_clear_reserved_fmt_fields + __traceiter_android_vh_commit_creds __traceiter_android_vh_em_cpu_energy + __traceiter_android_vh_exit_creds + __traceiter_android_vh_fill_ext_fmtdesc + __traceiter_android_vh_finish_update_load_avg_se + __traceiter_android_vh_iommu_alloc_iova + __traceiter_android_vh_iommu_free_iova + __traceiter_android_vh_ipv6_gen_linklocal_addr + __traceiter_android_vh_logbuf + __traceiter_android_vh_override_creds + __traceiter_android_vh_prepare_update_load_avg_se + __traceiter_android_vh_revert_creds __traceiter_android_vh_rwsem_init __traceiter_android_vh_rwsem_wake __traceiter_android_vh_rwsem_write_finished __traceiter_android_vh_scheduler_tick + __traceiter_android_vh_selinux_avc_insert + __traceiter_android_vh_selinux_avc_lookup + __traceiter_android_vh_selinux_avc_node_delete + __traceiter_android_vh_selinux_avc_node_replace + __traceiter_android_vh_selinux_is_initialized + __traceiter_android_vh_set_memory_nx + __traceiter_android_vh_set_memory_ro + __traceiter_android_vh_set_memory_rw + __traceiter_android_vh_set_memory_x + __traceiter_android_vh_set_module_permit_after_init + __traceiter_android_vh_set_module_permit_before_init __traceiter_android_vh_set_wake_flags __traceiter_android_vh_syscall_prctl_finished + __traceiter_android_vh_ufs_send_command + __traceiter_android_vh_ufs_send_tm_command __traceiter_cpu_frequency - __traceiter_gpu_mem_total __traceiter_pelt_se_tp __traceiter_rwmmio_post_read __traceiter_rwmmio_read __traceiter_rwmmio_write - trace_output_call + __traceiter_sched_update_nr_running_tp + __traceiter_task_newtask + __traceiter_xhci_urb_giveback + __tracepoint_android_rvh_after_enqueue_task + __tracepoint_android_rvh_cpu_overutilized __tracepoint_android_rvh_dequeue_task + __tracepoint_android_rvh_dequeue_task_fair __tracepoint_android_rvh_enqueue_task + __tracepoint_android_rvh_enqueue_task_fair __tracepoint_android_rvh_find_busiest_group __tracepoint_android_rvh_find_energy_efficient_cpu __tracepoint_android_rvh_finish_prio_fork + __tracepoint_android_rvh_media_device_setup_link + __tracepoint_android_rvh_new_task_stats __tracepoint_android_rvh_prepare_prio_fork __tracepoint_android_rvh_rtmutex_prepare_setprio __tracepoint_android_rvh_sched_newidle_balance @@ -1713,6 +1975,10 @@ __tracepoint_android_rvh_setscheduler __tracepoint_android_rvh_set_user_nice __tracepoint_android_rvh_tick_entry + __tracepoint_android_rvh_uclamp_eff_get + __tracepoint_android_rvh_v4l2subdev_set_fmt + __tracepoint_android_rvh_v4l2subdev_set_frame_interval + __tracepoint_android_rvh_v4l2subdev_set_selection __tracepoint_android_vh_alter_futex_plist_add __tracepoint_android_vh_alter_rwsem_list_add __tracepoint_android_vh_arch_set_freq_scale @@ -1720,41 +1986,70 @@ __tracepoint_android_vh_binder_set_priority __tracepoint_android_vh_binder_transaction_init __tracepoint_android_vh_cgroup_set_task + __tracepoint_android_vh_check_bpf_syscall + __tracepoint_android_vh_check_file_open + __tracepoint_android_vh_check_mmap_file + __tracepoint_android_vh_clear_mask_adjust + __tracepoint_android_vh_clear_reserved_fmt_fields + __tracepoint_android_vh_commit_creds __tracepoint_android_vh_em_cpu_energy + __tracepoint_android_vh_exit_creds + __tracepoint_android_vh_fill_ext_fmtdesc + __tracepoint_android_vh_finish_update_load_avg_se + __tracepoint_android_vh_iommu_alloc_iova + __tracepoint_android_vh_iommu_free_iova + __tracepoint_android_vh_ipv6_gen_linklocal_addr + __tracepoint_android_vh_logbuf + __tracepoint_android_vh_override_creds + __tracepoint_android_vh_prepare_update_load_avg_se + __tracepoint_android_vh_revert_creds __tracepoint_android_vh_rwsem_init __tracepoint_android_vh_rwsem_wake __tracepoint_android_vh_rwsem_write_finished __tracepoint_android_vh_scheduler_tick + __tracepoint_android_vh_selinux_avc_insert + __tracepoint_android_vh_selinux_avc_lookup + __tracepoint_android_vh_selinux_avc_node_delete + __tracepoint_android_vh_selinux_avc_node_replace + __tracepoint_android_vh_selinux_is_initialized + __tracepoint_android_vh_set_memory_nx + __tracepoint_android_vh_set_memory_ro + __tracepoint_android_vh_set_memory_rw + __tracepoint_android_vh_set_memory_x + __tracepoint_android_vh_set_module_permit_after_init + __tracepoint_android_vh_set_module_permit_before_init __tracepoint_android_vh_set_wake_flags __tracepoint_android_vh_syscall_prctl_finished + __tracepoint_android_vh_ufs_send_command + __tracepoint_android_vh_ufs_send_tm_command __tracepoint_cpu_frequency - __tracepoint_gpu_mem_total __tracepoint_pelt_se_tp tracepoint_probe_register tracepoint_probe_unregister __tracepoint_rwmmio_post_read __tracepoint_rwmmio_read __tracepoint_rwmmio_write + __tracepoint_sched_update_nr_running_tp + tracepoint_srcu + __tracepoint_task_newtask + __tracepoint_xhci_urb_giveback trace_print_array_seq - trace_print_flags_seq + trace_print_hex_seq trace_print_symbols_seq __trace_puts trace_raw_output_prep trace_seq_printf trace_seq_putc tracing_off - try_module_get try_wait_for_completion - tty_driver_flush_buffer tty_flip_buffer_push tty_insert_flip_string_fixed_flag - tty_register_ldisc tty_termios_baud_rate tty_termios_encode_baud_rate - tty_unregister_ldisc typec_get_drvdata typec_mux_get_drvdata typec_mux_register + typec_mux_set typec_mux_unregister typec_partner_set_identity typec_register_partner @@ -1773,7 +2068,6 @@ uart_update_timeout uclamp_eff_value __udelay - ufshcd_auto_hibern8_update ufshcd_delay_us ufshcd_dme_get_attr ufshcd_dme_set_attr @@ -1781,6 +2075,8 @@ ufshcd_fixup_dev_quirks ufshcd_get_pwr_dev_param ufshcd_hba_enable + ufshcd_hba_stop + ufshcd_hold ufshcd_link_recovery ufshcd_make_hba_operational ufshcd_pltfrm_init @@ -1790,21 +2086,31 @@ ufshcd_pltfrm_runtime_suspend ufshcd_pltfrm_shutdown ufshcd_pltfrm_suspend + ufshcd_query_attr + ufshcd_query_attr_retry + ufshcd_query_descriptor_retry + ufshcd_query_flag + ufshcd_read_desc_param + ufshcd_release ufshcd_remove ufshcd_uic_hibern8_exit unlock_page - unmap_mapping_range + unpin_user_page unpin_user_pages unregister_blkdev __unregister_chrdev unregister_chrdev_region unregister_die_notifier + unregister_inet6addr_notifier unregister_inetaddr_notifier unregister_kprobe unregister_module_notifier unregister_netdev + unregister_netdevice_many unregister_netdevice_notifier unregister_netdevice_queue + unregister_oom_notifier + unregister_pernet_device unregister_pernet_subsys unregister_pm_notifier unregister_reboot_notifier @@ -1817,24 +2123,77 @@ update_rq_clock up_read up_write + usb_add_config + usb_add_function usb_add_gadget_udc usb_add_hcd + usb_composite_probe + usb_composite_unregister + usb_copy_descriptors usb_create_hcd usb_create_shared_hcd usb_debug_root usb_del_gadget_udc + usb_deregister usb_disabled + usb_ep_alloc_request + usb_ep_autoconfig + usb_ep_dequeue + usb_ep_disable + usb_ep_enable + usb_ep_free_request + usb_ep_queue usb_ep_set_halt usb_ep_set_maxpacket_limit + usb_function_register + usb_function_unregister + usb_gadget_connect + usb_gadget_disconnect usb_gadget_giveback_request usb_gadget_map_request + usb_gadget_probe_driver + usb_gadget_set_selfpowered usb_gadget_set_state usb_gadget_unmap_request usb_get_dr_mode + usb_get_function + usb_get_function_instance usb_get_maximum_speed usb_hcd_is_primary_hcd usb_hcd_poll_rh_status + usb_interface_id + usbnet_change_mtu + usbnet_disconnect + usbnet_get_drvinfo + usbnet_get_endpoints + usbnet_get_link + usbnet_get_link_ksettings + usbnet_get_msglevel + usbnet_get_stats64 + usbnet_link_change + usbnet_nway_reset + usbnet_open + usbnet_probe + usbnet_read_cmd + usbnet_read_cmd_nopm + usbnet_resume + usbnet_set_link_ksettings + usbnet_set_msglevel + usbnet_skb_return + usbnet_start_xmit + usbnet_stop + usbnet_suspend + usbnet_tx_timeout + usbnet_unlink_rx_urbs + usbnet_update_max_qlen + usbnet_write_cmd + usbnet_write_cmd_async + usbnet_write_cmd_nopm + usb_put_function + usb_put_function_instance usb_put_hcd + usb_register_driver + usb_remove_function usb_remove_hcd usb_role_switch_get usb_role_switch_get_drvdata @@ -1842,27 +2201,44 @@ usb_role_switch_set_role usb_role_switch_unregister usb_speed_string + usb_string_id __usecs_to_jiffies usleep_range uuid_null v4l2_async_notifier_add_fwnode_subdev + v4l2_async_notifier_add_subdev + v4l2_async_notifier_cleanup v4l2_async_notifier_init v4l2_async_notifier_register v4l2_async_notifier_unregister v4l2_async_register_subdev + v4l2_async_subdev_notifier_register v4l2_async_unregister_subdev + v4l2_compat_ioctl32 + v4l2_ctrl_find + v4l2_ctrl_g_ctrl + v4l2_ctrl_g_ctrl_int64 v4l2_ctrl_handler_free v4l2_ctrl_handler_init_class v4l2_ctrl_handler_setup + __v4l2_ctrl_modify_range v4l2_ctrl_new_custom v4l2_ctrl_new_std v4l2_ctrl_new_std_menu + v4l2_ctrl_new_std_menu_items + v4l2_ctrl_request_complete + v4l2_ctrl_request_setup __v4l2_ctrl_s_ctrl + v4l2_ctrl_subdev_subscribe_event v4l2_ctrl_subscribe_event v4l2_device_register + v4l2_device_register_subdev __v4l2_device_register_subdev_nodes v4l2_device_unregister + v4l2_device_unregister_subdev + v4l2_event_queue v4l2_event_queue_fh + v4l2_event_subdev_unsubscribe v4l2_event_subscribe v4l2_event_unsubscribe v4l2_fh_add @@ -1870,9 +2246,13 @@ v4l2_fh_exit v4l2_fh_init v4l2_fh_is_singular + v4l2_fh_open + __v4l2_find_nearest_size + v4l2_format_info + v4l2_i2c_subdev_init + v4l2_m2m_buf_copy_metadata v4l2_m2m_buf_queue v4l2_m2m_buf_remove - v4l2_m2m_buf_remove_by_buf v4l2_m2m_ctx_init v4l2_m2m_ctx_release v4l2_m2m_dqbuf @@ -1893,27 +2273,53 @@ v4l2_m2m_job_finish v4l2_m2m_next_buf v4l2_m2m_qbuf + v4l2_m2m_register_media_controller v4l2_m2m_release + v4l2_m2m_request_queue v4l2_m2m_resume v4l2_m2m_streamoff v4l2_m2m_suspend v4l2_m2m_try_schedule + v4l2_m2m_unregister_media_controller + v4l2_pipeline_link_notify v4l2_src_change_event_subscribe + v4l2_subdev_call_wrappers v4l2_subdev_init + v4l2_subdev_link_validate + v4l2_subdev_link_validate_default v4l_bound_align_image vabits_actual vb2_buffer_done + vb2_common_vm_ops + vb2_create_framevec + vb2_destroy_framevec vb2_dma_contig_memops + vb2_fop_mmap + vb2_fop_poll + vb2_fop_release + vb2_ioctl_create_bufs + vb2_ioctl_dqbuf + vb2_ioctl_expbuf + vb2_ioctl_prepare_buf + vb2_ioctl_qbuf + vb2_ioctl_querybuf + vb2_ioctl_reqbufs + vb2_ioctl_streamoff + vb2_ioctl_streamon vb2_ops_wait_finish vb2_ops_wait_prepare vb2_plane_cookie vb2_plane_vaddr vb2_queue_init vb2_queue_release + vb2_request_object_is_buffer + vb2_request_queue + vb2_request_validate vchan_dma_desc_free_list vchan_init vchan_tx_desc_free vchan_tx_submit + verify_pkcs7_signature vfree video_devdata video_device_alloc @@ -1936,8 +2342,9 @@ vmalloc_user vmap vm_event_states - vmf_insert_pfn_prot + vm_map_ram vm_node_stat + vm_unmap_ram vm_zone_stat vring_del_virtqueue vring_interrupt @@ -1950,6 +2357,7 @@ wait_for_completion wait_for_completion_interruptible wait_for_completion_interruptible_timeout + wait_for_completion_io_timeout wait_for_completion_killable wait_for_completion_timeout wait_woken @@ -1958,20 +2366,19 @@ wake_up_process wakeup_source_add wakeup_source_create + wakeup_source_destroy wakeup_source_register + wakeup_source_remove wakeup_source_unregister __warn_printk watchdog_init_timeout watchdog_set_restart_priority - wiphy_apply_custom_regulatory - wiphy_free - wiphy_new_nm - wiphy_register - wiphy_unregister - wireless_send_event + wireless_nlevent_flush woken_wake_function work_busy work_on_cpu + ww_mutex_lock + ww_mutex_unlock xhci_add_endpoint xhci_check_bandwidth xhci_drop_endpoint @@ -1980,6 +2387,141 @@ xhci_get_ep_ctx xhci_init_driver xhci_reset_bandwidth + +# preserved by --additions-only + all_vm_events + __arch_clear_user + __bitmap_equal + __bitmap_or + blk_insert_cloned_request + cache_line_size + cgroup_taskset_first + cgroup_taskset_next + class_create_file_ns + class_remove_file_ns + clear_page + cpufreq_update_util_data + cpu_pm_register_notifier + cpu_pm_unregister_notifier + debug_locks_off + devfreq_add_device + devfreq_cooling_unregister + devfreq_register_opp_notifier + devfreq_unregister_opp_notifier + dev_get_by_name + devm_of_pwm_get + devm_rc_allocate_device + devm_rc_register_device + dev_pm_opp_find_freq_exact + dev_pm_opp_put_regulators + dev_pm_opp_set_regulators + dma_buf_mmap + dma_fence_get_status + dma_fence_remove_callback + dma_heap_buffer_free + dma_sync_single_for_device + downgrade_write + down_read_trylock + drm_gem_private_object_init + get_user_pages + get_user_pages_fast + gpiod_set_raw_value + hci_alloc_dev + hci_free_dev + hci_recv_frame + hci_register_dev + hci_unregister_dev + hex_dump_to_buffer + iomem_resource + irq_work_run + jiffies_64_to_clock_t + __kfifo_init + kset_find_obj + kstrtobool_from_user + ktime_get_raw + led_classdev_unregister + memdup_user + __mmdrop + module_put + netlink_kernel_release + nla_put_nohdr + n_tty_ioctl_helper + of_devfreq_cooling_register_power + of_root + param_ops_byte + param_ops_string + perf_num_counters + pin_user_pages_remote + rb_prev + rb_replace_node + __release_region + __request_region + schedutil_cpu_util + sdio_claim_host + sdio_claim_irq + sdio_disable_func + sdio_enable_func + sdio_f0_readb + sdio_f0_writeb + sdio_get_host_pm_caps + sdio_readb + sdio_readl + sdio_readsb + sdio_register_driver + sdio_release_host + sdio_release_irq + sdio_set_block_size + sdio_set_host_pm_flags + sdio_unregister_driver + sdio_writeb + sdio_writel + sdio_writesb + send_sig_info + shmem_file_setup + si_meminfo + skb_pull_rcsum + skb_realloc_headroom + smp_call_function_single + snd_soc_component_test_bits + sprint_symbol_no_offset + strpbrk + strspn + syscore_resume + syscore_suspend + system_long_wq + thermal_zone_device_update + __traceiter_android_rvh_sched_rebalance_domains + __traceiter_android_vh_cgroup_attach + __traceiter_android_vh_is_fpsimd_save + __traceiter_android_vh_media_device_setup_link + __traceiter_android_vh_v4l2subdev_set_fmt + __traceiter_android_vh_v4l2subdev_set_frame_interval + __traceiter_android_vh_v4l2subdev_set_selection + __traceiter_gpu_mem_total + trace_output_call + __tracepoint_android_rvh_sched_rebalance_domains + __tracepoint_android_vh_cgroup_attach + __tracepoint_android_vh_is_fpsimd_save + __tracepoint_android_vh_media_device_setup_link + __tracepoint_android_vh_ufs_update_sdev + __tracepoint_android_vh_v4l2subdev_set_fmt + __tracepoint_android_vh_v4l2subdev_set_frame_interval + __tracepoint_android_vh_v4l2subdev_set_selection + __tracepoint_gpu_mem_total + trace_print_flags_seq + try_module_get + tty_driver_flush_buffer + tty_register_ldisc + tty_unregister_ldisc + ufshcd_auto_hibern8_update + ufshcd_shutdown + unmap_mapping_range + unregister_syscore_ops + v4l2_m2m_buf_remove_by_buf + vmf_insert_pfn_prot + wait_for_completion_killable_timeout + wireless_send_event + ww_mutex_lock_interruptible zlib_deflate zlib_deflateEnd zlib_deflateInit2 diff --git a/android/abi_gki_aarch64_oplus b/android/abi_gki_aarch64_oplus new file mode 100644 index 000000000000..8a16c1d45a1c --- /dev/null +++ b/android/abi_gki_aarch64_oplus @@ -0,0 +1,2058 @@ +[abi_symbol_list] + activate_task + add_cpu + add_device_randomness + add_memory + add_memory_subsection + add_timer + add_uevent_var + add_wait_queue + alloc_anon_inode + alloc_chrdev_region + __alloc_disk_node + alloc_io_pgtable_ops + __alloc_pages_nodemask + __alloc_percpu + __alloc_skb + alloc_skb_with_frags + alloc_workqueue + amba_bustype + amba_driver_register + amba_driver_unregister + android_debug_per_cpu_symbol + android_debug_symbol + android_rvh_probe_register + anon_inode_getfile + __arch_copy_from_user + __arch_copy_in_user + __arch_copy_to_user + arch_timer_read_counter + argv_free + argv_split + arm64_const_caps_ready + arm64_use_ng_mappings + __arm_smccc_smc + atomic_notifier_call_chain + atomic_notifier_chain_register + atomic_notifier_chain_unregister + available_idle_cpu + bdget_disk + bdput + bio_endio + bitmap_allocate_region + __bitmap_andnot + __bitmap_clear + bitmap_find_next_zero_area_off + __bitmap_or + bitmap_parselist_user + bitmap_print_to_pagebuf + bitmap_release_region + __bitmap_set + blk_alloc_queue + blk_cleanup_queue + blk_execute_rq_nowait + blk_get_request + blk_mq_rq_cpu + blk_put_request + blk_queue_flag_clear + blk_queue_flag_set + blk_queue_io_min + blk_queue_io_opt + blk_queue_logical_block_size + blk_queue_max_discard_sectors + blk_queue_max_write_zeroes_sectors + blk_queue_physical_block_size + blk_rq_map_user + blk_rq_map_user_iov + blk_rq_unmap_user + blk_verify_command + blocking_notifier_call_chain + blocking_notifier_chain_register + blocking_notifier_chain_unregister + bpf_trace_run10 + bpf_trace_run12 + bpf_trace_run1 + bpf_trace_run2 + bpf_trace_run3 + bpf_trace_run4 + bpf_trace_run5 + bpf_trace_run6 + bpf_trace_run7 + bpf_trace_run8 + bpf_trace_run9 + bus_find_device + bus_for_each_dev + bus_register + bus_set_iommu + bus_unregister + cancel_delayed_work + cancel_delayed_work_sync + cancel_work_sync + capable + cdev_add + cdev_alloc + cdev_del + cdev_device_add + cdev_device_del + cdev_init + __cfi_slowpath + cgroup_path_ns + cgroup_taskset_first + cgroup_taskset_next + __check_object_size + check_preempt_curr + check_zeroed_user + __class_create + class_destroy + class_find_device + class_for_each_device + class_interface_unregister + __class_register + class_unregister + cleanup_srcu_struct + clear_page + __ClearPageMovable + clk_bulk_disable + clk_bulk_enable + clk_bulk_prepare + clk_bulk_put_all + clk_bulk_unprepare + __clk_determine_rate + clk_disable + clk_enable + clk_fixed_factor_ops + clk_fixed_rate_ops + clk_get + __clk_get_hw + __clk_get_name + clk_get_parent + clk_get_rate + clk_hw_get_flags + clk_hw_get_name + clk_hw_get_num_parents + clk_hw_get_parent + clk_hw_get_parent_by_index + clk_hw_get_rate + clk_hw_is_enabled + clk_hw_is_prepared + clk_hw_register + clk_hw_round_rate + clk_hw_unregister + __clk_is_enabled + __clk_mux_determine_rate_closest + clk_notifier_register + clk_notifier_unregister + clk_prepare + clk_put + clk_round_rate + clk_set_parent + clk_set_rate + clk_sync_state + clk_unprepare + cma_alloc + cma_get_name + cma_release + compat_alloc_user_space + compat_ptr_ioctl + complete + complete_all + completion_done + component_add + component_bind_all + component_del + component_master_add_with_match + component_master_del + component_match_add_release + component_unbind_all + config_ep_by_speed + configfs_register_subsystem + configfs_unregister_subsystem + config_group_init + config_group_init_type_name + config_item_get + config_item_put + console_stop + console_suspend_enabled + __const_udelay + consume_skb + contig_page_data + _copy_from_iter_full + __cpu_active_mask + cpu_bit_bitmap + cpufreq_cooling_unregister + cpufreq_cpu_get + cpufreq_cpu_get_raw + cpufreq_cpu_put + cpufreq_disable_fast_switch + cpufreq_driver_fast_switch + cpufreq_driver_resolve_freq + __cpufreq_driver_target + cpufreq_enable_fast_switch + cpufreq_freq_attr_scaling_available_freqs + cpufreq_freq_attr_scaling_boost_freqs + cpufreq_generic_frequency_table_verify + cpufreq_get_policy + cpufreq_register_driver + cpufreq_register_governor + cpufreq_register_notifier + cpufreq_unregister_driver + cpufreq_unregister_notifier + __cpuhp_remove_state + __cpuhp_setup_state + __cpuhp_setup_state_cpuslocked + __cpuhp_state_add_instance + __cpuhp_state_remove_instance + cpu_hwcap_keys + cpu_hwcaps + cpuidle_governor_latency_req + cpuidle_register_governor + cpu_irqtime + cpu_latency_qos_add_request + cpu_latency_qos_remove_request + cpu_latency_qos_request_active + cpu_latency_qos_update_request + cpu_maps_update_begin + cpu_maps_update_done + cpumask_next + cpumask_next_and + cpu_number + __cpu_online_mask + cpu_pm_register_notifier + cpu_pm_unregister_notifier + __cpu_possible_mask + __cpu_present_mask + cpupri_find_fitness + cpu_scale + cpus_read_lock + cpus_read_unlock + cpu_subsys + cpu_topology + crc32_le + crc8 + crc8_populate_msb + crypto_alloc_base + crypto_alloc_shash + crypto_comp_compress + crypto_comp_decompress + crypto_destroy_tfm + crypto_has_alg + crypto_register_alg + crypto_register_rngs + crypto_register_scomp + crypto_shash_digest + crypto_unregister_alg + crypto_unregister_rngs + crypto_unregister_scomp + css_next_child + _ctype + datagram_poll + deactivate_task + debugfs_attr_read + debugfs_attr_write + debugfs_create_bool + debugfs_create_dir + debugfs_create_file + debugfs_create_file_unsafe + debugfs_create_u32 + debugfs_create_u8 + debugfs_create_x32 + debugfs_create_x8 + debugfs_file_get + debugfs_file_put + debugfs_lookup + debugfs_remove + dec_zone_page_state + default_llseek + deferred_free + delayed_work_timer_fn + del_gendisk + del_timer + del_timer_sync + desc_to_gpio + destroy_workqueue + dev_coredumpv + _dev_crit + dev_driver_string + _dev_err + devfreq_add_device + devfreq_add_governor + devfreq_cooling_unregister + devfreq_get_devfreq_by_node + devfreq_remove_device + devfreq_remove_governor + devfreq_resume_device + devfreq_suspend_device + dev_fwnode + dev_get_by_name + dev_get_regmap + device_add + device_add_disk + device_add_groups + device_create + device_create_file + device_del + device_destroy + device_find_child + device_for_each_child + device_get_match_data + device_initialize + device_init_wakeup + device_link_add + device_match_fwnode + device_match_name + device_property_present + device_property_read_string + device_property_read_u16_array + device_property_read_u32_array + device_register + device_remove_file + device_show_int + device_store_int + device_unregister + device_wakeup_disable + device_wakeup_enable + _dev_info + devm_add_action + devm_blk_ksm_init + devm_clk_bulk_get_all + devm_clk_get + devm_clk_hw_register + devm_clk_put + devm_clk_register + devm_device_add_group + devm_device_remove_group + devm_extcon_dev_allocate + devm_extcon_dev_register + devm_extcon_dev_unregister + devm_free_irq + devm_gpiod_get_optional + devm_gpio_free + devm_gpio_request + devm_gpio_request_one + devm_hwspin_lock_register + devm_iio_channel_get + devm_iio_device_alloc + __devm_iio_device_register + devm_input_allocate_device + devm_ioremap + devm_ioremap_resource + devm_ioremap_wc + devm_iounmap + devm_kasprintf + devm_kfree + devm_kmalloc + devm_kmemdup + devm_kstrdup + devm_led_classdev_register_ext + devm_nvmem_cell_get + devm_nvmem_device_get + devm_nvmem_register + devm_of_clk_add_hw_provider + devm_of_icc_get + __devm_of_phy_provider_register + devm_of_platform_populate + devm_of_pwm_get + devm_pci_alloc_host_bridge + devm_phy_create + devm_phy_get + devm_pinctrl_get + devm_pinctrl_put + devm_pinctrl_register + devm_platform_ioremap_resource + devm_platform_ioremap_resource_byname + devm_power_supply_register + devm_regmap_field_alloc + __devm_regmap_init + __devm_regmap_init_i2c + __devm_regmap_init_mmio_clk + devm_regulator_bulk_get + devm_regulator_get + devm_regulator_get_optional + devm_regulator_put + devm_regulator_register + devm_regulator_register_notifier + devm_request_any_context_irq + devm_request_threaded_irq + __devm_reset_control_get + devm_reset_controller_register + devm_rtc_allocate_device + devm_thermal_of_cooling_device_register + devm_thermal_zone_of_sensor_register + devm_usb_get_phy_by_node + _dev_notice + dev_pm_domain_attach + dev_pm_domain_attach_by_name + dev_pm_domain_detach + dev_pm_genpd_add_notifier + dev_pm_genpd_remove_notifier + dev_pm_genpd_set_next_wakeup + dev_pm_genpd_set_performance_state + dev_pm_opp_add + dev_pm_opp_find_freq_ceil + dev_pm_opp_find_freq_exact + dev_pm_opp_find_freq_floor + dev_pm_opp_get_opp_count + dev_pm_opp_get_voltage + dev_pm_opp_of_add_table + dev_pm_opp_of_find_icc_paths + dev_pm_opp_of_register_em + dev_pm_opp_of_remove_table + dev_pm_opp_put + dev_pm_opp_put_clkname + dev_pm_opp_remove_all_dynamic + dev_pm_opp_set_clkname + dev_pm_opp_set_rate + dev_pm_opp_set_sharing_cpus + dev_pm_qos_add_notifier + dev_pm_qos_add_request + dev_pm_qos_read_value + dev_pm_qos_remove_notifier + dev_pm_qos_remove_request + dev_pm_qos_update_request + devres_add + devres_alloc_node + devres_destroy + devres_free + devres_release + dev_set_name + _dev_warn + disable_irq + disable_irq_nosync + disable_percpu_irq + disk_end_io_acct + disk_start_io_acct + divider_get_val + divider_recalc_rate + divider_ro_round_rate_parent + divider_round_rate_parent + dma_alloc_attrs + dma_async_device_register + dma_async_device_unregister + dma_async_tx_descriptor_init + dma_buf_attach + dma_buf_begin_cpu_access + dma_buf_begin_cpu_access_partial + dma_buf_detach + dma_buf_end_cpu_access + dma_buf_end_cpu_access_partial + dma_buf_export + dma_buf_fd + dma_buf_get + dma_buf_map_attachment + dma_buf_put + dma_buf_unmap_attachment + dma_buf_vmap + dma_buf_vunmap + dma_contiguous_default_area + dma_fence_add_callback + dma_fence_array_create + dma_fence_array_ops + dma_fence_context_alloc + dma_fence_default_wait + dma_fence_enable_sw_signaling + dma_fence_free + dma_fence_get_status + dma_fence_init + dma_fence_release + dma_fence_remove_callback + dma_fence_signal + dma_fence_signal_locked + dma_fence_wait_timeout + dma_free_attrs + dma_get_sgtable_attrs + dma_get_slave_channel + dma_heap_add + dma_heap_buffer_alloc + dma_heap_find + dma_heap_get_dev + dma_heap_get_drvdata + dma_heap_get_name + dmam_alloc_attrs + dma_map_page_attrs + dma_map_resource + dma_map_sg_attrs + dmam_free_coherent + dma_release_channel + dma_request_chan + dma_set_coherent_mask + dma_set_mask + dma_sync_sg_for_cpu + dma_sync_sg_for_device + dma_sync_single_for_cpu + dma_sync_single_for_device + dma_unmap_page_attrs + dma_unmap_resource + dma_unmap_sg_attrs + do_exit + down_read + down_write + d_path + dput + drain_workqueue + driver_find_device + driver_register + driver_unregister + dump_stack + edac_device_add_device + edac_device_alloc_ctl_info + edac_device_alloc_index + edac_device_del_device + edac_device_free_ctl_info + edac_device_handle_ce_count + edac_device_handle_ue_count + enable_irq + enable_percpu_irq + eventfd_ctx_fdget + eventfd_ctx_fileget + eventfd_ctx_put + eventfd_ctx_remove_wait_queue + eventfd_signal + event_triggers_call + extcon_get_edev_by_phandle + extcon_get_edev_name + extcon_get_property + extcon_get_state + extcon_register_notifier + extcon_set_state_sync + failure_tracking + fasync_helper + __fdget + fd_install + fget + filp_close + filp_open_block + find_last_bit + find_next_bit + find_next_zero_bit + find_snd_usb_substream + find_task_by_vpid + find_vma + find_vpid + finish_wait + firmware_request_nowarn + flush_dcache_page + flush_delayed_work + flush_work + flush_workqueue + fput + free_io_pgtable_ops + free_irq + __free_pages + free_pages + free_percpu + free_percpu_irq + freq_qos_add_request + freq_qos_remove_request + freq_qos_update_request + freq_scale + fsync_bdev + fwnode_find_reference + fwnode_get_next_child_node + fwnode_handle_get + fwnode_handle_put + fwnode_property_present + fwnode_property_read_string + fwnode_property_read_u32_array + generic_device_group + generic_handle_irq + generic_iommu_put_resv_regions + genlmsg_put + genl_register_family + genl_unregister_family + gen_pool_add_owner + gen_pool_alloc_algo_owner + gen_pool_avail + gen_pool_best_fit + gen_pool_create + gen_pool_destroy + gen_pool_first_fit_order_align + gen_pool_free_owner + gen_pool_has_addr + gen_pool_set_algo + gen_pool_size + gen_pool_virt_to_phys + getboottime64 + get_cpu_device + get_device + get_each_dmabuf + get_each_object_track + __get_free_pages + get_governor_parent_kobj + get_option + get_page_owner_handle + get_pfnblock_flags_mask + get_pid_task + get_random_bytes + get_random_u32 + get_sg_io_hdr + get_slabinfo + __get_task_comm + get_task_mm + get_task_pid + get_unmapped_area + get_unused_fd_flags + get_user_pages + gic_nonsecure_priorities + gov_attr_set_init + gov_attr_set_put + governor_sysfs_ops + gpiochip_add_data_with_key + gpiochip_add_pin_range + gpiochip_generic_free + gpiochip_generic_request + gpiochip_get_data + gpiochip_line_is_valid + gpiochip_lock_as_irq + gpiochip_remove + gpiochip_unlock_as_irq + gpiod_direction_input + gpiod_direction_output + gpiod_direction_output_raw + gpiod_get_optional + gpiod_get_raw_value + gpiod_get_value + gpiod_set_raw_value + gpiod_set_value + gpiod_set_value_cansleep + gpiod_to_irq + gpio_free + gpio_request + gpio_to_desc + handle_bad_irq + handle_edge_irq + handle_fasteoi_ack_irq + handle_fasteoi_irq + handle_level_irq + handle_nested_irq + handle_simple_irq + handle_sysrq + hashlen_string + hex_dump_to_buffer + hrtimer_active + hrtimer_cancel + hrtimer_forward + __hrtimer_get_remaining + hrtimer_init + hrtimer_start_range_ns + hrtimer_try_to_cancel + hvc_alloc + hvc_kick + hvc_poll + hvc_remove + hwrng_register + hwrng_unregister + hwspin_lock_free + hwspin_lock_request_specific + __hwspin_lock_timeout + __hwspin_unlock + hypervisor_kobj + i2c_add_adapter + i2c_del_adapter + i2c_del_driver + i2c_get_dma_safe_msg_buf + i2c_put_dma_safe_msg_buf + i2c_register_driver + i2c_smbus_read_byte_data + i2c_smbus_read_i2c_block_data + i2c_smbus_read_word_data + i2c_smbus_write_byte_data + i2c_smbus_write_i2c_block_data + i2c_smbus_write_word_data + i2c_transfer + i2c_transfer_buffer_flags + icc_get + icc_link_create + icc_node_add + icc_node_create + icc_node_del + icc_node_destroy + icc_provider_add + icc_provider_del + icc_put + icc_set_bw + icc_set_tag + ida_alloc_range + ida_free + idr_alloc + idr_alloc_cyclic + idr_destroy + idr_find + idr_for_each + idr_get_next + idr_preload + idr_remove + idr_replace + iio_channel_get + iio_channel_get_all + iio_channel_release + iio_read_channel_processed + import_iovec + inc_node_page_state + inc_zone_page_state + in_egroup_p + init_iova_domain + init_net + init_pseudo + __init_rwsem + init_srcu_struct + __init_swait_queue_head + init_task + init_timer_key + init_uts_ns + init_wait_entry + __init_waitqueue_head + input_alloc_absinfo + input_allocate_device + input_close_device + input_event + input_ff_create + input_ff_destroy + input_free_device + input_mt_init_slots + input_mt_report_pointer_emulation + input_mt_report_slot_state + input_open_device + input_register_device + input_register_handle + input_register_handler + input_set_abs_params + input_set_capability + input_unregister_device + input_unregister_handle + input_unregister_handler + interval_tree_insert + interval_tree_iter_first + interval_tree_iter_next + interval_tree_remove + int_sqrt + iommu_alloc_resv_region + iommu_attach_device + iommu_detach_device + iommu_device_register + iommu_device_sysfs_add + iommu_device_sysfs_remove + iommu_device_unregister + iommu_dma_get_resv_regions + iommu_domain_alloc + iommu_domain_free + iommu_domain_get_attr + iommu_domain_set_attr + iommu_fwspec_add_ids + iommu_fwspec_free + iommu_get_dma_cookie + iommu_get_domain_for_dev + iommu_get_msi_cookie + iommu_group_for_each_dev + iommu_group_get + iommu_group_get_iommudata + iommu_group_put + iommu_group_ref_get + iommu_group_set_iommudata + iommu_iova_to_phys + iommu_map + iommu_map_sg + iommu_present + iommu_put_dma_cookie + iommu_set_fault_handler + iommu_unmap + __ioread32_copy + __ioremap + iounmap + __iowrite32_copy + ipi_desc_get + iput + irq_chip_ack_parent + irq_chip_disable_parent + irq_chip_enable_parent + irq_chip_eoi_parent + irq_chip_get_parent_state + irq_chip_mask_parent + irq_chip_retrigger_hierarchy + irq_chip_set_affinity_parent + irq_chip_set_parent_state + irq_chip_set_type_parent + irq_chip_set_vcpu_affinity_parent + irq_chip_set_wake_parent + irq_chip_unmask_parent + irq_create_fwspec_mapping + irq_dispose_mapping + __irq_domain_add + irq_domain_alloc_irqs_parent + irq_domain_create_hierarchy + irq_domain_free_irqs_common + irq_domain_free_irqs_parent + irq_domain_get_irq_data + irq_domain_remove + irq_domain_set_hwirq_and_chip + irq_domain_set_info + irq_domain_update_bus_token + irq_domain_xlate_twocell + irq_do_set_affinity + irq_find_mapping + irq_find_matching_fwspec + irq_get_irqchip_state + irq_get_irq_data + irq_modify_status + irq_of_parse_and_map + irq_set_affinity_hint + irq_set_affinity_notifier + irq_set_chained_handler_and_data + irq_set_chip_and_handler_name + irq_set_chip_data + irq_set_irqchip_state + irq_set_irq_type + irq_set_irq_wake + irq_set_parent + irq_to_desc + irq_work_queue + irq_work_queue_on + irq_work_sync + is_dma_buf_file + isolate_and_split_free_page + isolate_anon_lru_page + is_vmalloc_addr + jiffies + jiffies_to_msecs + jiffies_to_usecs + kasan_flag_enabled + kasprintf + kernel_bind + kernel_connect + kernel_getsockname + kernel_kobj + kernel_power_off + kernel_recvmsg + kernel_restart + kernel_sendmsg + kern_mount + kern_unmount + __kfifo_alloc + __kfifo_in + __kfifo_out + kfree + kfree_const + kfree_sensitive + kfree_skb + kill_anon_super + kill_fasync + kimage_vaddr + kimage_voffset + __kmalloc + kmalloc_caches + kmalloc_order_trace + kmem_cache_alloc + kmem_cache_alloc_trace + kmem_cache_create + kmem_cache_create_usercopy + kmem_cache_destroy + kmem_cache_free + kmemdup + kmemdup_nul + kobject_add + kobject_create_and_add + kobject_del + kobject_init + kobject_init_and_add + kobject_put + kobject_set_name + kobject_uevent + kobj_sysfs_ops + krealloc + kset_create_and_add + ksize + ksoftirqd + kstat + kstat_irqs_cpu + kstat_irqs_usr + kstrdup + kstrdup_const + kstrndup + kstrtobool + kstrtoint + kstrtoll + kstrtou16 + kstrtou16_from_user + kstrtou8 + kstrtou8_from_user + kstrtouint + kstrtouint_from_user + kstrtoul_from_user + kstrtoull + kstrtoull_from_user + kthread_bind_mask + kthread_cancel_work_sync + kthread_create_on_node + kthread_create_worker + kthread_destroy_worker + kthread_flush_worker + __kthread_init_worker + kthread_queue_work + kthread_should_stop + kthread_stop + kthread_worker_fn + ktime_get + ktime_get_mono_fast_ns + ktime_get_real_seconds + ktime_get_real_ts64 + kvfree + kvmalloc_node + led_classdev_flash_register_ext + led_classdev_flash_unregister + led_classdev_unregister + __list_add_valid + __list_del_entry_valid + list_sort + llist_add_batch + llist_reverse_order + __lock_page + lock_sock_nested + log_buf_addr_get + log_buf_len_get + __log_post_read_mmio + __log_read_mmio + __log_write_mmio + lookup_page_ext + lzo1x_1_compress + lzo1x_decompress_safe + lzorle1x_1_compress + match_string + mbox_chan_received_data + mbox_chan_txdone + mbox_client_txdone + mbox_controller_register + mbox_controller_unregister + mbox_free_channel + mbox_request_channel + mbox_send_message + memblock_end_of_DRAM + __memcat_p + memchr + memcpy + __memcpy_fromio + __memcpy_toio + memdup_user + memmove + memory_block_size_bytes + memory_read_from_buffer + memparse + mempool_alloc + mempool_alloc_slab + mempool_create + mempool_destroy + mempool_free + mempool_free_slab + memremap + memset64 + memset + __memset_io + memstart_addr + memunmap + migrate_pages + migrate_swap + misc_deregister + misc_register + mmc_cqe_request_done + mmc_of_parse + mmc_regulator_get_supply + mmc_regulator_set_ocr + mmc_regulator_set_vqmmc + mmc_send_tuning + mmput + mod_delayed_work_on + mod_node_page_state + mod_timer + __module_get + module_layout + module_put + __msecs_to_jiffies + msleep + msleep_interruptible + __mutex_init + mutex_is_locked + mutex_lock + mutex_lock_interruptible + mutex_trylock + mutex_unlock + netlink_broadcast + __netlink_kernel_create + netlink_kernel_release + netlink_unicast + nla_find + nla_put + nla_reserve_64bit + nla_reserve + __nla_validate + __nlmsg_put + no_llseek + nonseekable_open + noop_llseek + nr_cpu_ids + nr_ipi_get + nr_irqs + ns_to_timespec64 + __num_online_cpus + nvmem_cell_get + nvmem_cell_put + nvmem_cell_read + nvmem_cell_read_u32 + nvmem_cell_write + nvmem_device_read + nvmem_device_write + of_address_to_resource + of_alias_get_id + of_clk_add_hw_provider + of_clk_add_provider + of_clk_del_provider + of_clk_hw_simple_get + of_clk_src_simple_get + of_count_phandle_with_args + of_cpufreq_cooling_register + of_cpu_node_to_id + of_devfreq_cooling_register + of_device_get_match_data + of_device_is_available + of_device_is_compatible + of_dma_configure_id + of_dma_controller_free + of_dma_controller_register + of_dma_is_coherent + of_drm_find_panel + of_find_compatible_node + of_find_device_by_node + of_find_i2c_device_by_node + of_find_matching_node_and_match + of_find_node_by_name + of_find_node_by_phandle + of_find_node_opts_by_path + of_find_node_with_property + of_find_property + of_fwnode_ops + of_genpd_add_provider_onecell + of_genpd_del_provider + of_get_address + of_get_child_by_name + of_get_cpu_node + of_get_named_gpio_flags + of_get_next_available_child + of_get_next_child + of_get_next_parent + of_get_property + of_get_regulator_init_data + of_graph_get_next_endpoint + of_graph_get_port_parent + of_graph_get_remote_endpoint + of_graph_is_present + of_graph_parse_endpoint + of_hwspin_lock_get_id + of_icc_get + of_icc_xlate_onecell + of_iomap + of_irq_find_parent + of_irq_get + of_irq_get_byname + of_irq_parse_one + of_match_device + of_match_node + of_n_addr_cells + of_node_name_eq + of_n_size_cells + of_parse_phandle + of_parse_phandle_with_args + of_parse_phandle_with_fixed_args + of_phandle_iterator_init + of_phandle_iterator_next + of_phy_simple_xlate + of_platform_depopulate + of_platform_device_create + of_platform_device_destroy + of_platform_populate + of_property_count_elems_of_size + of_property_match_string + of_property_read_string + of_property_read_string_helper + of_property_read_u32_index + of_property_read_u64_index + of_property_read_variable_u32_array + of_property_read_variable_u8_array + of_prop_next_string + of_prop_next_u32 + of_reserved_mem_device_init_by_idx + of_reserved_mem_device_release + of_reserved_mem_lookup + of_root + of_thermal_get_ntrips + of_thermal_get_trip_points + of_thermal_is_trip_valid + of_translate_address + on_each_cpu + oops_in_progress + overflowuid + page_endio + page_mapping + __page_pinner_migration_failed + panic + panic_notifier_list + panic_timeout + param_get_int + param_ops_bool + param_ops_int + param_ops_string + param_ops_uint + param_set_bool + pause_cpus + pci_alloc_irq_vectors_affinity + pci_assign_resource + pci_bus_type + pci_clear_master + pci_device_group + pci_dev_present + pci_disable_device + pcie_capability_read_word + pci_enable_device + pci_find_ext_capability + pci_free_irq_vectors + pci_get_device + pci_host_probe + pci_iomap + pci_irq_vector + pci_load_and_free_saved_state + pci_load_saved_state + pci_msi_create_irq_domain + pci_msi_mask_irq + pci_msi_unmask_irq + pci_read_config_dword + pci_read_config_word + __pci_register_driver + pci_release_region + pci_request_region + pci_restore_state + pci_save_state + pci_set_master + pci_set_power_state + pci_store_saved_state + pci_unregister_driver + pci_walk_bus + pci_write_config_dword + pcpu_nr_pages + PDE_DATA + __per_cpu_offset + per_cpu_ptr_to_phys + perf_aux_output_begin + perf_aux_output_end + perf_aux_output_flag + perf_event_create_kernel_counter + perf_event_enable + perf_event_read_local + perf_event_read_value + perf_event_release_kernel + perf_get_aux + perf_pmu_register + perf_pmu_unregister + perf_trace_buf_alloc + perf_trace_run_bpf_submit + pfn_valid + phy_calibrate + phy_exit + phy_init + phy_power_off + phy_power_on + phy_set_mode_ext + pick_highest_pushable_task + pid_nr_ns + pid_task + pinconf_generic_dt_node_to_map + pinctrl_dev_get_drvdata + pinctrl_force_default + pinctrl_force_sleep + pinctrl_lookup_state + pinctrl_pm_select_default_state + pinctrl_pm_select_sleep_state + pinctrl_select_state + pinctrl_utils_free_map + platform_bus_type + platform_device_add + platform_device_alloc + platform_device_del + platform_device_put + platform_device_register + platform_device_register_full + platform_device_unregister + __platform_driver_register + platform_driver_unregister + platform_get_irq + platform_get_irq_byname + platform_get_resource + platform_get_resource_byname + platform_irq_count + pm_clk_add + pm_clk_create + pm_clk_destroy + pm_clk_resume + pm_clk_suspend + pm_genpd_add_subdomain + pm_genpd_init + pm_genpd_remove + pm_genpd_remove_subdomain + pm_power_off + __pm_relax + pm_relax + pm_runtime_allow + pm_runtime_barrier + __pm_runtime_disable + pm_runtime_enable + pm_runtime_forbid + pm_runtime_force_resume + pm_runtime_force_suspend + __pm_runtime_idle + pm_runtime_irq_safe + pm_runtime_no_callbacks + __pm_runtime_resume + pm_runtime_set_autosuspend_delay + __pm_runtime_set_status + __pm_runtime_suspend + __pm_runtime_use_autosuspend + __pm_stay_awake + pm_stay_awake + pm_system_wakeup + pm_wakeup_dev_event + pm_wakeup_ws_event + power_supply_changed + power_supply_get_by_name + power_supply_get_drvdata + power_supply_get_property + power_supply_put + power_supply_reg_notifier + power_supply_set_property + power_supply_unregister + power_supply_unreg_notifier + prandom_u32 + preempt_schedule + preempt_schedule_notrace + prepare_to_wait_event + print_hex_dump + printk + printk_deferred + proc_create + proc_create_data + proc_dointvec + proc_dointvec_minmax + proc_dostring + proc_douintvec_minmax + proc_mkdir + proc_remove + proc_symlink + proto_register + proto_unregister + __pskb_pull_tail + public_key_verify_signature + putback_movable_pages + put_device + put_disk + put_iova_domain + __put_page + put_pid + put_sg_io_hdr + __put_task_struct + put_unused_fd + pwm_apply_state + pwmchip_add + pwmchip_remove + qcom_smem_state_get + qcom_smem_state_register + qcom_smem_state_unregister + qcom_smem_state_update_bits + queue_delayed_work_on + queue_work_on + radix_tree_insert + radix_tree_iter_delete + radix_tree_lookup + radix_tree_next_chunk + ___ratelimit + rational_best_approximation + raw_notifier_call_chain + raw_notifier_chain_register + raw_notifier_chain_unregister + _raw_read_lock + _raw_read_lock_bh + _raw_read_lock_irq + _raw_read_lock_irqsave + _raw_read_unlock + _raw_read_unlock_bh + _raw_read_unlock_irq + _raw_read_unlock_irqrestore + _raw_spin_lock + _raw_spin_lock_bh + _raw_spin_lock_irq + _raw_spin_lock_irqsave + _raw_spin_trylock + _raw_spin_trylock_bh + _raw_spin_unlock + _raw_spin_unlock_bh + _raw_spin_unlock_irq + _raw_spin_unlock_irqrestore + _raw_write_lock + _raw_write_lock_bh + _raw_write_lock_irq + _raw_write_lock_irqsave + _raw_write_unlock + _raw_write_unlock_bh + _raw_write_unlock_irq + _raw_write_unlock_irqrestore + rb_erase + rb_first + rb_insert_color + rb_last + rb_next + rb_prev + __rcu_read_lock + __rcu_read_unlock + rdev_get_drvdata + reboot_mode + refcount_dec_and_lock + refcount_dec_not_one + refcount_warn_saturate + register_blkdev + __register_chrdev + register_chrdev_region + register_console + register_die_notifier + register_ftrace_export + register_kretprobe + register_memory_notifier + register_module_notifier + register_pm_notifier + register_reboot_notifier + register_restart_handler + __register_rpmsg_driver + register_shrinker + register_syscore_ops + register_sysctl_table + regmap_bulk_read + regmap_bulk_write + regmap_check_range_table + regmap_field_read + regmap_field_update_bits_base + __regmap_init + regmap_mmio_detach_clk + regmap_read + regmap_update_bits_base + regmap_write + regulator_allow_bypass + regulator_bulk_disable + regulator_count_voltages + regulator_disable + regulator_enable + regulator_force_disable + regulator_get + regulator_get_drvdata + regulator_get_mode + regulator_get_voltage + regulator_get_voltage_rdev + regulator_is_enabled + regulator_is_supported_voltage + regulator_list_voltage_linear + regulator_notifier_call_chain + regulator_put + regulator_register_notifier + regulator_set_current_limit + regulator_set_load + regulator_set_mode + regulator_set_voltage + regulator_unregister_notifier + release_firmware + release_sock + remap_pfn_range + remove_cpu + remove_memory_subsection + remove_proc_entry + remove_proc_subtree + report_iommu_fault + request_any_context_irq + request_firmware + request_firmware_into_buf + request_firmware_nowait + __request_module + __request_percpu_irq + request_threaded_irq + resched_curr + reset_control_assert + reset_control_deassert + resume_cpus + revalidate_disk_size + rfkill_alloc + rfkill_destroy + rfkill_init_sw_state + rfkill_register + rfkill_unregister + rndis_deregister + rndis_free_response + rndis_get_next_response + rndis_msg_parser + rndis_register + rndis_set_host_mac + rndis_set_param_dev + rndis_set_param_medium + rndis_set_param_vendor + rndis_signal_connect + rndis_uninit + root_task_group + round_jiffies_relative + rpmsg_get_signals + rpmsg_poll + rpmsg_register_device + rpmsg_send + rpmsg_set_signals + rpmsg_trysend + rpmsg_unregister_device + rproc_add + rproc_add_subdev + rproc_alloc + rproc_boot + rproc_coredump_add_custom_segment + rproc_coredump_add_segment + rproc_coredump_set_elf_info + rproc_coredump_using_sections + rproc_del + rproc_free + rproc_get_by_child + rproc_get_by_phandle + rproc_put + rproc_remove_subdev + rproc_report_crash + rproc_shutdown + rtc_class_close + rtc_class_open + rtc_read_time + __rtc_register_device + rtc_time64_to_tm + rtc_tm_to_time64 + rtc_update_irq + rtc_valid_tm + runqueues + sched_clock + sched_feat_keys + sched_feat_names + sched_set_fifo + sched_set_normal + sched_setscheduler + sched_setscheduler_nocheck + sched_trace_rd_span + sched_uclamp_used + schedule + schedule_timeout + schedule_timeout_interruptible + scnprintf + scsi_autopm_get_device + scsi_autopm_put_device + scsi_block_when_processing_errors + scsi_command_size_tbl + scsi_compat_ioctl + scsi_device_get + scsi_device_put + scsi_device_quiesce + scsi_ioctl + scsi_ioctl_block_when_processing_errors + __scsi_iterate_devices + scsi_normalize_sense + __scsi_print_sense + scsi_register_interface + scsi_remove_device + sdev_prefix_printk + __sdhci_add_host + sdhci_add_host + sdhci_cleanup_host + sdhci_cqe_disable + sdhci_cqe_enable + sdhci_cqe_irq + sdhci_enable_clk + sdhci_get_property + sdhci_pltfm_free + sdhci_pltfm_init + sdhci_remove_host + sdhci_request + sdhci_reset + sdhci_set_bus_width + sdhci_set_power_noreg + sdhci_setup_host + seq_buf_printf + seq_lseek + seq_open + seq_printf + seq_putc + seq_puts + seq_read + seq_release + seq_write + set_cpus_allowed_ptr + set_normalized_timespec64 + set_page_dirty_lock + __SetPageMovable + set_task_cpu + set_user_nice + sg_alloc_table + sg_alloc_table_from_pages + sg_free_table + sg_init_one + sg_init_table + sg_miter_next + sg_miter_start + sg_miter_stop + sg_next + __sg_page_iter_dma_next + __sg_page_iter_next + __sg_page_iter_start + sg_scsi_ioctl + show_regs + sigprocmask + si_mem_available + si_meminfo + simple_attr_open + simple_attr_release + simple_open + simple_read_from_buffer + simple_strtol + simple_strtoul + simple_write_to_buffer + single_open + single_release + si_swapinfo + sk_alloc + skb_clone + skb_copy_bits + skb_copy_datagram_iter + skb_dequeue + skb_free_datagram + __skb_pad + skb_push + skb_put + skb_queue_purge + skb_queue_tail + skb_recv_datagram + skb_set_owner_w + skb_store_bits + skb_trim + sk_free + skip_spaces + smp_call_function_single + snd_pcm_format_width + snd_soc_add_component_controls + snd_soc_info_volsw + snd_soc_register_component + snd_soc_unregister_component + snd_usb_enable_audio_stream + snprintf + soc_device_register + soc_device_unregister + sock_alloc_send_skb + sock_create_kern + sock_gettstamp + sock_init_data + sock_no_accept + sock_no_listen + sock_no_mmap + sock_no_sendpage + sock_no_shutdown + sock_no_socketpair + sock_queue_rcv_skb + sock_register + sock_release + sock_setsockopt + sock_unregister + sort + __spi_alloc_controller + spi_register_controller + __spi_register_driver + spi_setup + spi_sync + spi_unregister_controller + spmi_controller_add + spmi_controller_alloc + spmi_controller_remove + __spmi_driver_register + spmi_ext_register_read + spmi_ext_register_readl + spmi_ext_register_write + spmi_ext_register_writel + spmi_register_read + spmi_register_write + spmi_register_zero_write + sprintf + srcu_init_notifier_head + srcu_notifier_call_chain + srcu_notifier_chain_register + srcu_notifier_chain_unregister + __srcu_read_lock + __srcu_read_unlock + sscanf + __stack_chk_fail + __stack_chk_guard + stack_depot_fetch + static_key_disable + stop_machine + stop_one_cpu_nowait + stpcpy + strcasecmp + strcat + strchr + strcmp + strcpy + strim + strlcat + strlcpy + strlen + strncasecmp + strnchr + strncmp + strncpy + strncpy_from_user + strnlen + strnstr + strpbrk + strrchr + strscpy + strsep + strstr + __sw_hweight32 + __sw_hweight64 + __sw_hweight8 + sync_file_create + sync_file_get_fence + synchronize_irq + synchronize_rcu + synchronize_srcu + syscon_node_to_regmap + syscon_regmap_lookup_by_phandle + sysctl_sched_features + sysctl_sched_latency + sysctl_vals + sysfs_add_file_to_group + sysfs_add_link_to_group + sysfs_create_bin_file + sysfs_create_file_ns + sysfs_create_files + sysfs_create_group + sysfs_create_link + sysfs_emit + __sysfs_match_string + sysfs_notify + sysfs_remove_bin_file + sysfs_remove_file_from_group + sysfs_remove_file_ns + sysfs_remove_files + sysfs_remove_group + sysfs_remove_link + sysfs_remove_link_from_group + sysfs_streq + sysrq_mask + system_freezable_wq + system_highpri_wq + system_power_efficient_wq + system_unbound_wq + system_wq + task_active_pid_ns + __tasklet_hi_schedule + tasklet_init + tasklet_kill + __tasklet_schedule + tasklet_setup + tasklist_lock + task_may_not_preempt + __task_pid_nr_ns + __task_rq_lock + task_rq_lock + thermal_cooling_device_register + thermal_cooling_device_unregister + thermal_of_cooling_device_register + thermal_pressure + thermal_zone_device_enable + thermal_zone_device_register + thermal_zone_device_unregister + thermal_zone_device_update + thermal_zone_get_slope + thermal_zone_get_temp + thermal_zone_get_zone_by_name + thermal_zone_of_sensor_register + thermal_zone_of_sensor_unregister + tick_nohz_get_sleep_length + time64_to_tm + topology_set_thermal_pressure + topology_update_done + total_swapcache_pages + trace_array_get_by_name + trace_array_put + trace_array_set_clr_event + trace_event_buffer_commit + trace_event_buffer_reserve + trace_event_ignore_this_pid + trace_event_raw_init + trace_event_reg + trace_handle_return + __traceiter_android_rvh_account_irq + __traceiter_android_rvh_build_perf_domains + __traceiter_android_rvh_can_migrate_task + __traceiter_android_rvh_check_preempt_wakeup + __traceiter_android_rvh_cpu_cgroup_attach + __traceiter_android_rvh_cpu_cgroup_online + __traceiter_android_rvh_dequeue_task + __traceiter_android_rvh_enqueue_task + __traceiter_android_rvh_find_busiest_queue + __traceiter_android_rvh_find_lowest_rq + __traceiter_android_rvh_flush_task + __traceiter_android_rvh_force_compatible_post + __traceiter_android_rvh_force_compatible_pre + __traceiter_android_rvh_gic_v3_set_affinity + __traceiter_android_rvh_migrate_queued_task + __traceiter_android_rvh_new_task_stats + __traceiter_android_rvh_pick_next_entity + __traceiter_android_rvh_place_entity + __traceiter_android_rvh_replace_next_task_fair + __traceiter_android_rvh_resume_cpus + __traceiter_android_rvh_sched_cpu_dying + __traceiter_android_rvh_sched_cpu_starting + __traceiter_android_rvh_sched_exec + __traceiter_android_rvh_sched_fork + __traceiter_android_rvh_sched_fork_init + __traceiter_android_rvh_sched_newidle_balance + __traceiter_android_rvh_sched_nohz_balancer_kick + __traceiter_android_rvh_sched_setaffinity + __traceiter_android_rvh_schedule + __traceiter_android_rvh_select_task_rq_fair + __traceiter_android_rvh_select_task_rq_rt + __traceiter_android_rvh_set_gfp_zone_flags + __traceiter_android_rvh_set_readahead_gfp_mask + __traceiter_android_rvh_set_skip_swapcache_flags + __traceiter_android_rvh_set_task_cpu + __traceiter_android_rvh_tick_entry + __traceiter_android_rvh_try_to_wake_up + __traceiter_android_rvh_try_to_wake_up_success + __traceiter_android_rvh_ttwu_cond + __traceiter_android_rvh_update_cpu_capacity + __traceiter_android_rvh_update_cpus_allowed + __traceiter_android_rvh_update_misfit_status + __traceiter_android_rvh_wake_up_new_task + __traceiter_android_vh_allow_domain_state + __traceiter_android_vh_alter_mutex_list_add + __traceiter_android_vh_alter_rwsem_list_add + __traceiter_android_vh_binder_restore_priority + __traceiter_android_vh_binder_set_priority + __traceiter_android_vh_binder_wait_for_work + __traceiter_android_vh_binder_wakeup_ilocked + __traceiter_android_vh_build_sched_domains + __traceiter_android_vh_check_uninterruptible_tasks + __traceiter_android_vh_check_uninterruptible_tasks_dn + __traceiter_android_vh_cpu_idle_enter + __traceiter_android_vh_cpu_idle_exit + __traceiter_android_vh_ftrace_dump_buffer + __traceiter_android_vh_ftrace_format_check + __traceiter_android_vh_ftrace_oops_enter + __traceiter_android_vh_ftrace_oops_exit + __traceiter_android_vh_ftrace_size_check + __traceiter_android_vh_gpio_block_read + __traceiter_android_vh_iommu_setup_dma_ops + __traceiter_android_vh_ipi_stop + __traceiter_android_vh_jiffies_update + __traceiter_android_vh_logbuf + __traceiter_android_vh_mutex_unlock_slowpath + __traceiter_android_vh_mutex_wait_finish + __traceiter_android_vh_mutex_wait_start + __traceiter_android_vh_printk_hotplug + __traceiter_android_vh_rwsem_wake + __traceiter_android_vh_rwsem_wake_finish + __traceiter_android_vh_scheduler_tick + __traceiter_android_vh_show_max_freq + __traceiter_android_vh_show_resume_epoch_val + __traceiter_android_vh_show_suspend_epoch_val + __traceiter_android_vh_sync_txn_recvd + __traceiter_android_vh_timer_calc_index + __traceiter_android_vh_update_topology_flags_workfn + __traceiter_binder_transaction_received + __traceiter_cpu_frequency_limits + __traceiter_gpu_mem_total + __traceiter_ipi_entry + __traceiter_ipi_raise + __traceiter_irq_handler_entry + __traceiter_rwmmio_post_read + __traceiter_rwmmio_read + __traceiter_rwmmio_write + __traceiter_sched_overutilized_tp + __traceiter_sched_switch + __traceiter_suspend_resume + __tracepoint_android_rvh_account_irq + __tracepoint_android_rvh_build_perf_domains + __tracepoint_android_rvh_can_migrate_task + __tracepoint_android_rvh_check_preempt_wakeup + __tracepoint_android_rvh_cpu_cgroup_attach + __tracepoint_android_rvh_cpu_cgroup_online + __tracepoint_android_rvh_dequeue_task + __tracepoint_android_rvh_enqueue_task + __tracepoint_android_rvh_find_busiest_queue + __tracepoint_android_rvh_find_lowest_rq + __tracepoint_android_rvh_flush_task + __tracepoint_android_rvh_force_compatible_post + __tracepoint_android_rvh_force_compatible_pre + __tracepoint_android_rvh_gic_v3_set_affinity + __tracepoint_android_rvh_migrate_queued_task + __tracepoint_android_rvh_new_task_stats + __tracepoint_android_rvh_pick_next_entity + __tracepoint_android_rvh_place_entity + __tracepoint_android_rvh_replace_next_task_fair + __tracepoint_android_rvh_resume_cpus + __tracepoint_android_rvh_sched_cpu_dying + __tracepoint_android_rvh_sched_cpu_starting + __tracepoint_android_rvh_sched_exec + __tracepoint_android_rvh_sched_fork + __tracepoint_android_rvh_sched_fork_init + __tracepoint_android_rvh_sched_newidle_balance + __tracepoint_android_rvh_sched_nohz_balancer_kick + __tracepoint_android_rvh_sched_setaffinity + __tracepoint_android_rvh_schedule + __tracepoint_android_rvh_select_task_rq_fair + __tracepoint_android_rvh_select_task_rq_rt + __tracepoint_android_rvh_set_gfp_zone_flags + __tracepoint_android_rvh_set_readahead_gfp_mask + __tracepoint_android_rvh_set_skip_swapcache_flags + __tracepoint_android_rvh_set_task_cpu + __tracepoint_android_rvh_tick_entry + __tracepoint_android_rvh_try_to_wake_up + __tracepoint_android_rvh_try_to_wake_up_success + __tracepoint_android_rvh_ttwu_cond + __tracepoint_android_rvh_update_cpu_capacity + __tracepoint_android_rvh_update_cpus_allowed + __tracepoint_android_rvh_update_misfit_status + __tracepoint_android_rvh_wake_up_new_task + __tracepoint_android_vh_allow_domain_state + __tracepoint_android_vh_alter_mutex_list_add + __tracepoint_android_vh_alter_rwsem_list_add + __tracepoint_android_vh_binder_restore_priority + __tracepoint_android_vh_binder_set_priority + __tracepoint_android_vh_binder_wait_for_work + __tracepoint_android_vh_binder_wakeup_ilocked + __tracepoint_android_vh_build_sched_domains + __tracepoint_android_vh_check_uninterruptible_tasks + __tracepoint_android_vh_check_uninterruptible_tasks_dn + __tracepoint_android_vh_cpu_idle_enter + __tracepoint_android_vh_cpu_idle_exit + __tracepoint_android_vh_ftrace_dump_buffer + __tracepoint_android_vh_ftrace_format_check + __tracepoint_android_vh_ftrace_oops_enter + __tracepoint_android_vh_ftrace_oops_exit + __tracepoint_android_vh_ftrace_size_check + __tracepoint_android_vh_gpio_block_read + __tracepoint_android_vh_iommu_setup_dma_ops + __tracepoint_android_vh_ipi_stop + __tracepoint_android_vh_jiffies_update + __tracepoint_android_vh_logbuf + __tracepoint_android_vh_mutex_unlock_slowpath + __tracepoint_android_vh_mutex_wait_finish + __tracepoint_android_vh_mutex_wait_start + __tracepoint_android_vh_printk_hotplug + __tracepoint_android_vh_rwsem_wake + __tracepoint_android_vh_rwsem_wake_finish + __tracepoint_android_vh_scheduler_tick + __tracepoint_android_vh_show_max_freq + __tracepoint_android_vh_show_resume_epoch_val + __tracepoint_android_vh_show_suspend_epoch_val + __tracepoint_android_vh_sync_txn_recvd + __tracepoint_android_vh_timer_calc_index + __tracepoint_android_vh_update_topology_flags_workfn + __tracepoint_binder_transaction_received + __tracepoint_cpu_frequency_limits + __tracepoint_gpu_mem_total + __tracepoint_ipi_entry + __tracepoint_ipi_raise + __tracepoint_irq_handler_entry + tracepoint_probe_register + tracepoint_probe_register_prio + tracepoint_probe_unregister + __tracepoint_rwmmio_post_read + __tracepoint_rwmmio_read + __tracepoint_rwmmio_write + __tracepoint_sched_overutilized_tp + __tracepoint_sched_switch + __tracepoint_suspend_resume + trace_print_array_seq + trace_print_flags_seq + trace_print_symbols_seq + trace_raw_output_prep + trace_seq_printf + trace_seq_putc + try_module_get + try_wait_for_completion + tty_flip_buffer_push + __tty_insert_flip_char + tty_insert_flip_string_fixed_flag + uart_add_one_port + uart_console_device + uart_console_write + uart_get_baud_rate + uart_insert_char + uart_parse_options + uart_register_driver + uart_remove_one_port + uart_resume_port + uart_set_options + uart_suspend_port + uart_try_toggle_sysrq + uart_unregister_driver + uart_update_timeout + uart_write_wakeup + uclamp_eff_value + ucsi_connector_change + ucsi_create + ucsi_destroy + ucsi_get_drvdata + ucsi_register + ucsi_set_drvdata + ucsi_unregister + __udelay + ufshcd_auto_hibern8_update + ufshcd_dme_get_attr + ufshcd_dme_set_attr + ufshcd_dump_regs + ufshcd_fixup_dev_quirks + ufshcd_get_local_unipro_ver + ufshcd_hold + ufshcd_pltfrm_init + ufshcd_pltfrm_resume + ufshcd_pltfrm_runtime_idle + ufshcd_pltfrm_runtime_resume + ufshcd_pltfrm_runtime_suspend + ufshcd_pltfrm_suspend + ufshcd_query_attr + ufshcd_query_descriptor_retry + ufshcd_query_flag + ufshcd_release + ufshcd_remove + ufshcd_shutdown + ufshcd_uic_hibern8_enter + ufshcd_uic_hibern8_exit + __uio_register_device + uio_unregister_device + unlock_page + unregister_blkdev + __unregister_chrdev + unregister_chrdev_region + unregister_console + unregister_die_notifier + unregister_ftrace_export + unregister_kretprobe + unregister_module_notifier + unregister_pm_notifier + unregister_reboot_notifier + unregister_restart_handler + unregister_rpmsg_driver + unregister_shrinker + unregister_syscore_ops + unregister_sysctl_table + update_devfreq + update_rq_clock + up_read + up_write + usb_add_phy_dev + usb_alloc_coherent + usb_alloc_dev + usb_alloc_urb + usb_assign_descriptors + usb_composite_setup_continue + usb_control_msg + usb_deregister + usb_ep_alloc_request + usb_ep_autoconfig + usb_ep_dequeue + usb_ep_disable + usb_ep_enable + usb_ep_free_request + usb_ep_queue + usb_ep_set_halt + usb_find_common_endpoints + usb_free_all_descriptors + usb_free_coherent + usb_free_urb + usb_function_register + usb_function_unregister + usb_gadget_wakeup + usb_ifnum_to_if + usb_interface_id + usb_phy_set_charger_current + usb_poison_urb + usb_put_dev + usb_put_function_instance + usb_register_driver + usb_register_notify + usb_remove_phy + usb_role_switch_find_by_fwnode + usb_role_switch_get_drvdata + usb_role_switch_register + usb_role_switch_set_role + usb_role_switch_unregister + usb_set_device_state + usb_speed_string + usb_string_id + usb_submit_urb + usb_unregister_notify + __usecs_to_jiffies + usleep_range + v4l2_compat_ioctl32 + v4l2_ctrl_handler_free + v4l2_device_register + v4l2_device_unregister + vabits_actual + vchan_dma_desc_free_list + vchan_find_desc + vchan_init + vchan_tx_desc_free + vchan_tx_submit + vfree + vfs_fsync + video_devdata + video_device_release_empty + video_ioctl2 + __video_register_device + video_unregister_device + vmalloc + vmalloc_nr_pages + vmalloc_to_page + vmalloc_to_pfn + vmap + vmf_insert_pfn + vm_insert_page + vm_iomap_memory + vm_map_pages + vm_node_stat + vm_zone_stat + vscnprintf + vsnprintf + vunmap + vzalloc + wait_for_completion + wait_for_completion_interruptible + wait_for_completion_interruptible_timeout + wait_for_completion_killable + wait_for_completion_killable_timeout + wait_for_completion_timeout + __wake_up + wake_up_if_idle + wake_up_process + wakeup_source_add + wakeup_source_register + wakeup_source_remove + wakeup_source_unregister + __warn_printk + ww_mutex_lock + ww_mutex_unlock + __xa_alloc + xa_destroy + xa_erase + xa_find + xa_find_after + xa_load + xa_store + xhci_alloc_command + xhci_alloc_erst + xhci_free_command + xhci_get_endpoint_index + xhci_queue_stop_endpoint + xhci_ring_alloc + xhci_ring_cmd_db + xhci_ring_free + xhci_trb_virt_to_dma diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index 39ef2d1c143c..bbe789e751d5 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -24,16 +24,20 @@ alloc_netdev_mqs __alloc_pages_nodemask __alloc_percpu + __alloc_percpu_gfp __alloc_skb alloc_skb_with_frags alloc_workqueue amba_bustype amba_driver_register amba_driver_unregister + android_debug_for_each_module android_debug_per_cpu_symbol android_debug_symbol android_rvh_probe_register anon_inode_getfile + arc4_crypt + arc4_setkey __arch_clear_user __arch_copy_from_user __arch_copy_in_user @@ -121,37 +125,6 @@ cdev_device_add cdev_device_del cdev_init - __cfg80211_alloc_event_skb - __cfg80211_alloc_reply_skb - cfg80211_calculate_bitrate - cfg80211_chandef_create - cfg80211_ch_switch_notify - cfg80211_connect_done - cfg80211_del_sta_sinfo - cfg80211_disconnected - cfg80211_external_auth_request - cfg80211_ft_event - cfg80211_get_bss - cfg80211_gtk_rekey_notify - cfg80211_inform_bss_frame_data - cfg80211_mgmt_tx_status - cfg80211_michael_mic_failure - cfg80211_new_sta - cfg80211_pmksa_candidate_notify - cfg80211_put_bss - cfg80211_ready_on_channel - cfg80211_remain_on_channel_expired - cfg80211_roamed - cfg80211_rx_mgmt_khz - cfg80211_rx_unprot_mlme_mgmt - cfg80211_scan_done - cfg80211_sched_scan_results - __cfg80211_send_event_skb - cfg80211_stop_iface - cfg80211_tdls_oper_request - cfg80211_unlink_bss - cfg80211_update_owe_info_event - cfg80211_vendor_cmd_reply __cfi_slowpath cgroup_path_ns cgroup_taskset_first @@ -242,6 +215,7 @@ copy_from_kernel_nofault __cpu_active_mask cpu_bit_bitmap + cpufreq_cooling_unregister cpufreq_cpu_get cpufreq_cpu_get_raw cpufreq_cpu_put @@ -293,8 +267,11 @@ cpus_read_unlock cpu_subsys cpu_topology + crc32_be + crc32_le crc8 crc8_populate_msb + crypto_aead_decrypt crypto_aead_encrypt crypto_aead_setauthsize crypto_aead_setkey @@ -315,6 +292,7 @@ crypto_enqueue_request crypto_has_alg crypto_init_queue + __crypto_memneq crypto_register_aead crypto_register_ahash crypto_register_alg @@ -322,7 +300,9 @@ crypto_register_rngs crypto_register_scomp crypto_register_skcipher + crypto_shash_digest crypto_shash_final + crypto_shash_finup crypto_shash_setkey crypto_shash_update crypto_skcipher_decrypt @@ -335,6 +315,7 @@ crypto_unregister_rngs crypto_unregister_scomp crypto_unregister_skcipher + __crypto_xor css_next_child csum_ipv6_magic csum_partial @@ -365,6 +346,7 @@ debugfs_lookup debugfs_print_regs32 debugfs_remove + debugfs_rename dec_zone_page_state default_llseek deferred_free @@ -375,6 +357,8 @@ desc_to_gpio destroy_workqueue dev_alloc_name + dev_change_net_namespace + dev_close dev_coredumpv _dev_crit __dev_direct_xmit @@ -382,6 +366,7 @@ _dev_emerg _dev_err dev_err_probe + dev_fetch_sw_netstats devfreq_add_device devfreq_add_governor devfreq_cooling_unregister @@ -421,6 +406,7 @@ device_property_read_u8_array device_register device_remove_file + device_rename device_set_wakeup_capable device_show_int device_store_int @@ -879,6 +865,7 @@ enable_percpu_irq ether_setup eth_mac_addr + ethtool_op_get_link eth_type_trans eventfd_ctx_fdget eventfd_ctx_fileget @@ -895,6 +882,7 @@ extcon_register_notifier extcon_set_state_sync extcon_unregister_notifier + failure_tracking fasync_helper __fdget fd_install @@ -945,6 +933,7 @@ generic_file_llseek generic_handle_irq generic_iommu_put_resv_regions + genlmsg_multicast_allns genlmsg_put genl_register_family genl_unregister_family @@ -967,6 +956,8 @@ get_each_object_track __get_free_pages get_governor_parent_kobj + get_net_ns_by_fd + get_net_ns_by_pid get_option get_page_owner_handle get_pfnblock_flags_mask @@ -1043,6 +1034,9 @@ hvc_kick hvc_poll hvc_remove + __hw_addr_init + __hw_addr_sync + __hw_addr_unsync hwrng_register hwrng_unregister hwspin_lock_free @@ -1059,6 +1053,29 @@ i2c_register_driver i2c_transfer i2c_transfer_buffer_flags + i3c_device_disable_ibi + i3c_device_do_priv_xfers + i3c_device_enable_ibi + i3c_device_free_ibi + i3c_device_get_info + i3c_device_request_ibi + i3cdev_to_dev + i3c_driver_register_with_owner + i3c_driver_unregister + i3c_generic_ibi_alloc_pool + i3c_generic_ibi_free_pool + i3c_generic_ibi_get_free_slot + i3c_generic_ibi_recycle_slot + i3c_master_add_i3c_dev_locked + i3c_master_disec_locked + i3c_master_do_daa + i3c_master_enec_locked + i3c_master_entdaa_locked + i3c_master_get_free_addr + i3c_master_queue_ibi + i3c_master_register + i3c_master_set_info + i3c_master_unregister icc_disable icc_enable icc_get @@ -1076,6 +1093,7 @@ ida_free idr_alloc idr_alloc_cyclic + idr_alloc_u32 idr_destroy idr_find idr_for_each @@ -1083,9 +1101,6 @@ idr_preload idr_remove idr_replace - ieee80211_freq_khz_to_channel - ieee80211_get_channel_khz - ieee80211_hdrlen iio_channel_get_all iio_read_channel_processed import_iovec @@ -1094,6 +1109,7 @@ inc_node_page_state inc_zone_page_state in_egroup_p + inet_csk_get_port inet_proto_csum_replace4 init_dummy_netdev init_iova_domain @@ -1243,6 +1259,8 @@ kernel_connect kernel_getsockname kernel_kobj + kernel_param_lock + kernel_param_unlock kernel_power_off kernel_recvmsg kernel_restart @@ -1252,6 +1270,9 @@ kernfs_put kern_mount kern_unmount + key_create_or_update + key_put + keyring_alloc __kfifo_alloc __kfifo_free __kfifo_in @@ -1260,6 +1281,7 @@ kfree_const kfree_sensitive kfree_skb + kfree_skb_list kick_all_cpus_sync kill_anon_super kill_fasync @@ -1333,6 +1355,7 @@ kthread_unpark kthread_worker_fn ktime_get + ktime_get_coarse_with_offset ktime_get_mono_fast_ns ktime_get_real_seconds ktime_get_real_ts64 @@ -1422,6 +1445,7 @@ mmc_send_tuning mmput mod_delayed_work_on + __mod_node_page_state mod_node_page_state mod_timer __module_get @@ -1448,8 +1472,11 @@ neigh_lookup neigh_xmit __netdev_alloc_skb + netdev_err + netdev_info netdev_rx_handler_register netdev_rx_handler_unregister + netdev_set_default_ethtool_ops netdev_update_features netif_carrier_off netif_carrier_on @@ -1458,6 +1485,7 @@ netif_napi_add __netif_napi_del netif_receive_skb + netif_receive_skb_core netif_receive_skb_list netif_rx netif_rx_ni @@ -1468,7 +1496,11 @@ netlink_capable __netlink_kernel_create netlink_kernel_release + netlink_register_notifier netlink_unicast + netlink_unregister_notifier + net_ns_type_operations + net_ratelimit __next_zones_zonelist nla_find nla_memcpy @@ -1784,6 +1816,7 @@ power_supply_set_property power_supply_unregister power_supply_unreg_notifier + prandom_bytes prandom_u32 preempt_schedule preempt_schedule_notrace @@ -1809,6 +1842,7 @@ put_device put_disk put_iova_domain + __put_net __put_page put_pid put_sg_io_hdr @@ -1892,6 +1926,7 @@ rcuwait_wake_up rdev_get_drvdata reboot_mode + reclaim_shmem_address_space refcount_dec_and_lock refcount_dec_not_one refcount_warn_saturate @@ -1916,6 +1951,7 @@ register_netdevice_notifier register_netevent_notifier register_oom_notifier + register_pernet_device register_pm_notifier register_reboot_notifier register_restart_handler @@ -1958,7 +1994,6 @@ regulator_set_mode regulator_set_voltage regulator_unregister_notifier - regulatory_set_wiphy_regd release_firmware __release_region release_sock @@ -1985,10 +2020,20 @@ return_address revalidate_disk_size rfkill_alloc + rfkill_blocked rfkill_destroy rfkill_init_sw_state + rfkill_pause_polling rfkill_register + rfkill_resume_polling + rfkill_set_hw_state rfkill_unregister + rhashtable_free_and_destroy + rhashtable_insert_slow + rhltable_init + __rht_bucket_nested + rht_bucket_nested + rht_bucket_nested_insert rndis_deregister rndis_free_response rndis_get_next_response @@ -2001,7 +2046,9 @@ rndis_signal_connect rndis_uninit root_task_group + round_jiffies round_jiffies_relative + round_jiffies_up rpmsg_get_signals rpmsg_poll rpmsg_register_device @@ -2013,8 +2060,10 @@ rproc_add_subdev rproc_alloc rproc_boot + rproc_coredump rproc_coredump_add_custom_segment rproc_coredump_add_segment + rproc_coredump_cleanup rproc_coredump_set_elf_info rproc_coredump_using_sections rproc_del @@ -2053,6 +2102,7 @@ sched_setscheduler sched_setscheduler_nocheck sched_show_task + sched_trace_rd_span sched_uclamp_used schedule schedule_hrtimeout @@ -2129,7 +2179,9 @@ sg_pcopy_from_buffer sg_pcopy_to_buffer sg_scsi_ioctl + shmem_file_setup shmem_mark_page_lazyfree + shmem_read_mapping_page_gfp shmem_truncate_range show_rcu_gp_kthreads show_regs @@ -2150,8 +2202,11 @@ skb_add_rx_frag skb_append_pagefrags skb_checksum + skb_checksum_help skb_clone + skb_clone_sk skb_coalesce_rx_frag + skb_complete_wifi_ack skb_copy skb_copy_bits skb_copy_datagram_iter @@ -2242,6 +2297,7 @@ soc_device_register soc_device_unregister sock_alloc_send_skb + __sock_create sock_create_kern sock_gettstamp sock_init_data @@ -2320,6 +2376,7 @@ strscpy strsep strstr + __sw_hweight16 __sw_hweight32 __sw_hweight64 __sw_hweight8 @@ -2415,6 +2472,8 @@ trace_get_event_file trace_handle_return __traceiter_android_rvh_account_irq + __traceiter_android_rvh_after_dequeue_task + __traceiter_android_rvh_after_enqueue_task __traceiter_android_rvh_build_perf_domains __traceiter_android_rvh_can_migrate_task __traceiter_android_rvh_cgroup_force_kthread_migration @@ -2427,6 +2486,8 @@ __traceiter_android_rvh_find_busiest_queue __traceiter_android_rvh_find_lowest_rq __traceiter_android_rvh_flush_task + __traceiter_android_rvh_force_compatible_post + __traceiter_android_rvh_force_compatible_pre __traceiter_android_rvh_gic_v3_set_affinity __traceiter_android_rvh_irqs_disable __traceiter_android_rvh_irqs_enable @@ -2455,6 +2516,7 @@ __traceiter_android_rvh_set_readahead_gfp_mask __traceiter_android_rvh_set_skip_swapcache_flags __traceiter_android_rvh_set_task_cpu + __traceiter_android_rvh_show_max_freq __traceiter_android_rvh_tick_entry __traceiter_android_rvh_try_to_wake_up __traceiter_android_rvh_try_to_wake_up_success @@ -2473,8 +2535,6 @@ __traceiter_android_vh_cpuidle_psci_enter __traceiter_android_vh_cpuidle_psci_exit __traceiter_android_vh_dump_throttled_rt_tasks - __traceiter_android_vh_force_compatible_post - __traceiter_android_vh_force_compatible_pre __traceiter_android_vh_freq_table_limits __traceiter_android_vh_ftrace_dump_buffer __traceiter_android_vh_ftrace_format_check @@ -2487,12 +2547,24 @@ __traceiter_android_vh_ipi_stop __traceiter_android_vh_jiffies_update __traceiter_android_vh_logbuf + __traceiter_android_vh_logbuf_pr_cont __traceiter_android_vh_printk_hotplug + __traceiter_android_vh_rproc_recovery __traceiter_android_vh_scheduler_tick __traceiter_android_vh_show_max_freq __traceiter_android_vh_show_resume_epoch_val __traceiter_android_vh_show_suspend_epoch_val __traceiter_android_vh_timer_calc_index + __traceiter_android_vh_ufs_check_int_errors + __traceiter_android_vh_ufs_clock_scaling + __traceiter_android_vh_ufs_compl_command + __traceiter_android_vh_ufs_fill_prdt + __traceiter_android_vh_ufs_prepare_command + __traceiter_android_vh_ufs_send_command + __traceiter_android_vh_ufs_send_tm_command + __traceiter_android_vh_ufs_send_uic_command + __traceiter_android_vh_ufs_update_sdev + __traceiter_android_vh_ufs_update_sysfs __traceiter_android_vh_update_topology_flags_workfn __traceiter_binder_transaction_received __traceiter_cpu_frequency @@ -2505,9 +2577,12 @@ __traceiter_rwmmio_post_read __traceiter_rwmmio_read __traceiter_rwmmio_write + __traceiter_sched_overutilized_tp __traceiter_sched_switch __traceiter_suspend_resume __tracepoint_android_rvh_account_irq + __tracepoint_android_rvh_after_dequeue_task + __tracepoint_android_rvh_after_enqueue_task __tracepoint_android_rvh_build_perf_domains __tracepoint_android_rvh_can_migrate_task __tracepoint_android_rvh_cgroup_force_kthread_migration @@ -2520,6 +2595,8 @@ __tracepoint_android_rvh_find_busiest_queue __tracepoint_android_rvh_find_lowest_rq __tracepoint_android_rvh_flush_task + __tracepoint_android_rvh_force_compatible_post + __tracepoint_android_rvh_force_compatible_pre __tracepoint_android_rvh_gic_v3_set_affinity __tracepoint_android_rvh_irqs_disable __tracepoint_android_rvh_irqs_enable @@ -2548,6 +2625,7 @@ __tracepoint_android_rvh_set_readahead_gfp_mask __tracepoint_android_rvh_set_skip_swapcache_flags __tracepoint_android_rvh_set_task_cpu + __tracepoint_android_rvh_show_max_freq __tracepoint_android_rvh_tick_entry __tracepoint_android_rvh_try_to_wake_up __tracepoint_android_rvh_try_to_wake_up_success @@ -2557,6 +2635,7 @@ __tracepoint_android_rvh_update_misfit_status __tracepoint_android_rvh_wake_up_new_task __tracepoint_android_vh_allow_domain_state + __tracepoint_android_vh_alter_rwsem_list_add __tracepoint_android_vh_binder_restore_priority __tracepoint_android_vh_binder_set_priority __tracepoint_android_vh_binder_transaction_init @@ -2568,8 +2647,6 @@ __tracepoint_android_vh_cpuidle_psci_enter __tracepoint_android_vh_cpuidle_psci_exit __tracepoint_android_vh_dump_throttled_rt_tasks - __tracepoint_android_vh_force_compatible_post - __tracepoint_android_vh_force_compatible_pre __tracepoint_android_vh_freq_table_limits __tracepoint_android_vh_ftrace_dump_buffer __tracepoint_android_vh_ftrace_format_check @@ -2582,15 +2659,29 @@ __tracepoint_android_vh_ipi_stop __tracepoint_android_vh_jiffies_update __tracepoint_android_vh_logbuf + __tracepoint_android_vh_logbuf_pr_cont + __tracepoint_android_vh_oom_check_panic __tracepoint_android_vh_printk_hotplug __tracepoint_android_vh_process_killed __tracepoint_android_vh_psi_event __tracepoint_android_vh_psi_group + __tracepoint_android_vh_rproc_recovery __tracepoint_android_vh_scheduler_tick + __tracepoint_android_vh_shmem_alloc_page __tracepoint_android_vh_show_max_freq __tracepoint_android_vh_show_resume_epoch_val __tracepoint_android_vh_show_suspend_epoch_val __tracepoint_android_vh_timer_calc_index + __tracepoint_android_vh_ufs_check_int_errors + __tracepoint_android_vh_ufs_clock_scaling + __tracepoint_android_vh_ufs_compl_command + __tracepoint_android_vh_ufs_fill_prdt + __tracepoint_android_vh_ufs_prepare_command + __tracepoint_android_vh_ufs_send_command + __tracepoint_android_vh_ufs_send_tm_command + __tracepoint_android_vh_ufs_send_uic_command + __tracepoint_android_vh_ufs_update_sdev + __tracepoint_android_vh_ufs_update_sysfs __tracepoint_android_vh_update_topology_flags_workfn __tracepoint_binder_transaction_received __tracepoint_cpu_frequency @@ -2606,6 +2697,7 @@ __tracepoint_rwmmio_post_read __tracepoint_rwmmio_read __tracepoint_rwmmio_write + __tracepoint_sched_overutilized_tp __tracepoint_sched_switch __tracepoint_suspend_resume trace_print_array_seq @@ -2702,6 +2794,7 @@ unregister_netdevice_queue unregister_netevent_notifier unregister_oom_notifier + unregister_pernet_device unregister_pm_notifier unregister_reboot_notifier unregister_restart_handler @@ -2846,6 +2939,7 @@ vchan_init vchan_tx_desc_free vchan_tx_submit + verify_pkcs7_signature vfree video_devdata video_device_alloc @@ -2860,6 +2954,7 @@ vmalloc_to_pfn vmap vmemdup_user + vm_event_states vmf_insert_mixed vmf_insert_pfn vm_get_page_prot @@ -2890,10 +2985,7 @@ wakeup_source_register wakeup_source_unregister __warn_printk - wiphy_free - wiphy_new_nm - wiphy_register - wiphy_unregister + wireless_nlevent_flush wireless_send_event woken_wake_function work_busy @@ -2906,6 +2998,9 @@ xa_find_after xa_load xa_store + __xfrm_decode_session + xfrm_lookup + xfrm_output xhci_alloc_command xhci_alloc_erst xhci_free_command diff --git a/android/abi_gki_aarch64_rockchip b/android/abi_gki_aarch64_rockchip new file mode 100644 index 000000000000..6c4b0be95bf0 --- /dev/null +++ b/android/abi_gki_aarch64_rockchip @@ -0,0 +1,1518 @@ +[abi_symbol_list] + __ClearPageMovable + __SetPageMovable + ___ratelimit + __alloc_disk_node + __alloc_pages_nodemask + __alloc_percpu + __alloc_percpu_gfp + __alloc_skb + __arch_copy_from_user + __arch_copy_to_user + __arm_smccc_hvc + __arm_smccc_smc + __bitmap_and + __bitmap_andnot + __bitmap_clear + __bitmap_set + __bitmap_weight + __blk_rq_map_sg + __cfi_slowpath + __check_object_size + __class_create + __class_register + __clk_get_name + __const_udelay + __cpu_online_mask + __cpu_possible_mask + __cpufreq_driver_target + __cpuhp_remove_state + __cpuhp_setup_state + __cpuhp_state_add_instance + __cpuhp_state_remove_instance + __crypto_memneq + __crypto_xor + __dev_kfree_skb_any + __devm_iio_device_register + __devm_of_phy_provider_register + __devm_regmap_init + __devm_regmap_init_i2c + __devm_regmap_init_mmio_clk + __devm_reset_control_get + __do_once_done + __do_once_start + __drm_err + __fdget + __free_pages + __get_free_pages + __getblk_gfp + __i2c_smbus_xfer + __i2c_transfer + __init_rwsem + __init_swait_queue_head + __init_waitqueue_head + __ioremap + __ipv6_addr_type + __kfifo_alloc + __kfifo_free + __kfifo_in + __kfifo_out + __kfifo_to_user + __kmalloc + __list_add_valid + __list_del_entry_valid + __lock_buffer + __lock_page + __log_post_read_mmio + __log_read_mmio + __log_write_mmio + __mdiobus_register + __memcpy_fromio + __memcpy_toio + __memset_io + __module_get + __msecs_to_jiffies + __mutex_init + __napi_alloc_skb + __napi_schedule + __netdev_alloc_skb + __netif_napi_del + __num_online_cpus + __of_reset_control_get + __page_pinner_migration_failed + __pci_register_driver + __per_cpu_offset + __platform_driver_register + __pm_runtime_disable + __pm_runtime_idle + __pm_runtime_resume + __pm_runtime_set_status + __pm_runtime_suspend + __pm_runtime_use_autosuspend + __printk_ratelimit + __pskb_pull_tail + __put_net + __put_page + __put_task_struct + __rcu_read_lock + __rcu_read_unlock + __refrigerator + __register_chrdev + __rtc_register_device + __scsi_add_device + __scsi_execute + __scsi_print_sense + __sdhci_add_host + __sg_page_iter_next + __sg_page_iter_start + __sock_create + __spi_alloc_controller + __spi_register_driver + __srcu_read_unlock + __stack_chk_fail + __stack_chk_guard + __sw_hweight64 + __sysfs_match_string + __task_pid_nr_ns + __tasklet_hi_schedule + __tasklet_schedule + __traceiter_rwmmio_post_read + __traceiter_rwmmio_read + __traceiter_rwmmio_write + __tracepoint_rwmmio_post_read + __tracepoint_rwmmio_read + __tracepoint_rwmmio_write + __tty_insert_flip_char + __unregister_chrdev + __usecs_to_jiffies + __v4l2_ctrl_modify_range + __v4l2_find_nearest_size + __wait_on_buffer + __wake_up + __warn_printk + _copy_from_iter_full + _copy_to_iter + _ctype + _dev_crit + _dev_err + _dev_info + _dev_warn + _raw_read_lock + _raw_read_lock_bh + _raw_read_lock_irqsave + _raw_read_unlock + _raw_read_unlock_bh + _raw_read_unlock_irqrestore + _raw_spin_lock + _raw_spin_lock_bh + _raw_spin_lock_irq + _raw_spin_lock_irqsave + _raw_spin_trylock + _raw_spin_trylock_bh + _raw_spin_unlock + _raw_spin_unlock_bh + _raw_spin_unlock_irq + _raw_spin_unlock_irqrestore + _raw_write_lock + _raw_write_lock_bh + _raw_write_lock_irq + _raw_write_lock_irqsave + _raw_write_unlock + _raw_write_unlock_bh + _raw_write_unlock_irq + _raw_write_unlock_irqrestore + add_timer + add_uevent_var + add_wait_queue + aes_encrypt + aes_expandkey + alloc_anon_inode + alloc_chrdev_region + alloc_etherdev_mqs + alloc_netdev_mqs + alloc_pages_exact + alloc_workqueue + amba_driver_register + amba_driver_unregister + arc4_crypt + arc4_setkey + arm64_const_caps_ready + arm64_use_ng_mappings + async_schedule_node + atomic_notifier_chain_register + atomic_notifier_chain_unregister + autoremove_wake_function + backlight_device_register + backlight_device_unregister + bcmp + bd_set_nr_sectors + bdget_disk + bdput + bio_endio + bitmap_find_next_zero_area_off + bitmap_free + bitmap_zalloc + blk_alloc_queue + blk_cleanup_queue + blk_execute_rq + blk_execute_rq_nowait + blk_freeze_queue_start + blk_get_queue + blk_get_request + blk_mq_alloc_request + blk_mq_alloc_request_hctx + blk_mq_alloc_tag_set + blk_mq_complete_request + blk_mq_complete_request_remote + blk_mq_delay_kick_requeue_list + blk_mq_end_request + blk_mq_free_request + blk_mq_free_tag_set + blk_mq_freeze_queue + blk_mq_freeze_queue_wait + blk_mq_freeze_queue_wait_timeout + blk_mq_init_queue + blk_mq_map_queues + blk_mq_pci_map_queues + blk_mq_quiesce_queue + blk_mq_requeue_request + blk_mq_start_request + blk_mq_tag_to_rq + blk_mq_tagset_busy_iter + blk_mq_tagset_wait_completed_request + blk_mq_unfreeze_queue + blk_mq_unique_tag + blk_mq_unquiesce_queue + blk_mq_update_nr_hw_queues + blk_poll + blk_put_queue + blk_put_request + blk_queue_chunk_sectors + blk_queue_dma_alignment + blk_queue_flag_clear + blk_queue_flag_set + blk_queue_flag_test_and_set + blk_queue_io_min + blk_queue_io_opt + blk_queue_logical_block_size + blk_queue_max_discard_sectors + blk_queue_max_discard_segments + blk_queue_max_hw_sectors + blk_queue_max_segments + blk_queue_max_write_zeroes_sectors + blk_queue_physical_block_size + blk_queue_virt_boundary + blk_queue_write_cache + blk_rq_map_kern + blk_rq_map_user + blk_rq_map_user_iov + blk_rq_unmap_user + blk_set_queue_dying + blk_status_to_errno + blk_sync_queue + blk_verify_command + bpf_trace_run1 + bpf_trace_run2 + bpf_trace_run3 + bpf_trace_run4 + bpf_trace_run5 + bpf_trace_run6 + bpf_trace_run7 + bt_err + bus_register + bus_register_notifier + bus_unregister + bus_unregister_notifier + call_netdevice_notifiers + call_rcu + cancel_delayed_work + cancel_delayed_work_sync + cancel_work_sync + capable + cdev_add + cdev_alloc + cdev_del + cdev_device_add + cdev_device_del + cdev_init + ce_aes_expandkey + class_destroy + class_find_device + class_interface_unregister + class_unregister + cleanup_srcu_struct + clk_bulk_disable + clk_bulk_enable + clk_bulk_prepare + clk_bulk_unprepare + clk_disable + clk_enable + clk_get + clk_get_rate + clk_hw_get_name + clk_hw_set_rate_range + clk_notifier_register + clk_notifier_unregister + clk_prepare + clk_put + clk_register + clk_round_rate + clk_set_rate + clk_unprepare + clk_unregister + cma_alloc + cma_get_name + cma_release + compat_ptr_ioctl + complete + completion_done + consume_skb + contig_page_data + cpu_have_feature + cpu_hwcap_keys + cpu_hwcaps + cpu_number + cpufreq_cpu_get_raw + cpufreq_enable_boost_support + cpufreq_freq_attr_scaling_available_freqs + cpufreq_freq_attr_scaling_boost_freqs + cpufreq_generic_frequency_table_verify + cpufreq_generic_get + cpufreq_generic_suspend + cpufreq_register_driver + cpufreq_register_governor + cpufreq_table_index_unsorted + cpufreq_unregister_driver + cpufreq_unregister_governor + cpumask_next + cpus_read_lock + cpus_read_unlock + crc32_be + crc32_le + crypto_aead_decrypt + crypto_aead_encrypt + crypto_aead_setauthsize + crypto_aead_setkey + crypto_ahash_digest + crypto_ahash_setkey + crypto_alloc_aead + crypto_alloc_ahash + crypto_alloc_base + crypto_alloc_shash + crypto_comp_compress + crypto_comp_decompress + crypto_dequeue_request + crypto_destroy_tfm + crypto_enqueue_request + crypto_has_alg + crypto_inc + crypto_init_queue + crypto_register_aead + crypto_register_ahash + crypto_register_alg + crypto_register_scomp + crypto_register_shash + crypto_register_skcipher + crypto_req_done + crypto_sha1_finup + crypto_sha1_update + crypto_shash_final + crypto_shash_setkey + crypto_shash_update + crypto_unregister_aead + crypto_unregister_ahash + crypto_unregister_alg + crypto_unregister_scomp + crypto_unregister_shash + crypto_unregister_skcipher + csum_partial + current_time + d_add + d_make_root + datagram_poll + deactivate_locked_super + debugfs_create_dir + debugfs_create_file + debugfs_create_regset32 + debugfs_create_u32 + debugfs_create_x64 + debugfs_remove + debugfs_rename + dec_zone_page_state + default_llseek + default_wake_function + deferred_free + del_gendisk + del_timer + del_timer_sync + delayed_work_timer_fn + desc_to_gpio + destroy_workqueue + dev_close + dev_driver_string + dev_err_probe + dev_fetch_sw_netstats + dev_fwnode + dev_get_by_name + dev_get_by_name_rcu + dev_get_regmap + dev_open + dev_pm_opp_free_cpufreq_table + dev_pm_opp_get_max_transition_latency + dev_pm_opp_get_opp_count + dev_pm_opp_get_opp_table + dev_pm_opp_get_sharing_cpus + dev_pm_opp_get_suspend_opp_freq + dev_pm_opp_init_cpufreq_table + dev_pm_opp_of_cpumask_add_table + dev_pm_opp_of_cpumask_remove_table + dev_pm_opp_of_get_sharing_cpus + dev_pm_opp_of_register_em + dev_pm_opp_put_opp_table + dev_pm_opp_put_regulators + dev_pm_opp_set_rate + dev_pm_opp_set_regulators + dev_pm_opp_set_sharing_cpus + dev_pm_qos_expose_latency_tolerance + dev_pm_qos_hide_latency_tolerance + dev_pm_qos_update_user_latency_tolerance + dev_printk + dev_queue_xmit + dev_set_name + device_add + device_add_disk + device_create + device_del + device_destroy + device_for_each_child + device_get_child_node_count + device_get_next_child_node + device_get_phy_mode + device_init_wakeup + device_initialize + device_property_present + device_property_read_string + device_property_read_string_array + device_property_read_u32_array + device_property_read_u8_array + device_register + device_release_driver + device_remove_file_self + device_set_wakeup_capable + device_set_wakeup_enable + device_wakeup_enable + devm_add_action + devm_blk_ksm_init + devm_clk_bulk_get + devm_clk_get + devm_clk_get_optional + devm_clk_hw_register + devm_clk_register + devm_extcon_dev_allocate + devm_extcon_dev_register + devm_extcon_register_notifier + devm_free_irq + devm_get_clk_from_child + devm_gpio_request_one + devm_gpiochip_add_data_with_key + devm_gpiod_get + devm_gpiod_get_index + devm_gpiod_get_optional + devm_iio_channel_get + devm_iio_device_alloc + devm_input_allocate_device + devm_ioremap + devm_ioremap_resource + devm_kasprintf + devm_kfree + devm_kmalloc + devm_kmemdup + devm_kstrdup + devm_kvasprintf + devm_led_classdev_register_ext + devm_mfd_add_devices + devm_nvmem_register + devm_of_clk_add_hw_provider + devm_phy_create + devm_phy_get + devm_pinctrl_register + devm_platform_get_and_ioremap_resource + devm_platform_ioremap_resource + devm_power_supply_register + devm_pwm_get + devm_regmap_field_alloc + devm_regulator_bulk_get + devm_regulator_get + devm_regulator_get_optional + devm_regulator_register + devm_request_any_context_irq + devm_request_threaded_irq + devm_reset_control_array_get + devm_rtc_allocate_device + devm_snd_dmaengine_pcm_register + devm_snd_soc_register_card + devm_snd_soc_register_component + devm_spi_register_controller + devm_thermal_zone_of_sensor_register + devm_usb_get_phy + devres_add + devres_alloc_node + devres_free + devres_release + disable_irq + disk_end_io_acct + disk_start_io_acct + dma_alloc_attrs + dma_async_device_register + dma_async_device_unregister + dma_async_tx_descriptor_init + dma_buf_export + dma_buf_fd + dma_buf_put + dma_contiguous_default_area + dma_free_attrs + dma_get_required_mask + dma_get_slave_channel + dma_heap_add + dma_heap_get_dev + dma_heap_get_drvdata + dma_heap_get_name + dma_map_page_attrs + dma_map_resource + dma_map_sg_attrs + dma_max_mapping_size + dma_pool_alloc + dma_pool_create + dma_pool_destroy + dma_pool_free + dma_release_channel + dma_request_chan + dma_set_coherent_mask + dma_set_mask + dma_sync_sg_for_cpu + dma_sync_sg_for_device + dma_sync_single_for_cpu + dma_sync_single_for_device + dma_unmap_page_attrs + dma_unmap_resource + dma_unmap_sg_attrs + dmabuf_page_pool_alloc + dmabuf_page_pool_create + dmabuf_page_pool_destroy + dmabuf_page_pool_free + dmaengine_unmap_put + dmam_alloc_attrs + dmam_free_coherent + down + down_read + down_write + dput + dql_completed + dql_reset + driver_register + driver_unregister + drm_add_edid_modes + drm_atomic_helper_connector_destroy_state + drm_atomic_helper_connector_duplicate_state + drm_atomic_helper_connector_reset + drm_bridge_add + drm_bridge_remove + drm_connector_attach_encoder + drm_connector_cleanup + drm_connector_init + drm_connector_update_edid_property + drm_detect_hdmi_monitor + drm_display_mode_from_videomode + drm_get_edid + drm_hdmi_avi_infoframe_from_display_mode + drm_helper_hpd_irq_event + drm_helper_probe_single_connector_modes + drm_mode_create + drm_mode_duplicate + drm_mode_probed_add + drm_mode_set_name + drm_mode_vrefresh + drm_panel_add + drm_panel_disable + drm_panel_init + drm_panel_remove + drm_panel_unprepare + dump_stack + enable_irq + eth_commit_mac_addr_change + eth_mac_addr + eth_platform_get_mac_address + eth_prepare_mac_addr_change + eth_type_trans + eth_validate_addr + ether_setup + ethtool_op_get_ts_info + event_triggers_call + extcon_get_edev_by_phandle + extcon_get_property + extcon_get_state + extcon_set_state_sync + failure_tracking + fasync_helper + find_next_bit + find_next_zero_bit + find_vma + finish_wait + flush_dcache_page + flush_work + flush_workqueue + fpsimd_context_busy + fput + free_irq + free_netdev + free_pages + free_pages_exact + free_percpu + freezing_slow_path + fsync_bdev + full_name_hash + fwnode_device_is_available + fwnode_get_name + fwnode_graph_get_next_endpoint + fwnode_graph_get_port_parent + fwnode_graph_get_remote_endpoint + fwnode_graph_get_remote_port_parent + fwnode_graph_parse_endpoint + fwnode_handle_put + fwnode_property_get_reference_args + fwnode_property_present + fwnode_property_read_string + fwnode_property_read_u32_array + fwnode_property_read_u64_array + gcd + gen_pool_add_owner + gen_pool_alloc_algo_owner + gen_pool_best_fit + gen_pool_create + gen_pool_destroy + gen_pool_dma_alloc_align + gen_pool_dma_zalloc_align + gen_pool_free_owner + gen_pool_set_algo + gen_pool_virt_to_phys + generic_mii_ioctl + genphy_resume + get_cpu_device + get_cpu_idle_time_us + get_device + get_kernel_pages + get_random_bytes + get_random_u32 + get_sg_io_hdr + get_zeroed_page + gf128mul_lle + gic_nonsecure_priorities + glob_match + gpio_to_desc + gpiochip_add_pin_range + gpiochip_generic_free + gpiochip_generic_request + gpiochip_get_data + gpiod_count + gpiod_direction_output + gpiod_get_optional + gpiod_get_value + gpiod_get_value_cansleep + gpiod_set_consumer_name + gpiod_set_value + gpiod_set_value_cansleep + hdmi_audio_infoframe_init + hdmi_audio_infoframe_pack + hdmi_avi_infoframe_pack + hex_asc_upper + hid_add_device + hid_allocate_device + hid_debug + hid_destroy_device + hid_input_report + hid_parse_report + hrtimer_cancel + hrtimer_init + hrtimer_start_range_ns + hwrng_register + hwrng_unregister + i2c_adapter_type + i2c_add_adapter + i2c_add_numbered_adapter + i2c_bus_type + i2c_del_adapter + i2c_del_driver + i2c_for_each_dev + i2c_get_adapter + i2c_parse_fw_timings + i2c_put_adapter + i2c_register_driver + i2c_smbus_read_byte + i2c_smbus_read_byte_data + i2c_smbus_xfer + i2c_transfer + i2c_transfer_buffer_flags + i2c_verify_client + ida_alloc_range + ida_destroy + ida_free + idr_alloc + idr_destroy + idr_find + idr_for_each + idr_get_next + idr_preload + idr_remove + iio_alloc_pollfunc + iio_buffer_init + iio_buffer_put + iio_channel_get_all + iio_dealloc_pollfunc + iio_device_attach_buffer + iio_get_channel_type + iio_get_time_ns + iio_push_to_buffers + iio_read_channel_processed + iio_trigger_notify_done + import_iovec + in4_pton + in6_pton + in_egroup_p + inc_zone_page_state + init_net + init_pseudo + init_srcu_struct + init_timer_key + init_uts_ns + init_wait_entry + input_alloc_absinfo + input_allocate_device + input_event + input_free_device + input_mt_init_slots + input_mt_report_slot_state + input_mt_sync_frame + input_register_device + input_set_abs_params + input_set_capability + input_unregister_device + iounmap + iput + ipv6_stub + irq_get_irq_data + irq_set_irq_wake + irq_stat + is_vmalloc_addr + jiffies + jiffies_to_msecs + kasan_flag_enabled + kasprintf + kern_mount + kern_unmount + kernel_neon_begin + kernel_neon_end + kernel_sendmsg + kernel_sigaction + key_put + keyring_alloc + kfree + kfree_const + kfree_sensitive + kfree_skb + kill_anon_super + kill_fasync + kimage_voffset + kmalloc_caches + kmalloc_order_trace + kmem_cache_alloc + kmem_cache_alloc_trace + kmem_cache_create + kmem_cache_create_usercopy + kmem_cache_destroy + kmem_cache_free + kmemdup + kobject_get + kobject_put + kobject_uevent_env + kstrdup + kstrdup_const + kstrndup + kstrtobool + kstrtobool_from_user + kstrtoint + kstrtoll + kstrtou16 + kstrtou8 + kstrtouint + kstrtoull + kthread_cancel_delayed_work_sync + kthread_create_on_node + kthread_create_worker + kthread_delayed_work_timer_fn + kthread_destroy_worker + kthread_mod_delayed_work + kthread_queue_delayed_work + ktime_get + ktime_get_coarse_real_ts64 + ktime_get_mono_fast_ns + ktime_get_real_ts64 + ktime_get_snapshot + ktime_get_with_offset + kvfree + kvmalloc_node + led_classdev_register_ext + led_classdev_unregister + list_sort + lock_sock_nested + lockref_get + loops_per_jiffy + lzo1x_1_compress + lzo1x_decompress_safe + lzorle1x_1_compress + match_int + match_token + mdiobus_alloc_size + mdiobus_free + mdiobus_get_phy + mdiobus_read + mdiobus_unregister + mdiobus_write + media_entity_pads_init + memchr + memchr_inv + memcpy + memdup_user + memmove + memparse + mempool_alloc + mempool_alloc_slab + mempool_create + mempool_create_node + mempool_destroy + mempool_free + mempool_free_slab + mempool_kfree + mempool_kmalloc + memremap + memset + memset64 + memstart_addr + memunmap + mii_check_media + mii_ethtool_get_link_ksettings + mii_ethtool_gset + mii_ethtool_set_link_ksettings + mii_link_ok + mii_nway_restart + mipi_dsi_attach + mipi_dsi_detach + mipi_dsi_driver_register_full + mipi_dsi_driver_unregister + mktime64 + mmc_add_host + mmc_alloc_host + mmc_can_gpio_cd + mmc_cqe_request_done + mmc_detect_change + mmc_free_host + mmc_gpio_get_cd + mmc_gpio_get_ro + mmc_of_parse + mmc_regulator_get_supply + mmc_regulator_set_ocr + mmc_regulator_set_vqmmc + mmc_remove_host + mmc_request_done + mmc_send_tuning + mod_delayed_work_on + mod_timer + module_layout + module_put + msleep + msleep_interruptible + mutex_is_locked + mutex_lock + mutex_lock_interruptible + mutex_unlock + n_tty_ioctl_helper + napi_complete_done + napi_disable + napi_gro_receive + napi_schedule_prep + net_ratelimit + netdev_alert + netdev_err + netdev_info + netdev_pick_tx + netdev_update_features + netdev_upper_dev_link + netdev_upper_dev_unlink + netdev_warn + netif_carrier_off + netif_carrier_on + netif_device_attach + netif_device_detach + netif_napi_add + netif_rx + netif_rx_ni + netif_schedule_queue + netif_set_real_num_rx_queues + netif_set_real_num_tx_queues + netif_stacked_transfer_operstate + netif_tx_stop_all_queues + netif_tx_wake_queue + new_inode + no_llseek + nonseekable_open + noop_llseek + nr_cpu_ids + ns_to_timespec64 + of_alias_get_id + of_clk_add_hw_provider + of_clk_add_provider + of_clk_del_provider + of_clk_get + of_clk_get_by_name + of_clk_hw_onecell_get + of_clk_hw_simple_get + of_clk_src_simple_get + of_count_phandle_with_args + of_device_get_match_data + of_device_is_available + of_device_is_compatible + of_dma_controller_free + of_dma_controller_register + of_find_device_by_node + of_find_i2c_adapter_by_node + of_find_property + of_get_child_by_name + of_get_compatible_child + of_get_mac_address + of_get_named_gpio_flags + of_get_next_available_child + of_get_next_child + of_get_parent + of_get_property + of_get_regulator_init_data + of_graph_parse_endpoint + of_irq_get_byname + of_machine_is_compatible + of_match_device + of_match_node + of_mdiobus_register + of_node_name_eq + of_parse_phandle + of_parse_phandle_with_args + of_phy_is_fixed_link + of_phy_simple_xlate + of_platform_device_create + of_property_count_elems_of_size + of_property_read_string + of_property_read_string_helper + of_property_read_u32_index + of_property_read_variable_u16_array + of_property_read_variable_u32_array + of_property_read_variable_u8_array + of_pwm_xlate_with_flags + page_endio + page_mapping + panic_notifier_list + param_array_ops + param_get_int + param_get_uint + param_ops_bool + param_ops_byte + param_ops_charp + param_ops_int + param_ops_string + param_ops_uint + param_ops_ulong + param_ops_ushort + param_set_uint + pci_alloc_irq_vectors_affinity + pci_device_is_present + pci_disable_device + pci_disable_pcie_error_reporting + pci_enable_device_mem + pci_enable_pcie_error_reporting + pci_free_irq + pci_free_irq_vectors + pci_intx + pci_irq_vector + pci_load_saved_state + pci_match_id + pci_read_config_byte + pci_read_config_dword + pci_read_config_word + pci_release_selected_regions + pci_request_irq + pci_request_selected_regions + pci_restore_state + pci_save_state + pci_select_bars + pci_set_master + pci_set_power_state + pci_unregister_driver + pci_write_config_dword + pci_write_config_word + pcibios_resource_to_bus + pcie_aspm_enabled + pcim_enable_device + perf_trace_buf_alloc + perf_trace_run_bpf_submit + pfn_valid + phy_attached_info + phy_disconnect + phy_ethtool_get_link_ksettings + phy_ethtool_nway_reset + phy_ethtool_set_link_ksettings + phy_exit + phy_init + phy_init_eee + phy_mii_ioctl + phy_power_off + phy_power_on + phy_print_status + phy_reset + phy_set_mode_ext + phy_start + phy_stop + phylink_connect_phy + phylink_create + phylink_destroy + phylink_of_phy_connect + phylink_set_port_modes + pin_user_pages_fast + pinconf_generic_dt_node_to_map + pinctrl_dev_get_drvdata + pinctrl_gpio_direction_input + pinctrl_gpio_direction_output + pinctrl_pm_select_default_state + pinctrl_pm_select_sleep_state + pinctrl_utils_free_map + platform_device_put + platform_device_register_full + platform_driver_unregister + platform_get_irq + platform_get_irq_byname + platform_get_irq_byname_optional + platform_get_irq_optional + platform_get_resource + platform_get_resource_byname + pm_power_off + pm_runtime_enable + pm_runtime_forbid + pm_runtime_force_resume + pm_runtime_force_suspend + pm_runtime_get_if_active + pm_runtime_irq_safe + pm_runtime_set_autosuspend_delay + pm_suspend_global_flags + pm_wakeup_dev_event + policy_has_boost_freq + posix_clock_register + posix_clock_unregister + power_supply_changed + power_supply_get_drvdata + power_supply_register + power_supply_unregister + preempt_schedule + preempt_schedule_notrace + prepare_to_wait + prepare_to_wait_event + print_hex_dump + printk + proc_create + proc_create_single_data + proc_mkdir + proto_register + proto_unregister + pskb_expand_head + put_device + put_disk + put_sg_io_hdr + pwm_apply_state + pwmchip_add + pwmchip_remove + queue_delayed_work_on + queue_work_on + rational_best_approximation + rb_erase + rb_first + rb_insert_color + rb_next + rcu_barrier + rdev_get_drvdata + rdev_get_id + read_cache_page + refcount_warn_saturate + regcache_cache_only + regcache_mark_dirty + regcache_sync + register_blkdev + register_chrdev_region + register_filesystem + register_netdev + register_netdevice + register_netdevice_notifier + register_pernet_device + register_pernet_subsys + register_reboot_notifier + register_shrinker + regmap_add_irq_chip + regmap_bulk_read + regmap_bulk_write + regmap_del_irq_chip + regmap_field_read + regmap_field_update_bits_base + regmap_irq_get_domain + regmap_multi_reg_write + regmap_raw_read + regmap_raw_write + regmap_read + regmap_update_bits_base + regmap_write + regulator_bulk_disable + regulator_bulk_enable + regulator_disable + regulator_disable_regmap + regulator_enable + regulator_enable_regmap + regulator_get + regulator_get_voltage + regulator_get_voltage_sel_regmap + regulator_is_enabled + regulator_is_enabled_regmap + regulator_list_voltage_linear + regulator_list_voltage_linear_range + regulator_map_voltage_iterate + regulator_map_voltage_linear + regulator_map_voltage_linear_range + regulator_put + regulator_register_notifier + regulator_set_active_discharge_regmap + regulator_set_voltage_sel_regmap + regulator_set_voltage_time_sel + regulator_unregister_notifier + release_firmware + release_sock + remap_pfn_range + remove_proc_entry + remove_wait_queue + request_firmware + request_threaded_irq + reset_control_assert + reset_control_deassert + reset_control_put + reset_control_reset + revalidate_disk_size + rfkill_alloc + rfkill_destroy + rfkill_register + rfkill_unregister + round_jiffies_relative + rt_mutex_lock + rt_mutex_trylock + rt_mutex_unlock + rtc_time64_to_tm + rtc_tm_to_time64 + rtc_update_irq + rtnl_lock + rtnl_trylock + rtnl_unlock + sb800_prefetch + scatterwalk_map_and_copy + schedule + schedule_timeout + schedule_timeout_interruptible + schedule_timeout_uninterruptible + scmi_driver_register + scmi_driver_unregister + scnprintf + scsi_add_host_with_dma + scsi_autopm_get_device + scsi_autopm_put_device + scsi_block_when_processing_errors + scsi_command_size_tbl + scsi_compat_ioctl + scsi_device_get + scsi_device_lookup + scsi_device_put + scsi_host_put + scsi_ioctl + scsi_ioctl_block_when_processing_errors + scsi_normalize_sense + scsi_print_sense_hdr + scsi_remove_device + scsi_remove_host + sdev_prefix_printk + sdhci_add_host + sdhci_cleanup_host + sdhci_cqe_disable + sdhci_cqe_enable + sdhci_cqe_irq + sdhci_enable_clk + sdhci_get_property + sdhci_pltfm_free + sdhci_pltfm_init + sdhci_remove_host + sdhci_reset + sdhci_set_bus_width + sdhci_setup_host + sdio_signal_irq + send_sig + seq_lseek + seq_printf + seq_putc + seq_puts + seq_read + set_capacity_revalidate_and_notify + set_disk_ro + set_freezable + set_page_dirty + set_user_nice + sg_alloc_table + sg_alloc_table_from_pages + sg_copy_from_buffer + sg_copy_to_buffer + sg_free_table + sg_init_one + sg_init_table + sg_miter_next + sg_miter_start + sg_miter_stop + sg_next + sg_pcopy_from_buffer + sg_pcopy_to_buffer + sg_scsi_ioctl + sigprocmask + simple_dir_operations + simple_read_from_buffer + simple_strtoul + single_open + single_release + sk_alloc + sk_free + skb_add_rx_frag + skb_clone + skb_copy_bits + skb_copy_datagram_iter + skb_copy_expand + skb_dequeue + skb_pull + skb_pull_rcsum + skb_push + skb_put + skb_queue_purge + skb_queue_tail + skb_recv_datagram + skb_trim + skb_tstamp_tx + skcipher_walk_aead_decrypt + skcipher_walk_aead_encrypt + skcipher_walk_done + snd_ctl_add + snd_ctl_new1 + snd_pcm_add_chmap_ctls + snd_pcm_create_iec958_consumer_hw_params + snd_pcm_format_width + snd_pcm_hw_constraint_eld + snd_pcm_hw_constraint_list + snd_soc_card_jack_new + snd_soc_component_update_bits + snd_soc_component_write + snd_soc_dai_link_set_capabilities + snd_soc_dai_set_sysclk + snd_soc_dai_set_tdm_slot + snd_soc_dapm_add_routes + snd_soc_dapm_disable_pin_unlocked + snd_soc_dapm_force_enable_pin_unlocked + snd_soc_dapm_get_enum_double + snd_soc_dapm_get_pin_switch + snd_soc_dapm_get_volsw + snd_soc_dapm_info_pin_switch + snd_soc_dapm_put_enum_double + snd_soc_dapm_put_pin_switch + snd_soc_dapm_put_volsw + snd_soc_dapm_sync_unlocked + snd_soc_get_enum_double + snd_soc_get_volsw + snd_soc_info_enum_double + snd_soc_info_volsw + snd_soc_jack_add_gpios + snd_soc_jack_report + snd_soc_of_get_dai_name + snd_soc_of_parse_audio_routing + snd_soc_of_parse_audio_simple_widgets + snd_soc_of_parse_aux_devs + snd_soc_of_parse_card_name + snd_soc_of_parse_daifmt + snd_soc_of_parse_node_prefix + snd_soc_of_parse_tdm_slot + snd_soc_params_to_frame_size + snd_soc_pm_ops + snd_soc_put_enum_double + snd_soc_put_volsw + snd_soc_runtime_calc_hw + snprintf + sock_init_data + sock_no_accept + sock_no_listen + sock_no_mmap + sock_no_shutdown + sock_no_socketpair + sock_queue_rcv_skb + sock_release + sort + spi_controller_resume + spi_controller_suspend + spi_finalize_current_transfer + spi_setup + spi_sync + sprintf + sscanf + stpcpy + strcasecmp + strchr + strcmp + strcpy + strcspn + stream_open + strim + strlcat + strlcpy + strlen + strncasecmp + strnchr + strncmp + strncpy + strnlen + strpbrk + strscpy + strsep + strspn + synchronize_irq + synchronize_net + synchronize_rcu + synchronize_srcu + sys_tz + syscon_node_to_regmap + syscon_regmap_lookup_by_phandle + sysfs_add_file_to_group + sysfs_create_group + sysfs_create_link + sysfs_remove_file_from_group + sysfs_remove_group + sysfs_remove_link + sysfs_streq + system_freezing_cnt + system_long_wq + system_state + system_wq + tasklet_init + tasklet_kill + tasklet_setup + thermal_zone_device_disable + thermal_zone_device_enable + thermal_zone_device_update + time64_to_tm + trace_event_buffer_commit + trace_event_buffer_reserve + trace_event_ignore_this_pid + trace_event_raw_init + trace_event_reg + trace_handle_return + trace_print_symbols_seq + trace_raw_output_prep + trace_seq_printf + trace_seq_putc + try_module_get + try_wait_for_completion + tty_flip_buffer_push + tty_hangup + tty_insert_flip_string_fixed_flag + tty_kref_put + tty_mode_ioctl + tty_port_tty_get + tty_register_ldisc + tty_termios_baud_rate + tty_termios_encode_baud_rate + tty_unregister_ldisc + unlock_page + unpin_user_pages + unregister_blkdev + unregister_chrdev_region + unregister_filesystem + unregister_netdev + unregister_netdevice_many + unregister_netdevice_notifier + unregister_netdevice_queue + unregister_pernet_device + unregister_pernet_subsys + unregister_reboot_notifier + unregister_shrinker + up + up_read + up_write + usb_add_gadget_udc + usb_add_hcd + usb_alloc_coherent + usb_alloc_urb + usb_amd_dev_put + usb_amd_quirk_pll_disable + usb_amd_quirk_pll_enable + usb_anchor_urb + usb_bulk_msg + usb_calc_bus_time + usb_control_msg + usb_create_hcd + usb_debug_root + usb_del_gadget_udc + usb_deregister + usb_disabled + usb_ep_set_maxpacket_limit + usb_find_common_endpoints + usb_free_coherent + usb_free_urb + usb_gadget_giveback_request + usb_gadget_map_request + usb_gadget_set_state + usb_gadget_unmap_request + usb_get_dr_mode + usb_hc_died + usb_hcd_check_unlink_urb + usb_hcd_giveback_urb + usb_hcd_link_urb_to_ep + usb_hcd_map_urb_for_dma + usb_hcd_platform_shutdown + usb_hcd_poll_rh_status + usb_hcd_resume_root_hub + usb_hcd_unlink_urb_from_ep + usb_hcds_loaded + usb_hub_clear_tt_buffer + usb_ifnum_to_if + usb_kill_anchored_urbs + usb_kill_urb + usb_phy_set_charger_current + usb_poison_urb + usb_put_dev + usb_put_hcd + usb_register_driver + usb_remove_hcd + usb_role_switch_get_drvdata + usb_role_switch_register + usb_role_switch_unregister + usb_root_hub_lost_power + usb_speed_string + usb_submit_urb + usb_unanchor_urb + usbnet_change_mtu + usbnet_disconnect + usbnet_get_drvinfo + usbnet_get_endpoints + usbnet_get_link + usbnet_get_link_ksettings + usbnet_get_msglevel + usbnet_get_stats64 + usbnet_link_change + usbnet_nway_reset + usbnet_open + usbnet_probe + usbnet_read_cmd + usbnet_read_cmd_nopm + usbnet_resume + usbnet_set_link_ksettings + usbnet_set_msglevel + usbnet_skb_return + usbnet_start_xmit + usbnet_stop + usbnet_suspend + usbnet_tx_timeout + usbnet_write_cmd + usbnet_write_cmd_async + usbnet_write_cmd_nopm + usleep_range + utf16s_to_utf8s + uuid_null + v4l2_async_notifier_add_fwnode_subdev + v4l2_async_notifier_add_subdev + v4l2_async_notifier_cleanup + v4l2_async_notifier_init + v4l2_async_notifier_unregister + v4l2_async_register_subdev + v4l2_async_subdev_notifier_register + v4l2_async_unregister_subdev + v4l2_ctrl_auto_cluster + v4l2_ctrl_handler_free + v4l2_ctrl_handler_init_class + v4l2_ctrl_handler_setup + v4l2_ctrl_new_std + v4l2_ctrl_new_std_menu + v4l2_ctrl_new_std_menu_items + v4l2_i2c_subdev_init + vabits_actual + vfree + vmalloc + vmalloc_to_page + vmap + vscnprintf + vunmap + vzalloc + wait_for_completion + wait_for_completion_interruptible + wait_for_completion_io_timeout + wait_for_completion_killable + wait_for_completion_timeout + wait_woken + wake_up_process + watchdog_init_timeout + watchdog_register_device + watchdog_set_restart_priority + watchdog_unregister_device + woken_wake_function + xa_destroy + xa_erase + xa_find + xa_find_after + xa_load + xa_store diff --git a/android/abi_gki_aarch64_unisoc b/android/abi_gki_aarch64_unisoc deleted file mode 100644 index c1c6e5e983bc..000000000000 --- a/android/abi_gki_aarch64_unisoc +++ /dev/null @@ -1,2571 +0,0 @@ -[abi_symbol_list] -# commonly used symbols - add_timer - add_uevent_var - add_wait_queue - add_to_page_cache_lru - aes_encrypt - aes_expandkey - alloc_anon_inode - alloc_chrdev_region - alloc_netdev_mqs - alloc_pages_exact - __alloc_pages_nodemask - __alloc_percpu - __alloc_skb - alloc_workqueue - __arch_copy_from_user - __arch_copy_in_user - __arch_copy_to_user - arm64_const_caps_ready - arp_tbl - atomic_notifier_call_chain - atomic_notifier_chain_register - atomic_notifier_chain_unregister - bdget_disk - bdput - bio_add_page - bio_alloc_bioset - bio_associate_blkg - bio_endio - bio_put - bit_wait - blk_alloc_queue - blk_finish_plug - blk_start_plug - blk_queue_flag_clear - blk_queue_flag_set - blk_queue_io_min - blk_queue_io_opt - blk_queue_make_request - blk_queue_max_discard_sectors - blk_queue_max_write_zeroes_sectors - blk_queue_physical_block_size - blocking_notifier_chain_register - blocking_notifier_chain_unregister - bpf_trace_run1 - bpf_trace_run2 - bpf_trace_run3 - bpf_trace_run4 - __breadahead - bus_register - bus_set_iommu - bus_unregister - __close_fd - __ClearPageMovable - call_rcu - cancel_delayed_work - cancel_delayed_work_sync - cancel_work_sync - cdev_add - cdev_del - cdev_device_add - cdev_device_del - cdev_init - __cfi_slowpath - __check_object_size - __class_create - class_destroy - class_find_device - clear_nlink - clear_inode - clk_bulk_disable - clk_bulk_enable - clk_bulk_prepare - clk_bulk_unprepare - clk_disable - clk_enable - clk_fixed_factor_ops - clk_get_rate - clk_prepare - clk_put - clk_set_parent - clk_set_rate - clk_unprepare - clocks_calc_mult_shift - clockevents_config_and_register - __clocksource_register_scale - compat_alloc_user_space - complete - complete_all - config_ep_by_speed - config_group_init_type_name - contig_page_data - console_lock - console_unlock - __const_udelay - cpu_have_feature - cpu_hwcap_keys - cpu_hwcaps - cpumask_next - cpufreq_add_update_util_hook - cpufreq_remove_update_util_hook - cpu_number - __cpu_online_mask - __cpu_possible_mask - crypto_alloc_base - crypto_ahash_digest - crypto_ahash_setkey - crypto_alloc_ahash - crypto_destroy_tfm - crypto_has_alg - crypto_inc - __crypto_memneq - crypto_register_aead - crypto_register_shash - crypto_register_shashes - crypto_unregister_aead - crypto_unregister_shash - crypto_unregister_shashes - __crypto_xor - csum_ipv6_magic - csum_partial - __dynamic_netdev_dbg - d_make_root - d_splice_alias - debugfs_create_bool - debugfs_create_dir - debugfs_create_file - debugfs_create_u32 - debugfs_initialized - debugfs_remove - debugfs_remove_recursive - debugfs_create_symlink - dec_zone_page_state - default_llseek - delayed_work_timer_fn - del_timer - del_timer_sync - destroy_workqueue - dev_driver_string - _dev_err - dev_fwnode - dev_get_by_name - dev_get_regmap - device_add - device_connection_find_match - device_create - device_create_file - device_destroy - device_initialize - device_init_wakeup - device_link_add - device_match_fwnode - device_match_name - device_property_present - device_property_read_string - device_property_read_u32_array - device_register - device_remove_file - device_set_wakeup_capable - device_unregister - _dev_info - __dev_kfree_skb_any - devm_add_action - devm_backlight_device_register - devm_clk_bulk_get - devm_clk_bulk_get_all - devm_clk_get - devm_clk_get_optional - devm_free_irq - devm_gpiochip_add_data - devm_gpiod_get - devm_gpio_free - devm_gpio_request - devm_hwspin_lock_request_specific - __devm_iio_device_register - devm_ioremap_nocache - devm_ioremap_resource - devm_kfree - devm_kmalloc - devm_kmemdup - devm_mfd_add_devices - devm_nvmem_register - devm_of_platform_populate - devm_pinctrl_get - devm_pinctrl_put - devm_power_supply_register - __devm_regmap_init - __devm_regmap_init_i2c - __devm_regmap_init_mmio_clk - devm_regulator_get - devm_regulator_register - devm_request_threaded_irq - devm_spi_register_controller - devm_usb_get_phy - devm_usb_get_phy_by_phandle - dev_queue_xmit - dev_set_name - _dev_warn - disable_irq - disable_irq_nosync - dma_alloc_attrs - dma_direct_map_page - dma_direct_sync_single_for_cpu - dma_direct_sync_single_for_device - dma_direct_unmap_page - dma_fence_release - dma_fence_wait_timeout - dma_free_attrs - dma_heap_add - dma_heap_get_dev - dma_heap_get_name - dma_max_mapping_size - dma_set_mask - down - dput - driver_register - driver_unregister - drm_atomic_helper_plane_destroy_state - drm_atomic_helper_plane_duplicate_state - drm_atomic_helper_plane_reset - drm_atomic_helper_setup_commit - drm_compat_ioctl - drm_dbg - drm_dev_alloc - drm_dev_put - drm_dev_register - drm_err - drm_ioctl - drm_mm_init - drm_mm_insert_node_in_range - drm_mm_remove_node - drm_mm_takedown - drm_mode_config_cleanup - drm_mode_config_init - drm_open - drm_plane_create_color_properties - drm_poll - drm_read - drm_release - dst_release - dump_stack - enable_irq - ether_setup - eth_type_trans - event_triggers_call - extcon_find_edev_by_node - extcon_get_edev_by_phandle - extcon_get_state - fb_mode_option - __find_get_block - find_next_bit - finish_wait - flush_work - flush_workqueue - fpsimd_context_busy - fput - free_irq - free_netdev - __free_pages - free_pages_exact - free_percpu - freezing_slow_path - fs_bio_set - fs_ftype_to_dtype - fsync_bdev - fwnode_property_present - fwnode_property_read_string - gen_pool_avail - generic_end_io_acct - generic_file_llseek - generic_handle_irq - generic_read_dir - generic_ro_fops - generic_start_io_acct - genl_register_family - genl_unregister_family - gen_pool_add_owner - gen_pool_alloc_algo_owner - gen_pool_create - gen_pool_free_owner - get_cpu_device - __get_free_pages - get_governor_parent_kobj - get_random_bytes - gov_attr_set_get - gov_attr_set_init - gov_attr_set_put - governor_sysfs_ops - gpiochip_get_data - gpiochip_line_is_irq - gpiod_direction_input - gpiod_direction_output_raw - gpiod_get - gpiod_get_raw_value - gpiod_set_raw_value - gpiod_set_raw_value_cansleep - gpiod_to_chip - gpiod_to_irq - gpio_free - gpio_request - gpio_to_desc - handle_bad_irq - handle_edge_irq - handle_level_irq - have_governor_per_policy - i2c_del_driver - i2c_register_driver - i2c_smbus_read_byte_data - i2c_smbus_write_byte_data - i2c_transfer_buffer_flags - ida_alloc_range - ida_destroy - ida_free - idr_alloc - idr_destroy - idr_find - idr_for_each - idr_remove - ieee80211_channel_to_freq_khz - ieee80211_freq_khz_to_channel - ieee80211_get_channel_khz - iget_failed - iget5_locked - ignore_console_lock_warning - igrab - inet_proto_csum_replace4 - init_net - __init_rwsem - init_timer_key - init_user_ns - init_wait_entry - init_pseudo - init_special_inode - __init_waitqueue_head - inc_zone_page_state - inode_init_once - inode_nohighmem - input_alloc_absinfo - input_allocate_device - input_event - input_free_device - input_mt_get_slot_by_key - input_mt_sync_frame - input_register_device - iommu_alloc_resv_region - iommu_attach_device - iommu_detach_device - iommu_device_link - iommu_device_register - iommu_device_sysfs_add - iommu_device_sysfs_remove - iommu_device_unlink - iommu_device_unregister - iommu_dma_get_resv_regions - iommu_domain_alloc - iommu_domain_free - iommu_domain_get_attr - iommu_domain_set_attr - iommu_fwspec_add_ids - iommu_fwspec_free - iommu_get_dma_cookie - iommu_get_domain_for_dev - iommu_group_alloc - iommu_group_get - iommu_group_get_for_dev - iommu_group_get_iommudata - iommu_group_put - iommu_group_ref_get - iommu_group_remove_device - iommu_group_set_iommudata - iommu_map - iommu_map_sg - iommu_present - iommu_put_dma_cookie - iommu_set_fault_handler - iommu_unmap - __ioremap - iounmap - iput - ip6t_alloc_initial_table - ip6t_do_table - ip6t_register_table - ip6t_unregister_table - ip_route_output_flow - ipv4_redirect - ipv4_update_pmtu - ir_lirc_scancode_event - ir_raw_gen_manchester - ir_raw_gen_pd - ir_raw_handler_register - ir_raw_handler_unregister - ir_raw_gen_pl - irq_find_mapping - irq_get_irq_data - irq_modify_status - irq_of_parse_and_map - irq_set_irq_type - irq_set_irq_wake - irq_work_sync - is_console_locked - jiffies - jiffies_to_msecs - kern_mount - kern_unmount - kernel_kobj - kasprintf - kernel_neon_begin - kernel_neon_end - __kfifo_alloc - __kfifo_free - __kfifo_in - __kfifo_out - kfree - kfree_skb - kill_anon_super - kimage_vaddr - kimage_voffset - __kmalloc - kmalloc_caches - kmalloc_order_trace - kmem_cache_alloc - kmem_cache_alloc_trace - kmem_cache_create - kmem_cache_destroy - kmem_cache_free - kmemdup - kobject_create_and_add - kobject_uevent_env - kstrndup - kstrtou16 - kstrtobool - kstrtoint - kstrtoll - kstrtouint - kstrtoull - kthread_create_on_node - kthread_should_stop - kthread_stop - ktime_get - ktime_get_mono_fast_ns - ktime_get_real_seconds - ktime_get_real_ts64 - kzfree - LZ4_decompress_safe_partial - lzo1x_decompress_safe - lzorle1x_1_compress - lzo1x_1_compress - __list_add_valid - __list_del_entry_valid - memcpy - __memcpy_fromio - memmove - memparse - memset - memset64 - misc_deregister - misc_register - mod_node_page_state - mod_timer - module_put - __msecs_to_jiffies - msleep - __mutex_init - mutex_lock - mutex_lock_interruptible - mutex_trylock - mutex_unlock - nd_tbl - neigh_destroy - __netdev_alloc_skb - __num_online_cpus - netif_carrier_off - netif_carrier_on - netif_rx_ni - netif_tx_wake_queue - nf_conntrack_destroy - nf_conntrack_find_get - nf_ct_get_tuplepr - nf_ct_invert_tuple - nf_ct_l4proto_find - nf_register_net_hooks - nf_unregister_net_hooks - nr_cpu_ids - nvmem_cell_get - nvmem_cell_put - nvmem_cell_read - of_address_to_resource - of_alias_get_id - of_clk_get - of_clk_get_parent_count - of_count_phandle_with_args - of_device_get_match_data - of_device_is_available - of_device_is_compatible - of_dev_put - of_find_compatible_node - of_find_device_by_node - of_find_node_by_name - of_find_property - of_get_child_by_name - of_get_named_gpio_flags - of_get_next_available_child - of_get_next_child - of_get_property - of_get_regulator_init_data - of_graph_get_remote_node - of_irq_get - of_match_node - of_nvmem_cell_get - of_parse_phandle - of_parse_phandle_with_args - of_parse_phandle_with_fixed_args - of_platform_depopulate - of_platform_populate - of_property_count_elems_of_size - of_property_match_string - of_property_read_string - of_property_read_u32_index - of_property_read_u64 - of_property_read_variable_u32_array - of_prop_next_string - oops_in_progress - out_of_line_wait_on_bit_lock - overflowgid - overflowuid - panic - page_endio - page_get_link - page_mapping - pagecache_get_page - param_ops_charp - param_ops_uint - param_ops_ushort - __pci_register_driver - pci_set_master - pci_unregister_driver - PDE_DATA - __per_cpu_offset - perf_trace_buf_alloc - perf_trace_run_bpf_submit - pfn_valid - pinctrl_lookup_state - pinctrl_select_state - pinctrl_pm_select_default_state - pinctrl_pm_select_sleep_state - platform_bus_type - platform_device_add - platform_device_add_properties - platform_device_add_resources - platform_device_alloc - platform_device_put - platform_device_register - platform_device_register_full - platform_device_unregister - __platform_driver_register - platform_driver_unregister - platform_get_irq - platform_get_irq_byname - platform_get_resource - platform_get_resource_byname - pm_power_off - __pm_relax - pm_runtime_allow - __pm_runtime_disable - pm_runtime_enable - pm_runtime_forbid - pm_runtime_force_resume - pm_runtime_force_suspend - __pm_runtime_idle - __pm_runtime_resume - pm_runtime_set_autosuspend_delay - __pm_runtime_set_status - __pm_runtime_suspend - __pm_runtime_use_autosuspend - __pm_stay_awake - pm_wakeup_ws_event - posix_acl_access_xattr_handler - posix_acl_default_xattr_handler - posix_acl_from_xattr - power_supply_changed - power_supply_get_battery_info - power_supply_get_by_name - power_supply_get_drvdata - power_supply_get_property - power_supply_powers - power_supply_put - ppp_input - ppp_register_compressor - ppp_unregister_compressor - preempt_schedule - preempt_schedule_notrace - prepare_to_wait_event - printk - proc_create - proc_create_data - proc_create_seq_private - proc_mkdir - __pskb_copy_fclone - pskb_expand_head - put_device - put_pages_list - put_tty_driver - queue_delayed_work_on - queue_work_on - ___ratelimit - _raw_read_lock - _raw_read_unlock - _raw_spin_lock - _raw_spin_lock_bh - _raw_spin_lock_irq - _raw_spin_lock_irqsave - _raw_spin_unlock - _raw_spin_unlock_bh - _raw_spin_unlock_irq - _raw_spin_unlock_irqrestore - _raw_write_lock - _raw_write_unlock - __rcu_read_lock - __rcu_read_unlock - radix_tree_preload - radix_tree_delete - radix_tree_gang_lookup - radix_tree_insert - radix_tree_lookup - rc_map_unregister - rc_repeat - rc_keydown - rc_map_register - rdev_get_drvdata - refcount_dec_and_test_checked - refcount_inc_checked - __refrigerator - __register_chrdev - read_cache_page - read_cache_page_gfp - register_filesystem - register_pernet_subsys - register_pm_notifier - regmap_read - regmap_update_bits_base - regmap_write - regulator_disable - regulator_disable_regmap - regulator_enable - regulator_enable_regmap - regulator_get_voltage_sel_regmap - regulator_is_enabled_regmap - regulator_list_voltage_linear - regulator_map_voltage_linear - regulator_set_voltage_sel_regmap - release_firmware - remap_pfn_range - remove_proc_entry - remove_wait_queue - __request_module - request_threaded_irq - reset_control_assert - reset_control_deassert - revalidate_disk - rfkill_alloc - rfkill_destroy - rfkill_init_sw_state - rfkill_register - rfkill_unregister - __SetPageMovable - sched_clock - sched_setscheduler - schedule - schedule_timeout - schedule_timeout_interruptible - scnprintf - seq_lseek - seq_printf - seq_putc - seq_puts - seq_read - set_nlink - set_normalized_timespec64 - set_user_nice - sg_init_table - sg_miter_next - sg_miter_start - sg_miter_stop - sg_nents - sg_next - simple_attr_open - simple_attr_read - simple_attr_release - simple_attr_write - simple_get_link - simple_read_from_buffer - simple_strtol - single_open - single_release - skb_clone - skb_copy - skb_cow_data - skb_ensure_writable - skb_push - skb_put - skb_realloc_headroom - skb_to_sgvec_nomark - skb_trim - skcipher_walk_aead_decrypt - skcipher_walk_aead_encrypt - skcipher_walk_done - skcipher_walk_virt - sk_free - snd_info_create_card_entry - snd_info_free_entry - snd_info_get_line - snd_info_register - snd_pcm_hw_constraint_minmax - snd_pcm_lib_ioctl - snd_pcm_period_elapsed - snd_soc_add_component_controls - snd_soc_dapm_disable_pin - snd_soc_dapm_enable_pin - snd_soc_dapm_ignore_suspend - snd_soc_dapm_kcontrol_dapm - snd_soc_dapm_put_enum_double - snd_soc_dapm_put_volsw - snd_soc_dapm_sync - snd_soc_info_enum_double - snd_soc_info_volsw - snd_soc_pm_ops - snd_soc_register_component - snd_soc_unregister_component - snprintf - __spi_alloc_controller - sprintf - sscanf - __stack_chk_fail - __stack_chk_guard - strcasecmp - strcat - strchr - strcmp - strcpy - strlcat - strlcpy - strlen - strncasecmp - strncmp - strncpy - strncpy_from_user - strnlen - strnstr - strstr - __sw_hweight32 - __sw_hweight64 - submit_bio - sync_filesystem - synchronize_irq - syscon_regmap_lookup_by_phandle - syscon_regmap_lookup_by_phandle_args - sysfs_create_bin_file - sysfs_create_file_ns - sysfs_create_group - sysfs_create_groups - sysfs_create_link - __sysfs_match_string - sysfs_notify - sysfs_remove_bin_file - sysfs_remove_file_ns - sysfs_remove_group - sysfs_remove_groups - sysfs_remove_link - sysfs_streq - system_freezable_wq - system_freezing_cnt - system_unbound_wq - system_wq - sys_tz - tasklet_init - tasklet_kill - __tasklet_schedule - thermal_zone_get_zone_by_name - timer_of_init - trace_define_field - trace_event_buffer_commit - trace_event_buffer_reserve - trace_event_ignore_this_pid - trace_event_raw_init - trace_event_reg - trace_handle_return - trace_raw_output_prep - trace_seq_printf - try_module_get - __tty_alloc_driver - tty_flip_buffer_push - __tty_insert_flip_char - tty_insert_flip_string_fixed_flag - tty_kref_put - tty_port_close - tty_port_destroy - tty_port_hangup - tty_port_init - tty_port_link_device - tty_port_open - tty_port_register_device - tty_port_tty_get - tty_port_tty_wakeup - tty_register_driver - tty_set_operations - tty_standard_install - tty_std_termios - tty_termios_baud_rate - tty_unregister_device - tty_unregister_driver - tty_vhangup - __ubsan_handle_cfi_check_fail_abort - __udelay - __unregister_chrdev - unlock_new_inode - unlock_page - unregister_filesystem - unregister_chrdev_region - unregister_pernet_subsys - up - usb_add_gadget_udc - usb_alloc_coherent - usb_alloc_urb - usb_autopm_get_interface - usb_autopm_get_interface_no_resume - usb_autopm_put_interface - usb_control_msg - usb_del_gadget_udc - usb_deregister - usb_ep_alloc_request - usb_ep_autoconfig - usb_ep_dequeue - usb_ep_enable - usb_ep_free_request - usb_ep_queue - usb_ep_set_maxpacket_limit - usb_find_common_endpoints - usb_free_coherent - usb_free_urb - usb_function_register - usb_function_unregister - usb_gadget_giveback_request - usb_gadget_udc_reset - usb_get_dr_mode - usb_get_intf - usb_hcd_is_primary_hcd - usb_interface_id - usb_kill_urb - usb_phy_get_charger_current - usb_phy_set_charger_current - usb_put_function_instance - usb_put_intf - usb_register_driver - usb_submit_urb - usleep_range - vabits_actual - vfree - vmalloc - vm_map_ram - vm_unmap_aliases - vm_unmap_ram - vm_iomap_memory - vsnprintf - vunmap - wait_for_completion - wait_for_completion_interruptible - wait_for_completion_interruptible_timeout - wait_for_completion_timeout - __wake_up - __wake_up_locked - wake_up_bit - wake_up_process - wakeup_source_add - wakeup_source_create - wakeup_source_destroy - wakeup_source_register - wakeup_source_remove - wakeup_source_unregister - __warn_printk - xfrm4_protocol_deregister - xfrm4_protocol_register - xfrm4_rcv - xfrm_aalg_get_byname - xfrm_input - xfrm_input_resume - xfrm_output_resume - xfrm_register_type - __xfrm_state_destroy - xfrm_state_lookup - xfrm_unregister_type - xt_register_match - xt_register_matches - xt_register_target - xt_register_targets - xt_unregister_match - xt_unregister_matches - xt_unregister_target - xt_unregister_targets - -# required by blk-mq-virtio.ko - blk_mq_map_queues - -# required by cdc-acm.ko - capable - cdc_parse_cdc_header - default_wake_function - refcount_inc_not_zero_checked - tty_port_put - tty_port_tty_hangup - usb_anchor_urb - usb_autopm_get_interface_async - usb_autopm_put_interface_async - usb_clear_halt - usb_driver_claim_interface - usb_driver_release_interface - usb_get_from_anchor - usb_ifnum_to_if - -# required by charger-manager.ko - alarm_cancel - alarm_expires_remaining - alarm_init - alarm_start - alarmtimer_get_rtcdev - devm_kasprintf - ns_to_timespec64 - orderly_poweroff - power_supply_set_property - regulator_force_disable - regulator_set_current_limit - thermal_zone_get_temp - -# required by clk-sprd.ko - clk_hw_get_num_parents - clk_hw_get_parent - clk_hw_is_enabled - __clk_mux_determine_rate - devm_clk_hw_register - devm_of_clk_add_hw_provider - divider_get_val - divider_recalc_rate - divider_round_rate_parent - of_clk_hw_onecell_get - -# required by cpufreq_userspace.ko - __cpufreq_driver_target - cpufreq_register_governor - cpufreq_unregister_governor - -# required by dwc3-haps.ko - pcim_enable_device - -# required by dwc3-of-simple.ko - clk_bulk_get_all - clk_bulk_put_all - of_reset_control_array_get - reset_control_put - reset_control_reset - -# required by dwc3-qcom.ko - devm_extcon_register_notifier - devm_reset_control_array_get - -# required by dwc3.ko - extcon_register_notifier - extcon_unregister_notifier - usb_gadget_map_request_by_dev - usb_gadget_set_state - -# required by exfat.ko - __blockdev_direct_IO - block_write_full_page - __bread_gfp - __brelse - cont_write_begin - current_time - d_find_alias - d_instantiate - d_move - drop_nlink - filemap_fdatawait_range - filemap_fdatawrite_range - full_name_hash - generic_block_bmap - generic_cont_expand_simple - generic_fh_to_dentry - generic_fh_to_parent - generic_file_fsync - generic_file_mmap - generic_file_read_iter - generic_file_splice_read - generic_file_write_iter - generic_fillattr - generic_write_end - __getblk_gfp - ilookup - inc_nlink - in_group_p - __insert_inode_hash - invalidate_inode_buffers - iunique - kill_block_super - kvfree - kvmalloc_node - load_nls - __lock_buffer - __lock_page - new_inode - mark_buffer_dirty - __mark_inode_dirty - match_int - match_octal - match_strdup - match_token - mktime64 - mount_bdev - mpage_readpage - mpage_readpages - mpage_writepages - __remove_inode_hash - setattr_copy - setattr_prepare - sb_min_blocksize - sb_set_blocksize - strscpy - sync_blockdev - sync_dirty_buffer - sync_mapping_buffers - time64_to_tm - touch_buffer - trace_print_symbols_seq - truncate_inode_pages - truncate_pagecache - truncate_setsize - unload_nls - unlock_buffer - utf16s_to_utf8s - utf8s_to_utf16s - write_inode_now - -# required by fan53555.ko - regulator_set_voltage_time_sel - -# required by focaltech_ats.ko - devm_input_allocate_device - devm_regulator_put - i2c_new_probed_device - i2c_transfer - input_mt_init_slots - input_mt_report_slot_state - input_set_abs_params - input_set_capability - kobject_put - of_find_i2c_adapter_by_node - of_property_read_variable_u8_array - request_firmware_nowait - -# required by gpio-eic-sprd.ko - gpiochip_find - -# required by gpio-pmic-eic-sprd.ko - handle_nested_irq - -# required by gpio-sprd.ko - __platform_driver_probe - -# required by i2c-sprd.ko - i2c_add_numbered_adapter - i2c_del_adapter - -# required by img_mem.ko - dma_direct_map_sg - dma_direct_sync_sg_for_cpu - dma_direct_sync_sg_for_device - dma_direct_unmap_sg - idr_get_next - sg_alloc_table - sg_free_table - vsprintf - -# required by ims_bridge.ko - in4_pton - in6_pton - inet_select_addr - ip6_local_out - ip6_route_output_flags - ip_local_out - ipv6_dev_get_saddr - mempool_alloc - mempool_alloc_slab - mempool_create - mempool_destroy - mempool_free - mempool_free_slab - nf_ct_get_tuplepr - nf_ct_invert_tuple - param_ops_int - prandom_u32 - proc_create_net_data - __pskb_pull_tail - skb_checksum_help - rcu_barrier - strim - xfrm_lookup - completion_done - -# required by kfifo_buf.ko - devres_add - devres_alloc_node - devres_free - devres_release - iio_buffer_init - iio_buffer_put - __kfifo_to_user - -# required by leds-sc27xx-bltc.ko - devm_led_classdev_register_ext - -# required by mali_gondul.ko - anon_inode_getfd - __bitmap_weight - clear_page - devfreq_add_device - devfreq_remove_device - devfreq_resume_device - devfreq_suspend_device - dev_pm_opp_disable - dev_pm_opp_find_freq_floor - dev_pm_opp_put_regulators - dev_pm_opp_set_regulators - dma_fence_get_status - dma_fence_remove_callback - downgrade_write - down_trylock - get_user_pages - get_user_pages_fast - get_user_pages_remote - hrtimer_active - hrtimer_forward - iomem_resource - kstrtobool_from_user - memstart_addr - __mmdrop - nonseekable_open - of_property_read_variable_u64_array - param_ops_byte - rb_erase - rb_first - rb_insert_color - rb_next - rb_prev - rb_replace_node - regulator_get_optional - __release_region - remap_vmalloc_range - __request_region - reservation_ww_class - seq_open - __seq_open_private - seq_release_private - seq_write - set_page_dirty_lock - strcspn - system_highpri_wq - trace_print_flags_seq - vmalloc_user - ww_mutex_lock - ww_mutex_unlock - -# required by microarray_fp.ko - cdev_alloc - -# required by mmc_hsq.ko - mmc_cqe_request_done - mmc_send_tuning - -# required by musb_hdrc.ko - device_wakeup_enable - dev_printk - flush_delayed_work - flush_dcache_page - param_ops_bool - usb_add_hcd - usb_create_hcd - usb_ep_set_halt - usb_hcd_check_unlink_urb - usb_hcd_giveback_urb - usb_hcd_link_urb_to_ep - usb_hcd_map_urb_for_dma - usb_hcd_poll_rh_status - usb_hcd_resume_root_hub - usb_hcd_unlink_urb_from_ep - usb_hcd_unmap_urb_for_dma - usb_otg_state_string - usb_put_hcd - usb_remove_hcd - -# required by musb_sprd.ko - usb_ep_disable - usb_speed_string - -# required by pcie-sprd.ko - device_get_next_child_node - devm_gpiod_get_index - devm_ioremap - dw_pcie_host_init - dw_pcie_msi_init - dw_pcie_setup_rc - dw_pcie_wait_for_link - fwnode_handle_put - gpiod_get_value - of_fwnode_ops - pci_assign_unassigned_bus_resources - pci_bus_add_devices - pci_check_and_mask_intx - pci_check_and_unmask_intx - pci_clear_master - pcie_bus_configure_settings - pci_enable_msi - pci_intx - pci_ioremap_bar - pci_ioremap_wc_bar - pci_lock_rescan_remove - pci_reset_function - pci_scan_child_bus - pci_stop_and_remove_bus_device - pci_unlock_rescan_remove - sdio_claim_irq - sdio_f0_readb - sdio_f0_writeb - sdio_get_host_pm_caps - sdio_readw - sdio_release_irq - sdio_set_host_pm_flags - sdio_writew - -# required by phy-sprd-sharkl3.ko - usb_add_phy_dev - usb_phy_set_charger_state - usb_remove_phy - -# required by pinctrl-sprd.ko - devm_platform_ioremap_resource - of_property_read_string_helper - pinconf_generic_parse_dt_config - pinctrl_dev_get_drvdata - pinctrl_register - pinctrl_unregister - pinctrl_utils_add_map_configs - pinctrl_utils_add_map_mux - pinctrl_utils_free_map - pinctrl_utils_reserve_map - pin_get_name - -# required by pvrsrvkm.ko - autoremove_wake_function - bpf_trace_run6 - bpf_trace_run7 - bpf_trace_run8 - cache_line_size - devfreq_cooling_unregister - devfreq_recommended_opp - devfreq_register_opp_notifier - devfreq_unregister_opp_notifier - devm_devfreq_add_device - devm_devfreq_remove_device - dev_pm_opp_add - dev_pm_opp_find_freq_ceil - dev_pm_opp_get_freq - dev_pm_opp_get_opp_count - dev_pm_opp_get_voltage - dev_pm_opp_of_add_table - dev_pm_opp_of_register_em - dev_pm_opp_of_remove_table - dev_pm_opp_put - dma_buf_attach - dma_buf_begin_cpu_access - dma_buf_detach - dma_buf_end_cpu_access - dma_buf_export - dma_buf_fd - dma_buf_get - dma_buf_kmap - dma_buf_kunmap - dma_buf_map_attachment - dma_buf_mmap - dma_buf_put - dma_buf_unmap_attachment - dma_buf_vmap - dma_buf_vunmap - dma_fence_add_callback - dma_fence_array_ops - dma_fence_context_alloc - dma_fence_default_wait - dma_fence_enable_sw_signaling - dma_fence_free - dma_fence_init - dma_fence_signal - down_read - down_write - drm_dev_unregister - fd_install - fget - find_vma - find_vpid - __get_task_comm - get_unused_fd_flags - idr_preload - idr_replace - ion_query_heaps_kernel - kill_pid - ksize - kthread_freezable_should_stop - ktime_get_raw_ts64 - memcmp - mutex_is_locked - of_devfreq_cooling_register_power - of_hwspin_lock_get_id_byname - of_modalias_node - on_each_cpu - prepare_to_wait - proc_remove - put_unused_fd - _raw_read_lock_bh - _raw_read_unlock_bh - _raw_write_lock_bh - _raw_write_unlock_bh - register_shrinker - request_firmware - seq_vprintf - set_freezable - si_meminfo - split_page - strncat - strsep - sync_file_create - sync_file_get_fence - __task_pid_nr_ns - trace_set_clr_event - unmap_mapping_range - unregister_shrinker - up_read - up_write - __usecs_to_jiffies - vmf_insert_mixed - vm_get_page_prot - vm_insert_page - vsscanf - vzalloc - -# required by pwm-sprd.ko - pwmchip_add - pwmchip_remove - -# required by pwm_bl.ko - backlight_device_register - backlight_device_unregister - devm_pwm_get - gpiod_get_direction - int_pow - pwm_free - pwm_request - -# required by roles.ko - fwnode_connection_find_match - fwnode_get_parent - -# required by rtc-sc27xx.ko - devm_rtc_allocate_device - rtc_ktime_to_tm - __rtc_register_device - rtc_time64_to_tm - rtc_tm_to_time64 - rtc_update_irq - -# required by sc2703-bl.ko - of_pwm_get - pwm_apply_state - -# required by sc2703_disp.ko - mfd_add_devices - -# required by sc2703_regulator.ko - regulator_notifier_call_chain - -# required by sc27xx_adc.ko - devm_iio_device_alloc - hwspin_lock_free - hwspin_lock_request_specific - __hwspin_lock_timeout - __hwspin_unlock - of_hwspin_lock_get_id - -# required by sc27xx_fuel_gauge.ko - devm_iio_channel_get - gpiod_get_value_cansleep - iio_read_channel_processed - power_supply_find_ocv2cap_table - power_supply_ocv2cap_simple - power_supply_put_battery_info - power_supply_temp2resist_simple - -# required by sc27xx_pd.ko - device_get_named_child_node - devm_extcon_register_notifier_all - devm_regulator_get_optional - -# required by sc27xx_typec.ko - devm_extcon_dev_allocate - devm_extcon_dev_register - extcon_set_state_sync - typec_register_partner - typec_register_port - typec_set_data_role - typec_set_pwr_opmode - typec_set_pwr_role - typec_set_vconn_role - typec_unregister_partner - typec_unregister_port - -# required by sc27xx-vibra.ko - input_ff_create_memless - -# required by sc9863a-clk.ko - device_get_match_data - -# required by sdhci-sprd.ko - clk_round_rate - mmc_free_host - mmc_of_parse - mmc_regulator_set_vqmmc - mmc_remove_host - mmc_request_done - __sdhci_add_host - sdhci_cleanup_host - sdhci_enable_clk - sdhci_enable_v4_mode - sdhci_pltfm_free - sdhci_pltfm_init - sdhci_remove_host - sdhci_request - sdhci_request_atomic - sdhci_reset - sdhci_runtime_resume_host - sdhci_runtime_suspend_host - sdhci_set_bus_width - sdhci_setup_host - -# required by sdiohal.ko - mmc_detect_change - mmc_set_data_timeout - mmc_wait_for_req - __put_page - print_hex_dump - sdio_claim_host - sdio_enable_func - sdio_memcpy_fromio - sdio_memcpy_toio - sdio_readb - sdio_readl - sdio_readsb - sdio_register_driver - sdio_release_host - sdio_set_block_size - sdio_unregister_driver - sdio_writeb - sdio_writel - sdio_writesb - __trace_bprintk - -# required by seth.ko - napi_complete_done - napi_disable - __napi_schedule - napi_schedule_prep - netif_napi_add - netif_napi_del - netif_receive_skb - register_netdev - unregister_netdev - -# required by sfp_core.ko - csum_tcpudp_nofold - dev_get_by_index_rcu - ip_send_check - ipv6_ext_hdr - ipv6_find_hdr - kstrtouint_from_user - __local_bh_enable_ip - nf_conntrack_destroy - nf_conntrack_find_get - of_dma_configure - proc_dointvec - register_netdevice_notifier - register_net_sysctl - rt6_lookup - seq_open_private - seq_release - skb_copy_bits - unregister_netdevice_notifier - -# required by shubcore.ko - iio_alloc_pollfunc - iio_dealloc_pollfunc - iio_device_alloc - iio_device_attach_buffer - iio_device_free - iio_device_unregister - iio_pollfunc_store_time - iio_push_to_buffers - iio_trigger_alloc - iio_triggered_buffer_postenable - iio_triggered_buffer_predisable - iio_trigger_free - iio_trigger_notify_done - iio_trigger_poll - __iio_trigger_register - iio_trigger_unregister - ktime_get_with_offset - param_array_ops - unregister_pm_notifier - -# required by sipa_core.ko - free_pages - memremap - memunmap - pm_wakeup_dev_event - skb_dequeue - skb_queue_tail - -# required by sipa_sys_pd.ko - kstrdup - of_genpd_add_provider_simple - pm_genpd_init - pm_genpd_remove - -# required by sipc_core.ko - gen_pool_destroy - mbox_chan_received_data - mbox_chan_txdone - mbox_client_txdone - mbox_controller_register - mbox_controller_unregister - mbox_free_channel - mbox_request_channel - mbox_request_channel_byname - mbox_send_message - register_syscore_ops - -# required by sipx.ko - hrtimer_cancel - hrtimer_init - hrtimer_start_range_ns - hrtimer_try_to_cancel - -# required by snd-soc-aw881xx.ko - i2c_smbus_write_byte - -# required by snd-soc-akm4377.ko - regcache_mark_dirty - regcache_sync - snd_soc_get_volsw - snd_soc_put_volsw - -# required by snd-soc-sprd-audio-dma.ko - dmam_alloc_attrs - dmam_free_coherent - dma_release_channel - __memset_io - of_dma_request_slave_channel - snd_pcm_format_physical_width - snd_pcm_hw_constraint_integer - snd_pcm_hw_constraint_step - snd_soc_rtdcom_lookup - snd_soc_set_runtime_hwparams - vmap - -# required by snd-soc-sprd-card.ko - devm_gpio_request_one - devm_snd_soc_register_card - gpio_request_one - snd_interval_refine - snd_soc_of_get_dai_name - snd_soc_of_parse_audio_routing - snd_soc_of_parse_audio_simple_widgets - snd_soc_of_parse_card_name - snd_soc_of_parse_daifmt - snd_soc_of_parse_tdm_slot - -# required by snd-soc-sprd-codec-sc2721-power.ko - regulator_register - regulator_unregister - -# required by snd-soc-sprd-codec-sc2721.ko - dapm_regulator_event - gpiod_set_debounce - iio_channel_get - iio_read_channel_raw - iio_write_channel_attribute - irq_to_desc - power_supply_register - power_supply_unregister - regulator_get - regulator_get_mode - regulator_is_enabled - regulator_put - regulator_set_mode - regulator_set_voltage - snd_ctl_find_id - snd_jack_set_key - snd_pcm_rate_to_rate_bit - snd_soc_card_jack_new - snd_soc_component_read32 - snd_soc_component_update_bits - snd_soc_component_write - snd_soc_dapm_force_enable_pin - snd_soc_dapm_get_enum_double - snd_soc_dapm_get_volsw - snd_soc_get_enum_double - snd_soc_jack_report - snd_soc_put_enum_double - -# required by snd-soc-sprd-platform.ko - devm_snd_soc_register_component - dma_request_slave_channel - of_reserved_mem_device_init_by_idx - snd_dma_alloc_pages - snd_dma_free_pages - -# required by snd-soc-sprd-vbc-r1p0v3.ko - snd_ctl_boolean_mono_info - snd_pcm_hw_constraint_list - -# required by snd-soc-tfa98xx.ko - crc32_le - device_create_bin_file - device_remove_bin_file - msleep_interruptible - snd_pcm_format_width - snd_pcm_hw_constraint_mask64 - snd_soc_dapm_add_routes - snd_soc_dapm_new_controls - -# required by sprd-cpufreq-common.ko - dev_pm_opp_remove - -# required by sprd-cpufreqhw.ko - arch_set_freq_scale - cpufreq_generic_attr - cpufreq_generic_frequency_table_verify - cpufreq_generic_get - cpufreq_generic_suspend - cpufreq_register_driver - cpufreq_unregister_driver - dev_pm_opp_free_cpufreq_table - dev_pm_opp_init_cpufreq_table - -# required by sprd-drm.ko - adjust_managed_page_count - component_add - component_bind_all - component_del - component_master_add_with_match - component_master_del - component_match_add_release - component_unbind_all - devm_gpiod_get_optional - dma_get_sgtable_attrs - dma_mmap_attrs - dma_set_coherent_mask - drm_add_edid_modes - drm_atomic_helper_async_commit - drm_atomic_helper_check - drm_atomic_helper_cleanup_planes - drm_atomic_helper_commit - drm_atomic_helper_commit_cleanup_done - drm_atomic_helper_commit_hw_done - drm_atomic_helper_commit_modeset_disables - drm_atomic_helper_commit_modeset_enables - drm_atomic_helper_commit_planes - drm_atomic_helper_commit_tail - drm_atomic_helper_commit_tail_rpm - drm_atomic_helper_connector_destroy_state - drm_atomic_helper_connector_duplicate_state - drm_atomic_helper_connector_reset - drm_atomic_helper_crtc_destroy_state - drm_atomic_helper_crtc_duplicate_state - drm_atomic_helper_crtc_reset - drm_atomic_helper_disable_plane - drm_atomic_helper_page_flip - __drm_atomic_helper_plane_destroy_state - __drm_atomic_helper_plane_duplicate_state - __dynamic_dev_dbg - __dynamic_pr_debug - drm_atomic_helper_prepare_planes - drm_atomic_helper_resume - drm_atomic_helper_set_config - drm_atomic_helper_shutdown - drm_atomic_helper_suspend - drm_atomic_helper_swap_state - drm_atomic_helper_update_legacy_modeset_state - drm_atomic_helper_update_plane - drm_atomic_helper_wait_for_dependencies - drm_atomic_helper_wait_for_fences - drm_atomic_helper_wait_for_vblanks - drm_atomic_private_obj_fini - drm_atomic_private_obj_init - drm_atomic_set_crtc_for_connector - drm_atomic_set_fence_for_plane - drm_atomic_set_mode_for_crtc - drm_atomic_state_alloc - drm_atomic_state_clear - drm_atomic_state_default_clear - drm_atomic_state_default_release - __drm_atomic_state_free - drm_bridge_attach - drm_connector_attach_content_protection_property - drm_connector_attach_encoder - drm_connector_cleanup - drm_connector_init - drm_connector_unregister - drm_connector_update_edid_property - drm_crtc_cleanup - __drm_crtc_commit_free - drm_crtc_handle_vblank - drm_crtc_init_with_planes - drm_crtc_send_vblank_event - drm_crtc_vblank_off - drm_crtc_vblank_on - drm_detect_monitor_audio - drm_display_mode_from_videomode - drm_display_mode_to_videomode - drm_dp_aux_register - drm_dp_aux_unregister - drm_dp_calc_pbn_mode - drm_dp_channel_eq_ok - drm_dp_clock_recovery_ok - drm_dp_dpcd_read - drm_dp_dpcd_read_link_status - drm_dp_dpcd_write - drm_encoder_cleanup - drm_encoder_init - drm_format_info - drm_gem_cma_prime_get_sg_table - drm_gem_cma_prime_mmap - drm_gem_cma_prime_vmap - drm_gem_cma_prime_vunmap - drm_gem_cma_vm_ops - drm_gem_create_mmap_offset - drm_gem_fb_create - drm_gem_fb_get_obj - drm_gem_handle_create - drm_gem_mmap - drm_gem_mmap_obj - drm_gem_object_init - drm_gem_object_put_unlocked - drm_gem_object_release - drm_gem_prime_export - drm_gem_prime_fd_to_handle - drm_gem_prime_handle_to_fd - drm_gem_prime_import - drm_gem_vm_close - drm_get_edid - drm_hdcp_check_ksvs_revoked - drm_hdcp_update_content_protection - drm_helper_hpd_irq_event - drm_helper_probe_single_connector_modes - drm_kms_helper_poll_disable - drm_kms_helper_poll_enable - drm_kms_helper_poll_fini - drm_kms_helper_poll_init - drm_match_cea_mode - drm_mode_config_reset - drm_mode_create - drm_mode_crtc_set_gamma_size - drm_mode_destroy - drm_mode_duplicate - drm_mode_probed_add - drm_mode_vrefresh - drm_object_attach_property - drm_panel_add - drm_panel_attach - drm_panel_detach - drm_panel_disable - drm_panel_enable - drm_panel_get_modes - drm_panel_init - drm_panel_prepare - drm_panel_remove - drm_panel_unprepare - drm_plane_cleanup - drm_plane_create_alpha_property - drm_plane_create_blend_mode_property - drm_plane_create_rotation_property - drm_plane_create_zpos_immutable_property - drm_prime_gem_destroy - drm_property_create - drm_property_create_blob - drm_property_create_range - drm_put_dev - drm_universal_plane_init - drm_vblank_init - gpiod_direction_output - kstrtou8 - mipi_dsi_attach - mipi_dsi_dcs_read - mipi_dsi_dcs_write_buffer - mipi_dsi_detach - mipi_dsi_driver_register_full - mipi_dsi_driver_unregister - mipi_dsi_generic_read - mipi_dsi_generic_write - mipi_dsi_host_register - mipi_dsi_host_unregister - mipi_dsi_set_maximum_return_packet_size - no_llseek - of_clk_get_by_name - of_drm_find_bridge - of_drm_find_panel - of_fdt_unflatten_tree - of_find_backlight_by_node - of_find_node_opts_by_path - of_get_drm_display_mode - of_graph_get_endpoint_by_regs - of_graph_get_remote_port_parent - of_reserved_mem_device_release - __platform_register_drivers - platform_unregister_drivers - regmap_get_reg_stride - regmap_get_val_bytes - try_wait_for_completion - -# required by spi-sprd.ko - dma_request_chan - spi_controller_suspend - spi_finalize_current_transfer - -# required by spi-sprd-adi.ko - unregister_restart_handler - -# required by sprd-dma.ko - dma_async_device_register - dma_async_device_unregister - dma_async_tx_descriptor_init - of_dma_controller_free - of_dma_controller_register - of_dma_simple_xlate - -# required by sprd-gsp.ko - __kthread_init_worker - kthread_queue_work - kthread_worker_fn - -# required by sprd-hwdvfs-sharkl3.ko - __i2c_transfer - rt_mutex_trylock - -# required by sprd_dedicate_thm.ko - devm_thermal_zone_of_sensor_register - system_power_efficient_wq - -# required by sprd_dvfs.ko - devfreq_add_governor - devfreq_remove_governor - devfreq_update_status - device_rename - update_devfreq - -# required by sprd_hwspinlock.ko - hwspin_lock_register - hwspin_lock_unregister - -# required by sprd_ipa.ko - skb_to_sgvec - irq_set_affinity_hint - napi_gro_receive - -# required by sprd-saudio.ko - snd_card_free - -# required by sprd-sc27xx-spi.ko - devm_regmap_add_irq_chip - regmap_irq_get_domain - spi_bus_type - __spi_register_driver - spi_sync - -# required by sprd_apb_busmonitor.ko - _dev_emerg - -# required by sprd_cproc.ko - of_get_parent - -# required by sprd_cpu_cooling.ko - cpu_down - cpufreq_get_policy - cpu_up - cpufreq_quick_get - dev_pm_opp_find_freq_exact - thermal_cooling_device_unregister - thermal_of_cooling_device_register - -# required by sprd-mailbox.ko - devm_mbox_controller_register - -# required by sprd_mcd.ko - gpiod_set_value_cansleep - kernel_power_off - register_restart_handler - unregister_reboot_notifier - -# required by sprd_pcie_ep_device.ko - pci_enable_device - pci_request_regions - pci_restore_state - pci_save_state - pci_set_power_state - -# required by sprd_pm_domain.ko - kfree_const - kstrdup_const - of_genpd_add_subdomain - -# required by sprd_powerdebug.ko - cpu_pm_register_notifier - cpu_pm_unregister_notifier - pm_print_active_wakeup_sources - syscon_node_to_regmap - -# required by sprd_sdio_fm.ko - vfs_llseek - -# required by sprd_soc_thm.ko - thermal_zone_device_unregister - thermal_zone_device_update - thermal_zone_of_sensor_register - -# required by sprd_vdsp.ko - bsearch - devm_kstrdup - __memcpy_toio - of_match_device - of_n_addr_cells - of_n_size_cells - of_translate_address - sort - -# required by sprd_wdt.ko - devm_watchdog_register_device - watchdog_init_timeout - -# required by sprdbt_sipc_tty.ko - tty_schedule_flip - -# required by sprdwl_ng.ko - bcmp - build_skb - __cfg80211_alloc_event_skb - __cfg80211_alloc_reply_skb - cfg80211_chandef_create - cfg80211_ch_switch_notify - cfg80211_connect_done - cfg80211_cqm_rssi_notify - cfg80211_del_sta_sinfo - cfg80211_disconnected - cfg80211_find_elem_match - cfg80211_get_bss - cfg80211_ibss_joined - cfg80211_inform_bss_data - cfg80211_mgmt_tx_status - cfg80211_michael_mic_failure - cfg80211_new_sta - cfg80211_put_bss - cfg80211_ready_on_channel - cfg80211_remain_on_channel_expired - cfg80211_roamed - cfg80211_rx_mgmt - cfg80211_rx_unprot_mlme_mgmt - cfg80211_scan_done - cfg80211_sched_scan_results - __cfg80211_send_event_skb - cfg80211_tdls_oper_request - cfg80211_unlink_bss - cfg80211_unregister_wdev - cfg80211_vendor_cmd_reply - console_printk - consume_skb - _ctype - dev_get_by_index - down_timeout - freq_reg_info - genlmsg_put - jiffies_to_usecs - kfree_skb_list - netdev_alloc_frag - netdev_err - netdev_info - netdev_warn - netlink_unicast - nla_memcpy - __nla_parse - nla_put - nla_put_64bit - nla_put_nohdr - printk_timed_ratelimit - register_inet6addr_notifier - register_inetaddr_notifier - register_netdevice - regulatory_hint - rtnl_lock - rtnl_unlock - simple_open - skb_queue_purge - skb_unlink - synchronize_rcu - unregister_inet6addr_notifier - unregister_inetaddr_notifier - unregister_netdevice_queue - wiphy_free - wiphy_new_nm - wiphy_register - wiphy_unregister - -# required by sunwave_fp.ko - input_unregister_device - -# required by tcpm.ko - fwnode_property_read_u32_array - mod_delayed_work_on - usb_debug_root - -# required by trusty.ko - _copy_from_iter - _copy_to_iter - __cpuhp_remove_state - __cpuhp_setup_state - __cpuhp_state_add_instance - __cpuhp_state_remove_instance - device_for_each_child - disable_percpu_irq - enable_percpu_irq - free_percpu_irq - irq_create_of_mapping - panic_notifier_list - register_virtio_device - register_virtio_driver - __request_percpu_irq - unregister_virtio_device - unregister_virtio_driver - virtqueue_add_inbuf - virtqueue_add_outbuf - virtqueue_detach_unused_buf - virtqueue_get_buf - virtqueue_get_vring_size - virtqueue_kick - virtqueue_kick_prepare - virtqueue_notify - vring_del_virtqueue - vring_interrupt - vring_new_virtqueue - wait_woken - woken_wake_function - -# required by typec.ko - blocking_notifier_call_chain - __class_register - class_unregister - device_find_child - fwnode_property_read_u16_array - get_device - kobject_uevent - match_string - -# required by usb-storage.ko - blk_queue_bounce_limit - blk_queue_max_hw_sectors - blk_queue_update_dma_alignment - _dev_notice - param_ops_string - schedule_timeout_uninterruptible - scsi_add_host_with_dma - scsi_eh_prep_cmnd - scsi_eh_restore_cmnd - scsi_get_host_dev - scsi_host_alloc - scsi_host_put - scsi_is_host_device - scsi_normalize_sense - scsi_remove_host - scsi_report_bus_reset - scsi_report_device_reset - scsi_scan_host - scsi_sense_desc_find - sg_miter_skip - simple_strtoul - usb_autopm_put_interface_no_suspend - usb_lock_device_for_reset - usb_reset_device - usb_reset_endpoint - usb_sg_cancel - usb_sg_init - usb_sg_wait - usb_unlink_urb - -# required by usb_f_mtp.ko - usb_os_desc_prepare_interf_dir - usb_string_id - config_group_init_type_name - -# required by usbserial.ko - device_del - driver_attach - handle_sysrq - tty_hangup - tty_ldisc_deref - tty_ldisc_ref - tty_termios_copy_hw - usb_disabled - usb_get_dev - usb_match_id - usb_match_one_id - usb_poison_urb - usb_put_dev - usb_show_dynids - usb_store_new_id - usb_unpoison_urb - -# required by vha.ko - clk_bulk_get - device_wakeup_disable - devm_iounmap - __ndelay - param_ops_long - param_ops_ulong - pm_relax - pm_stay_awake - -# required by virtio_crypto.ko - cpu_bit_bitmap - cpus_read_lock - cpus_read_unlock - cpu_topology - crypto_ablkcipher_type - crypto_engine_alloc_init - crypto_engine_exit - crypto_engine_start - crypto_finalize_ablkcipher_request - crypto_register_alg - crypto_register_scomp - crypto_transfer_ablkcipher_request_to_engine - crypto_unregister_alg - crypto_unregister_scomp - scatterwalk_map_and_copy - sg_init_one - sg_nents_for_len - -# required by wcn_bsp.ko - gpiod_set_value - memdup_user - pci_disable_device - pci_disable_msi - pci_disable_msix - pcie_capability_read_dword - pcie_capability_read_word - pci_enable_msix_range - pci_enable_wake - pci_find_ext_capability - pci_load_and_free_saved_state - pci_msi_vec_count - pci_read_config_byte - pci_read_config_dword - pci_release_regions - pci_store_saved_state - pci_write_config_byte - pci_write_config_dword - register_chrdev_region - request_firmware_direct - -# required by rc-core.ko - input_scancode_to_scalar - kobject_get_path - led_trigger_register_simple - led_trigger_unregister_simple - __module_get - nsecs_to_jiffies - -# required by spi-bitbang.ko - spi_register_controller - spi_unregister_controller - -# required by sprd_memdisk.ko - __alloc_disk_node - blk_cleanup_queue - blk_mq_end_request - blk_mq_init_sq_queue - blk_mq_start_request - blk_queue_logical_block_size - del_gendisk - device_add_disk - put_disk - register_blkdev - unregister_blkdev - -# required by ppp_async.ko - crc_ccitt_table - n_tty_ioctl_helper - ppp_channel_index - ppp_input_error - ppp_output_wakeup - ppp_register_channel - ppp_unit_number - ppp_unregister_channel - _raw_write_lock_irq - _raw_write_unlock_irq - skb_pull - start_tty - stop_tty - tty_mode_ioctl - tty_register_ldisc - tty_unregister_ldisc - tty_unthrottle - -# required by cls_fw.ko - __dev_get_by_index - __dev_get_by_name - kfree_call_rcu - nla_strlcpy - __put_net - register_tcf_proto_ops - rtnl_is_locked - tcf_action_exec - tcf_exts_destroy - tcf_exts_dump - tcf_exts_dump_stats - tcf_exts_validate - tcf_queue_work - unregister_tcf_proto_ops - -# required by ipcomp.ko - ipcomp_destroy - ipcomp_init_state - ipcomp_input - ipcomp_output - xfrm_init_state - xfrm_state_alloc - xfrm_state_insert - -# required by xcbc.ko - crypto_alloc_instance - crypto_attr_alg2 - crypto_check_attr_type - crypto_init_spawn - crypto_mod_put - crypto_register_template - crypto_spawn_tfm - crypto_unregister_template - shash_free_instance - shash_register_instance - -# required by aes-ce-ccm.ko - ce_aes_expandkey - -# required by xt_TEE.ko - static_key_slow_dec - static_key_slow_inc - xt_tee_enabled - -# required by ir-kbd-i2c.ko - i2c_new_dummy_device - i2c_unregister_device - -# required by ledtrig-pattern.ko - led_get_default_pattern - led_set_brightness - led_trigger_register - led_trigger_unregister - -# required by virtio_crypto.ko - virtio_break_device - virtqueue_add_sgs - virtqueue_disable_cb - virtqueue_enable_cb - virtqueue_is_broken - -# required by dns_resolver.ko - generic_key_instantiate - key_invalidate - key_put - key_revoke - keyring_alloc - key_validate - kmemdup_nul - memchr - prepare_kernel_cred - register_key_type - request_key_tag - unregister_key_type - user_destroy - user_read - user_revoke - -# required by aes-neon-blk.ko - crypto_aes_inv_sbox - crypto_aes_sbox - crypto_alloc_shash - crypto_register_skciphers - crypto_shash_digest - crypto_unregister_skciphers - scatterwalk_ffwd - simd_skcipher_create_compat - simd_skcipher_free - -# required by ghash-ce.ko - gf128mul_lle - -# required by pppoe.ko - _copy_from_iter_full - datagram_poll - dev_add_pack - dev_get_by_name_rcu - dev_remove_pack - lock_sock_nested - pppox_compat_ioctl - pppox_ioctl - pppox_unbind_sock - ppp_register_net_channel - proto_register - proto_unregister - pskb_trim_rcsum_slow - register_pernet_device - register_pppox_proto - release_sock - sk_alloc - skb_copy_datagram_iter - skb_pull_rcsum - skb_recv_datagram - __sk_receive_skb - sock_init_data - sock_no_accept - sock_no_bind - sock_no_getsockopt - sock_no_listen - sock_no_mmap - sock_no_setsockopt - sock_no_shutdown - sock_no_socketpair - sock_queue_rcv_skb - sock_wmalloc - unregister_pernet_device - unregister_pppox_proto - -# required by sha1-ce.ko - crypto_sha1_finup - crypto_sha1_update - -# required by ah6.ko - ip6_redirect - ip6_update_pmtu - net_ratelimit - xfrm6_find_1stfragopt - xfrm6_protocol_deregister - xfrm6_protocol_register - xfrm6_rcv - -# required by raw_diag.ko - inet_diag_bc_sk - inet_diag_register - inet_diag_unregister - inet_sk_diag_fill - netlink_net_capable - raw_v4_hashinfo - __raw_v4_lookup - raw_v6_hashinfo - __raw_v6_lookup - sock_diag_destroy - -# required by xt_addrtype.ko - inet_dev_addr_type - __ipv6_addr_type - ipv6_chk_addr - -# required by sprd_thermal.ko - devm_thermal_zone_of_sensor_unregister - -# required by arc4.ko - arc4_crypt - arc4_setkey - crypto_register_skcipher - crypto_unregister_skcipher - -# required by ip6table_security.ko - xt_hook_ops_alloc - -# required by xfrm4_tunnel.ko - xfrm4_tunnel_deregister - xfrm4_tunnel_register - -# required by ppp_mppe.ko - crypto_has_ahash - crypto_shash_final - crypto_shash_update - -# required by pptp.ko - find_next_zero_bit - gre_add_protocol - gre_del_protocol - __ip_select_ident - security_sk_classify_flow - skb_set_owner_w - sk_setup_caps - sock_no_recvmsg - sock_no_sendmsg - -# required by gtco.ko - __usb_get_extra_descriptor - -# required by l2tp_ppp.ko - l2tp_session_create - l2tp_session_delete - l2tp_session_free - l2tp_session_get_nth - l2tp_session_register - l2tp_session_set_header_len - l2tp_tunnel_create - l2tp_tunnel_delete - l2tp_tunnel_free - l2tp_tunnel_get - l2tp_tunnel_get_nth - l2tp_tunnel_get_session - l2tp_tunnel_register - l2tp_udp_encap_recv - l2tp_xmit_skb - ppp_dev_name - -# required by ppp_generic.ko - arch_bpf_jit_check_func - bpf_prog_create - bpf_prog_destroy - bpf_stats_enabled_key - iov_iter_init - netdev_printk - netif_rx - ns_capable - rtnl_link_register - rtnl_link_unregister - skb_queue_head - skb_scrub_packet - slhc_compress - slhc_free - slhc_init - slhc_remember - slhc_toss - slhc_uncompress - unregister_netdevice_many - -# required by pppox.ko - sock_register - sock_unregister - -# required by ppp_deflate.ko - zlib_deflate - zlib_deflateEnd - zlib_deflateInit2 - zlib_deflateReset - zlib_deflate_workspacesize - zlib_inflate - zlib_inflateEnd - zlib_inflateIncomp - zlib_inflateInit2 - zlib_inflateReset - zlib_inflate_workspacesize - -# required by sprd_cpp.ko - clk_get_parent - of_iomap - -# required by sprd_camera.ko - ion_alloc - ion_free - ktime_get_ts64 - ns_to_timeval - of_irq_to_resource - _raw_spin_trylock - regulator_get_linear_step - -# required by trusty-pm.ko - ktime_get_boot_fast_ns - unregister_syscore_ops - -# required by ufs-sprd.ko - ufshcd_dme_set_attr - ufshcd_get_local_unipro_ver - ufshcd_pltfrm_init - ufshcd_pltfrm_resume - ufshcd_pltfrm_runtime_idle - ufshcd_pltfrm_runtime_resume - ufshcd_pltfrm_runtime_suspend - ufshcd_pltfrm_shutdown - ufshcd_pltfrm_suspend - ufshcd_remove - -# required by sprd_sip_svc.ko - __arm_smccc_smc - -# required by mali_gondul.ko - __arch_clear_user - bpf_trace_run5 - ktime_get_raw - of_machine_is_compatible - _totalram_pages - trace_output_call - __tracepoint_gpu_mem_total - trace_print_array_seq - vmf_insert_pfn_prot - -# required by sprd_ion.ko - ion_buffer_zero - __ion_device_add_heap - memset32 - of_platform_device_create - __sg_page_iter_next - __sg_page_iter_start - -# required by snd-soc-sprd-codec-sc2730.ko - dapm_kcontrol_get_value - __kfifo_init - __kfifo_from_user_r - __kfifo_to_user_r - snd_pcm_rate_bit_to_rate - snd_soc_bytes_info_ext - snd_soc_new_compress - snd_card_new - snd_card_register - snd_ctl_add - snd_ctl_new1 - snd_pcm_new - snd_pcm_set_ops - -# required by ssd20xx_ts.ko - input_mt_report_pointer_emulation - -# cpufreq_interactive.ko - add_timer_on - cpufreq_register_notifier - cpufreq_table_index_unsorted - cpufreq_unregister_notifier - down_read_trylock - get_cpu_idle_time - irq_work_queue - kobject_init_and_add - sched_setscheduler_nocheck - strpbrk - -# required by sprd_wdf.ko - kstrtoull_from_user - smpboot_register_percpu_thread - -# required by zram.ko - bdgrab - bio_chain - bio_init - blkdev_put - blk_status_to_errno - blkdev_get - filp_close - filp_open_block - file_path - I_BDEV - set_blocksize - submit_bio_wait diff --git a/android/abi_gki_aarch64_virtual_device b/android/abi_gki_aarch64_virtual_device index db3c296e0791..724632832596 100644 --- a/android/abi_gki_aarch64_virtual_device +++ b/android/abi_gki_aarch64_virtual_device @@ -34,8 +34,6 @@ cancel_delayed_work_sync cancel_work_sync capable - cfg80211_inform_bss_data - cfg80211_put_bss __cfi_slowpath __check_object_size __class_create @@ -565,10 +563,6 @@ # required by mac80211_hwsim.ko alloc_netdev_mqs - __cfg80211_alloc_event_skb - __cfg80211_alloc_reply_skb - __cfg80211_send_event_skb - cfg80211_vendor_cmd_reply debugfs_attr_read debugfs_attr_write dev_alloc_name @@ -583,28 +577,6 @@ hrtimer_forward hrtimer_init hrtimer_start_range_ns - ieee80211_alloc_hw_nm - ieee80211_beacon_cntdwn_is_complete - ieee80211_beacon_get_tim - ieee80211_csa_finish - ieee80211_free_hw - ieee80211_free_txskb - ieee80211_get_buffered_bc - ieee80211_get_tx_rates - ieee80211_iterate_active_interfaces_atomic - ieee80211_probereq_get - ieee80211_queue_delayed_work - ieee80211_radar_detected - ieee80211_ready_on_channel - ieee80211_register_hw - ieee80211_remain_on_channel_expired - ieee80211_rx_irqsafe - ieee80211_scan_completed - ieee80211_stop_queues - ieee80211_stop_tx_ba_cb_irqsafe - ieee80211_tx_status_irqsafe - ieee80211_unregister_hw - ieee80211_wake_queues init_net __netdev_alloc_skb netif_rx @@ -619,7 +591,6 @@ nla_put param_ops_ushort register_pernet_device - regulatory_hint rhashtable_destroy rhashtable_init rhashtable_insert_slow @@ -635,7 +606,6 @@ skb_trim skb_unlink unregister_pernet_device - wiphy_apply_custom_regulatory # required by md-mod.ko ack_all_badblocks @@ -940,9 +910,6 @@ devm_mfd_add_devices # required by virt_wifi.ko - cfg80211_connect_done - cfg80211_disconnected - cfg80211_scan_done __dev_get_by_index dev_printk __module_get @@ -952,13 +919,8 @@ rtnl_link_unregister skb_clone unregister_netdevice_many - wiphy_free - wiphy_new_nm - wiphy_register - wiphy_unregister # required by virt_wifi_sim.ko - ieee80211_get_channel_khz release_firmware request_firmware @@ -1233,6 +1195,8 @@ # required by virtio_pci.ko irq_set_affinity_hint pci_alloc_irq_vectors_affinity + pci_disable_sriov + pci_enable_sriov pci_find_capability pci_find_ext_capability pci_find_next_capability @@ -1242,6 +1206,7 @@ pci_irq_vector pci_release_selected_regions pci_request_selected_regions + pci_vfs_assigned synchronize_irq virtio_device_freeze virtio_device_restore @@ -1322,3 +1287,28 @@ _raw_read_unlock _raw_write_lock _raw_write_unlock + +# required by gs_usb.ko + usb_kill_anchored_urbs + alloc_candev_mqs + register_candev + free_candev + can_change_mtu + open_candev + usb_anchor_urb + usb_unanchor_urb + alloc_can_skb + can_get_echo_skb + alloc_can_err_skb + close_candev + can_put_echo_skb + can_free_echo_skb + unregister_candev + +# required by vcan.ko + sock_efree + +# required by slcan.ko + tty_mode_ioctl + tty_hangup + hex_asc_upper diff --git a/android/abi_gki_aarch64_vivo b/android/abi_gki_aarch64_vivo new file mode 100644 index 000000000000..5f3433d6f311 --- /dev/null +++ b/android/abi_gki_aarch64_vivo @@ -0,0 +1,2019 @@ +[abi_symbol_list] + activate_task + add_cpu + add_device_randomness + add_memory + add_memory_subsection + add_timer + add_uevent_var + add_wait_queue + alarm_cancel + alarm_init + alarm_start + alloc_anon_inode + alloc_chrdev_region + __alloc_disk_node + alloc_io_pgtable_ops + __alloc_pages_nodemask + __alloc_percpu + __alloc_skb + alloc_skb_with_frags + alloc_workqueue + amba_bustype + amba_driver_register + amba_driver_unregister + android_debug_per_cpu_symbol + android_debug_symbol + android_rvh_probe_register + anon_inode_getfile + __arch_copy_from_user + __arch_copy_in_user + __arch_copy_to_user + arch_timer_read_counter + argv_free + argv_split + arm64_const_caps_ready + arm64_use_ng_mappings + __arm_smccc_smc + atomic_notifier_call_chain + atomic_notifier_chain_register + atomic_notifier_chain_unregister + available_idle_cpu + bdget_disk + bdput + bio_add_pc_page + bio_endio + bio_reset + bitmap_allocate_region + __bitmap_clear + bitmap_find_next_zero_area_off + __bitmap_or + bitmap_parselist_user + bitmap_print_to_pagebuf + bitmap_release_region + __bitmap_set + blk_alloc_queue + blk_bio_list_merge + blk_cleanup_queue + blk_execute_rq + blk_execute_rq_nowait + blk_get_request + blk_mq_debugfs_rq_show + blk_mq_rq_cpu + blk_mq_run_hw_queue + blk_mq_sched_mark_restart_hctx + blk_mq_sched_request_inserted + blk_put_request + blk_queue_flag_clear + blk_queue_flag_set + blk_queue_io_min + blk_queue_io_opt + blk_queue_logical_block_size + blk_queue_max_discard_sectors + blk_queue_max_write_zeroes_sectors + blk_queue_physical_block_size + blk_rq_append_bio + blk_rq_map_kern + blk_rq_map_user + blk_rq_map_user_iov + blk_rq_unmap_user + blk_stat_enable_accounting + blk_verify_command + blocking_notifier_call_chain + blocking_notifier_chain_register + blocking_notifier_chain_unregister + bpf_trace_run1 + bpf_trace_run10 + bpf_trace_run12 + bpf_trace_run2 + bpf_trace_run3 + bpf_trace_run4 + bpf_trace_run5 + bpf_trace_run6 + bpf_trace_run7 + bpf_trace_run8 + bpf_trace_run9 + bus_find_device + bus_for_each_dev + bus_register + bus_set_iommu + bus_unregister + cancel_delayed_work + cancel_delayed_work_sync + cancel_work_sync + capable + cdev_add + cdev_alloc + cdev_del + cdev_device_add + cdev_device_del + cdev_init + __cfi_slowpath + cgroup_path_ns + cgroup_taskset_first + cgroup_taskset_next + __check_object_size + check_preempt_curr + check_zeroed_user + __class_create + class_destroy + class_find_device + class_for_each_device + class_interface_unregister + __class_register + class_unregister + cleanup_srcu_struct + clear_page + __ClearPageMovable + clk_bulk_disable + clk_bulk_enable + clk_bulk_prepare + clk_bulk_put_all + clk_bulk_unprepare + __clk_determine_rate + clk_disable + clk_enable + clk_fixed_factor_ops + clk_fixed_rate_ops + clk_get + __clk_get_hw + __clk_get_name + clk_get_parent + clk_get_rate + clk_hw_get_flags + clk_hw_get_name + clk_hw_get_num_parents + clk_hw_get_parent + clk_hw_get_parent_by_index + clk_hw_get_rate + clk_hw_is_enabled + clk_hw_is_prepared + clk_hw_register + clk_hw_round_rate + clk_hw_unregister + __clk_is_enabled + __clk_mux_determine_rate_closest + clk_notifier_register + clk_notifier_unregister + clk_prepare + clk_put + clk_round_rate + clk_set_parent + clk_set_rate + clk_sync_state + clk_unprepare + cma_alloc + cma_get_name + cma_release + compat_alloc_user_space + compat_ptr_ioctl + complete + complete_all + completion_done + component_add + component_bind_all + component_del + component_master_add_with_match + component_master_del + component_match_add_release + component_unbind_all + config_ep_by_speed + configfs_register_subsystem + configfs_unregister_subsystem + config_group_init + config_group_init_type_name + config_item_get + config_item_put + console_stop + console_suspend_enabled + __const_udelay + consume_skb + contig_page_data + _copy_from_iter_full + __cpu_active_mask + cpu_bit_bitmap + cpufreq_cpu_get + cpufreq_cpu_get_raw + cpufreq_cpu_put + cpufreq_disable_fast_switch + cpufreq_driver_fast_switch + cpufreq_driver_resolve_freq + __cpufreq_driver_target + cpufreq_enable_fast_switch + cpufreq_freq_attr_scaling_available_freqs + cpufreq_freq_attr_scaling_boost_freqs + cpufreq_generic_frequency_table_verify + cpufreq_get_policy + cpufreq_register_driver + cpufreq_register_governor + cpufreq_register_notifier + cpufreq_unregister_driver + cpufreq_unregister_notifier + __cpuhp_remove_state + __cpuhp_setup_state + __cpuhp_setup_state_cpuslocked + __cpuhp_state_add_instance + __cpuhp_state_remove_instance + cpu_hwcap_keys + cpu_hwcaps + cpuidle_governor_latency_req + cpuidle_register_governor + cpu_irqtime + cpu_latency_qos_add_request + cpu_latency_qos_remove_request + cpu_latency_qos_request_active + cpu_latency_qos_update_request + cpumask_next + cpumask_next_and + cpu_number + __cpu_online_mask + cpu_pm_register_notifier + cpu_pm_unregister_notifier + __cpu_possible_mask + __cpu_present_mask + cpupri_find_fitness + cpu_scale + cpus_read_lock + cpus_read_unlock + cpu_subsys + cpu_topology + crc8 + crc8_populate_msb + crypto_alloc_base + crypto_comp_compress + crypto_comp_decompress + crypto_destroy_tfm + crypto_has_alg + crypto_register_alg + crypto_register_rngs + crypto_register_scomp + crypto_unregister_alg + crypto_unregister_rngs + crypto_unregister_scomp + css_next_child + _ctype + datagram_poll + deactivate_task + debugfs_attr_read + debugfs_attr_write + debugfs_create_bool + debugfs_create_dir + debugfs_create_file + debugfs_create_file_unsafe + debugfs_create_u32 + debugfs_create_u8 + debugfs_create_x32 + debugfs_create_x8 + debugfs_file_get + debugfs_file_put + debugfs_lookup + debugfs_remove + dec_zone_page_state + default_llseek + deferred_free + delayed_work_timer_fn + del_gendisk + del_timer + del_timer_sync + desc_to_gpio + destroy_workqueue + dev_coredumpv + _dev_crit + dev_driver_string + _dev_err + devfreq_add_device + devfreq_add_governor + devfreq_cooling_unregister + devfreq_remove_device + devfreq_remove_governor + devfreq_resume_device + devfreq_suspend_device + dev_fwnode + dev_get_by_name + dev_get_regmap + device_add + device_add_disk + device_add_groups + device_create + device_create_file + device_del + device_destroy + device_find_child + device_for_each_child + device_get_match_data + device_initialize + device_init_wakeup + device_link_add + device_match_fwnode + device_match_name + device_property_present + device_property_read_string + device_property_read_u16_array + device_property_read_u32_array + device_register + device_remove_file + device_show_int + device_store_int + device_unregister + device_wakeup_disable + device_wakeup_enable + _dev_info + devm_add_action + devm_blk_ksm_init + devm_clk_bulk_get_all + devm_clk_get + devm_clk_hw_register + devm_clk_put + devm_clk_register + devm_device_add_group + devm_device_remove_group + devm_extcon_dev_allocate + devm_extcon_dev_register + devm_extcon_dev_unregister + devm_free_irq + devm_gpiod_get_optional + devm_gpio_request + devm_gpio_request_one + devm_hwspin_lock_register + devm_iio_channel_get + devm_iio_device_alloc + __devm_iio_device_register + devm_input_allocate_device + devm_ioremap + devm_ioremap_resource + devm_ioremap_wc + devm_iounmap + devm_kasprintf + devm_kfree + devm_kmalloc + devm_kmemdup + devm_kstrdup + devm_led_classdev_register_ext + devm_nvmem_cell_get + devm_nvmem_device_get + devm_nvmem_register + devm_of_clk_add_hw_provider + devm_of_icc_get + __devm_of_phy_provider_register + devm_of_platform_populate + devm_of_pwm_get + devm_pci_alloc_host_bridge + devm_phy_create + devm_phy_get + devm_pinctrl_get + devm_pinctrl_put + devm_pinctrl_register + devm_platform_ioremap_resource + devm_platform_ioremap_resource_byname + devm_power_supply_register + devm_regmap_field_alloc + __devm_regmap_init + __devm_regmap_init_i2c + __devm_regmap_init_mmio_clk + devm_regulator_bulk_get + devm_regulator_get + devm_regulator_get_optional + devm_regulator_put + devm_regulator_register + devm_regulator_register_notifier + devm_request_any_context_irq + devm_request_threaded_irq + __devm_reset_control_get + devm_reset_controller_register + devm_rtc_allocate_device + devm_thermal_of_cooling_device_register + devm_thermal_zone_of_sensor_register + devm_usb_get_phy_by_node + _dev_notice + dev_pm_domain_attach + dev_pm_domain_attach_by_name + dev_pm_domain_detach + dev_pm_genpd_add_notifier + dev_pm_genpd_remove_notifier + dev_pm_genpd_set_next_wakeup + dev_pm_genpd_set_performance_state + dev_pm_opp_add + dev_pm_opp_find_freq_ceil + dev_pm_opp_find_freq_exact + dev_pm_opp_find_freq_floor + dev_pm_opp_get_opp_count + dev_pm_opp_get_voltage + dev_pm_opp_of_add_table + dev_pm_opp_of_find_icc_paths + dev_pm_opp_of_register_em + dev_pm_opp_of_remove_table + dev_pm_opp_put + dev_pm_opp_put_clkname + dev_pm_opp_remove_all_dynamic + dev_pm_opp_set_clkname + dev_pm_opp_set_rate + dev_pm_opp_set_sharing_cpus + dev_pm_qos_add_notifier + dev_pm_qos_add_request + dev_pm_qos_read_value + dev_pm_qos_remove_notifier + dev_pm_qos_remove_request + dev_pm_qos_update_request + dev_printk + devres_add + devres_alloc_node + devres_free + devres_release + dev_set_name + _dev_warn + disable_irq + disable_irq_nosync + disable_percpu_irq + disk_end_io_acct + disk_start_io_acct + divider_get_val + divider_recalc_rate + divider_ro_round_rate_parent + divider_round_rate_parent + dma_alloc_attrs + dma_async_device_register + dma_async_device_unregister + dma_async_tx_descriptor_init + dma_buf_attach + dma_buf_begin_cpu_access + dma_buf_begin_cpu_access_partial + dma_buf_detach + dma_buf_end_cpu_access + dma_buf_end_cpu_access_partial + dma_buf_export + dma_buf_fd + dma_buf_get + dma_buf_map_attachment + dma_buf_put + dma_buf_unmap_attachment + dma_buf_vmap + dma_buf_vunmap + dma_fence_add_callback + dma_fence_array_create + dma_fence_array_ops + dma_fence_context_alloc + dma_fence_default_wait + dma_fence_enable_sw_signaling + dma_fence_free + dma_fence_get_status + dma_fence_init + dma_fence_release + dma_fence_remove_callback + dma_fence_signal + dma_fence_signal_locked + dma_fence_wait_timeout + dma_free_attrs + dma_get_sgtable_attrs + dma_get_slave_channel + dma_heap_add + dma_heap_buffer_alloc + dma_heap_find + dma_heap_get_dev + dma_heap_get_drvdata + dma_heap_get_name + dmam_alloc_attrs + dma_map_page_attrs + dma_map_resource + dma_map_sg_attrs + dmam_free_coherent + dma_release_channel + dma_request_chan + dma_set_coherent_mask + dma_set_mask + dma_sync_sg_for_cpu + dma_sync_sg_for_device + dma_sync_single_for_cpu + dma_sync_single_for_device + dma_unmap_page_attrs + dma_unmap_resource + dma_unmap_sg_attrs + do_exit + down_read + down_write + d_path + dput + drain_workqueue + driver_find_device + driver_register + driver_unregister + edac_device_add_device + edac_device_alloc_ctl_info + edac_device_alloc_index + edac_device_del_device + edac_device_free_ctl_info + edac_device_handle_ce_count + edac_device_handle_ue_count + elevator_alloc + elv_register + elv_unregister + enable_irq + enable_percpu_irq + eventfd_ctx_fdget + eventfd_ctx_fileget + eventfd_ctx_put + eventfd_ctx_remove_wait_queue + eventfd_signal + event_triggers_call + extcon_get_edev_by_phandle + extcon_get_edev_name + extcon_get_property + extcon_get_state + extcon_register_notifier + extcon_set_state_sync + failure_tracking + fasync_helper + __fdget + fd_install + fget + filp_close + filp_open_block + find_last_bit + find_next_bit + find_next_zero_bit + find_snd_usb_substream + find_task_by_vpid + find_vma + find_vpid + finish_wait + firmware_request_nowarn + flush_dcache_page + flush_delayed_work + flush_work + flush_workqueue + fput + free_io_pgtable_ops + free_irq + __free_pages + free_pages + free_percpu + free_percpu_irq + freq_qos_add_request + freq_qos_remove_request + freq_qos_update_request + freq_scale + fsync_bdev + fwnode_find_reference + fwnode_get_next_child_node + fwnode_handle_get + fwnode_handle_put + fwnode_property_present + fwnode_property_read_string + fwnode_property_read_u32_array + generic_device_group + generic_handle_irq + generic_iommu_put_resv_regions + genlmsg_put + genl_register_family + genl_unregister_family + gen_pool_add_owner + gen_pool_alloc_algo_owner + gen_pool_avail + gen_pool_best_fit + gen_pool_create + gen_pool_destroy + gen_pool_first_fit_order_align + gen_pool_free_owner + gen_pool_has_addr + gen_pool_set_algo + gen_pool_size + gen_pool_virt_to_phys + getboottime64 + get_cpu_device + get_device + __get_free_pages + get_governor_parent_kobj + get_option + get_pid_task + get_random_bytes + get_random_u32 + get_sg_io_hdr + __get_task_comm + get_task_mm + get_task_pid + get_unmapped_area + get_unused_fd_flags + get_user_pages + gfp_zone + gic_nonsecure_priorities + gov_attr_set_init + gov_attr_set_put + governor_sysfs_ops + gpiochip_add_data_with_key + gpiochip_add_pin_range + gpiochip_generic_free + gpiochip_generic_request + gpiochip_get_data + gpiochip_line_is_valid + gpiochip_lock_as_irq + gpiochip_remove + gpiochip_unlock_as_irq + gpiod_direction_input + gpiod_direction_output + gpiod_direction_output_raw + gpiod_get_optional + gpiod_get_raw_value + gpiod_get_raw_value_cansleep + gpiod_get_value + gpiod_set_raw_value + gpiod_set_value + gpiod_set_value_cansleep + gpiod_to_irq + gpio_free + gpio_request + gpio_request_one + gpio_to_desc + handle_bad_irq + handle_edge_irq + handle_fasteoi_ack_irq + handle_fasteoi_irq + handle_level_irq + handle_nested_irq + handle_simple_irq + handle_sysrq + hashlen_string + hex_dump_to_buffer + hrtimer_active + hrtimer_cancel + hrtimer_forward + __hrtimer_get_remaining + hrtimer_init + hrtimer_start_range_ns + hrtimer_try_to_cancel + hvc_alloc + hvc_kick + hvc_poll + hvc_remove + hwrng_register + hwrng_unregister + hwspin_lock_free + hwspin_lock_request_specific + __hwspin_lock_timeout + __hwspin_unlock + hypervisor_kobj + i2c_add_adapter + i2c_del_adapter + i2c_del_driver + i2c_get_dma_safe_msg_buf + i2c_put_dma_safe_msg_buf + i2c_register_driver + i2c_smbus_read_byte_data + i2c_smbus_write_byte_data + i2c_transfer + i2c_transfer_buffer_flags + icc_get + icc_link_create + icc_node_add + icc_node_create + icc_node_del + icc_node_destroy + icc_provider_add + icc_provider_del + icc_put + icc_set_bw + icc_set_tag + ida_alloc_range + ida_free + idr_alloc + idr_alloc_cyclic + idr_destroy + idr_find + idr_for_each + idr_get_next + idr_preload + idr_remove + idr_replace + iio_channel_get + iio_channel_get_all + iio_channel_release + iio_read_channel_processed + import_iovec + inc_zone_page_state + in_egroup_p + init_iova_domain + init_net + init_pseudo + __init_rwsem + init_srcu_struct + __init_swait_queue_head + init_task + init_timer_key + init_uts_ns + init_wait_entry + __init_waitqueue_head + input_alloc_absinfo + input_allocate_device + input_close_device + input_event + input_free_device + input_mt_init_slots + input_mt_report_pointer_emulation + input_mt_report_slot_state + input_open_device + input_register_device + input_register_handle + input_register_handler + input_set_abs_params + input_set_capability + input_unregister_device + input_unregister_handle + input_unregister_handler + interval_tree_insert + interval_tree_iter_first + interval_tree_iter_next + interval_tree_remove + int_sqrt + iommu_alloc_resv_region + iommu_attach_device + iommu_detach_device + iommu_device_register + iommu_device_sysfs_add + iommu_device_sysfs_remove + iommu_device_unregister + iommu_dma_get_resv_regions + iommu_domain_alloc + iommu_domain_free + iommu_domain_get_attr + iommu_domain_set_attr + iommu_fwspec_add_ids + iommu_fwspec_free + iommu_get_dma_cookie + iommu_get_domain_for_dev + iommu_get_msi_cookie + iommu_group_for_each_dev + iommu_group_get + iommu_group_get_iommudata + iommu_group_put + iommu_group_ref_get + iommu_group_set_iommudata + iommu_iova_to_phys + iommu_map + iommu_map_sg + iommu_present + iommu_put_dma_cookie + iommu_set_fault_handler + iommu_unmap + __ioread32_copy + __ioremap + iounmap + __iowrite32_copy + ipi_desc_get + iput + irq_chip_ack_parent + irq_chip_disable_parent + irq_chip_enable_parent + irq_chip_eoi_parent + irq_chip_get_parent_state + irq_chip_mask_parent + irq_chip_retrigger_hierarchy + irq_chip_set_affinity_parent + irq_chip_set_parent_state + irq_chip_set_type_parent + irq_chip_set_vcpu_affinity_parent + irq_chip_set_wake_parent + irq_chip_unmask_parent + irq_create_fwspec_mapping + irq_dispose_mapping + __irq_domain_add + irq_domain_alloc_irqs_parent + irq_domain_create_hierarchy + irq_domain_free_irqs_common + irq_domain_free_irqs_parent + irq_domain_get_irq_data + irq_domain_remove + irq_domain_set_hwirq_and_chip + irq_domain_set_info + irq_domain_update_bus_token + irq_domain_xlate_twocell + irq_find_mapping + irq_find_matching_fwspec + irq_get_irqchip_state + irq_get_irq_data + irq_modify_status + irq_of_parse_and_map + irq_set_affinity_hint + irq_set_affinity_notifier + irq_set_chained_handler_and_data + irq_set_chip_and_handler_name + irq_set_chip_data + irq_set_irqchip_state + irq_set_irq_type + irq_set_irq_wake + irq_set_parent + irq_to_desc + irq_work_queue + irq_work_queue_on + irq_work_sync + is_dma_buf_file + is_vmalloc_addr + jiffies + jiffies_to_msecs + jiffies_to_usecs + kasan_flag_enabled + kasprintf + kernel_bind + kernel_connect + kernel_getsockname + kernel_kobj + kernel_recvmsg + kernel_restart + kernel_sendmsg + kern_mount + kern_unmount + __kfifo_alloc + __kfifo_in + __kfifo_out + kfree + kfree_const + kfree_sensitive + kfree_skb + kill_anon_super + kill_fasync + kimage_vaddr + kimage_voffset + __kmalloc + kmalloc_caches + kmalloc_order_trace + kmem_cache_alloc + kmem_cache_alloc_trace + kmem_cache_create + kmem_cache_create_usercopy + kmem_cache_destroy + kmem_cache_free + kmemdup + kmemdup_nul + kobject_add + kobject_create_and_add + kobject_del + kobject_init + kobject_init_and_add + kobject_put + kobject_set_name + kobject_uevent + kobj_sysfs_ops + krealloc + kset_create_and_add + ksize + ksoftirqd + kstat + kstat_irqs_cpu + kstat_irqs_usr + kstrdup + kstrdup_const + kstrndup + kstrtobool + kstrtoint + kstrtoll + kstrtou16 + kstrtou16_from_user + kstrtou8 + kstrtou8_from_user + kstrtouint + kstrtouint_from_user + kstrtoul_from_user + kstrtoull + kstrtoull_from_user + kthread_bind_mask + kthread_cancel_work_sync + kthread_create_on_node + kthread_create_worker + kthread_destroy_worker + kthread_flush_worker + __kthread_init_worker + kthread_queue_work + kthread_should_stop + kthread_stop + kthread_worker_fn + ktime_get + ktime_get_mono_fast_ns + ktime_get_real_seconds + ktime_get_real_ts64 + ktime_get_with_offset + kvfree + kvmalloc_node + led_classdev_flash_register_ext + led_classdev_flash_unregister + led_classdev_unregister + __list_add_valid + __list_del_entry_valid + list_sort + llist_add_batch + llist_reverse_order + __lock_page + lock_sock_nested + log_buf_addr_get + log_buf_len_get + __log_post_read_mmio + __log_read_mmio + __log_write_mmio + lzo1x_1_compress + lzo1x_decompress_safe + lzorle1x_1_compress + match_string + mbox_chan_received_data + mbox_chan_txdone + mbox_client_txdone + mbox_controller_register + mbox_controller_unregister + mbox_free_channel + mbox_request_channel + mbox_send_message + memblock_end_of_DRAM + __memcat_p + memcpy + __memcpy_fromio + __memcpy_toio + memdup_user + memmove + memory_block_size_bytes + memory_read_from_buffer + memparse + mempool_alloc + mempool_alloc_slab + mempool_create + mempool_destroy + mempool_free + mempool_free_slab + memremap + memset + memset64 + __memset_io + memstart_addr + memunmap + migrate_swap + misc_deregister + misc_register + mmc_cqe_request_done + mmc_of_parse + mmc_regulator_get_supply + mmc_regulator_set_ocr + mmc_regulator_set_vqmmc + mmc_send_tuning + mmput + mod_delayed_work_on + mod_node_page_state + mod_timer + __module_get + module_layout + module_put + __msecs_to_jiffies + msleep + msleep_interruptible + __mutex_init + mutex_is_locked + mutex_lock + mutex_lock_interruptible + mutex_trylock + mutex_unlock + netlink_broadcast + __netlink_kernel_create + netlink_kernel_release + netlink_unicast + __next_zones_zonelist + nla_find + nla_put + nla_reserve + nla_reserve_64bit + __nla_validate + __nlmsg_put + no_llseek + nonseekable_open + noop_llseek + nr_cpu_ids + nr_ipi_get + nr_irqs + ns_to_timespec64 + __num_online_cpus + nvmem_cell_get + nvmem_cell_put + nvmem_cell_read + nvmem_cell_read_u32 + nvmem_cell_write + nvmem_device_read + nvmem_device_write + of_address_to_resource + of_alias_get_id + of_clk_add_hw_provider + of_clk_add_provider + of_clk_del_provider + of_clk_hw_simple_get + of_clk_src_simple_get + of_count_phandle_with_args + of_cpufreq_cooling_register + of_cpu_node_to_id + of_devfreq_cooling_register + of_device_get_match_data + of_device_is_available + of_device_is_compatible + of_dma_configure_id + of_dma_controller_free + of_dma_controller_register + of_dma_is_coherent + of_drm_find_panel + of_find_compatible_node + of_find_device_by_node + of_find_i2c_device_by_node + of_find_matching_node_and_match + of_find_node_by_name + of_find_node_by_phandle + of_find_node_opts_by_path + of_find_node_with_property + of_find_property + of_fwnode_ops + of_genpd_add_provider_onecell + of_genpd_del_provider + of_get_address + of_get_child_by_name + of_get_cpu_node + of_get_named_gpio_flags + of_get_next_available_child + of_get_next_child + of_get_next_parent + of_get_property + of_get_regulator_init_data + of_graph_get_next_endpoint + of_graph_get_port_parent + of_graph_get_remote_endpoint + of_graph_is_present + of_graph_parse_endpoint + of_hwspin_lock_get_id + of_icc_get + of_icc_xlate_onecell + of_iomap + of_irq_find_parent + of_irq_get + of_irq_get_byname + of_irq_parse_one + of_match_device + of_match_node + of_n_addr_cells + of_node_name_eq + of_n_size_cells + of_parse_phandle + of_parse_phandle_with_args + of_parse_phandle_with_fixed_args + of_phandle_iterator_init + of_phandle_iterator_next + of_phy_simple_xlate + of_platform_depopulate + of_platform_device_create + of_platform_device_destroy + of_platform_populate + of_property_count_elems_of_size + of_property_match_string + of_property_read_string + of_property_read_string_helper + of_property_read_u32_index + of_property_read_u64_index + of_property_read_variable_u16_array + of_property_read_variable_u32_array + of_property_read_variable_u8_array + of_prop_next_string + of_prop_next_u32 + of_reserved_mem_device_init_by_idx + of_reserved_mem_device_release + of_reserved_mem_lookup + of_root + of_thermal_get_ntrips + of_thermal_get_trip_points + of_thermal_is_trip_valid + of_translate_address + on_each_cpu + oops_in_progress + overflowuid + page_endio + page_mapping + __page_pinner_migration_failed + panic + panic_notifier_list + panic_timeout + param_get_int + param_ops_bool + param_ops_int + param_ops_uint + param_set_bool + pause_cpus + pci_alloc_irq_vectors_affinity + pci_assign_resource + pci_bus_type + pci_clear_master + pci_device_group + pci_dev_present + pci_disable_device + pcie_capability_read_word + pci_enable_device + pci_find_ext_capability + pci_free_irq_vectors + pci_get_device + pci_host_probe + pci_iomap + pci_irq_vector + pci_load_and_free_saved_state + pci_load_saved_state + pci_msi_create_irq_domain + pci_msi_mask_irq + pci_msi_unmask_irq + pci_read_config_dword + pci_read_config_word + __pci_register_driver + pci_release_region + pci_request_region + pci_restore_state + pci_save_state + pci_set_master + pci_set_power_state + pci_store_saved_state + pci_unregister_driver + pci_walk_bus + pci_write_config_dword + __per_cpu_offset + per_cpu_ptr_to_phys + perf_aux_output_begin + perf_aux_output_end + perf_aux_output_flag + perf_event_create_kernel_counter + perf_event_disable + perf_event_enable + perf_event_read_local + perf_event_read_value + perf_event_release_kernel + perf_get_aux + perf_pmu_register + perf_pmu_unregister + perf_trace_buf_alloc + perf_trace_run_bpf_submit + pfn_valid + phy_calibrate + phy_exit + phy_init + phy_power_off + phy_power_on + phy_set_mode_ext + pick_highest_pushable_task + pid_nr_ns + pid_task + pinconf_generic_dt_node_to_map + pinctrl_dev_get_drvdata + pinctrl_force_default + pinctrl_force_sleep + pinctrl_lookup_state + pinctrl_pm_select_default_state + pinctrl_pm_select_sleep_state + pinctrl_select_state + pinctrl_utils_free_map + platform_bus_type + platform_device_add + platform_device_alloc + platform_device_del + platform_device_put + platform_device_register_full + platform_device_unregister + __platform_driver_register + platform_driver_unregister + platform_get_irq + platform_get_irq_byname + platform_get_resource + platform_get_resource_byname + platform_irq_count + pm_clk_add + pm_clk_create + pm_clk_destroy + pm_clk_resume + pm_clk_suspend + pm_genpd_add_subdomain + pm_genpd_init + pm_genpd_remove + pm_genpd_remove_subdomain + pm_power_off + __pm_relax + pm_relax + pm_runtime_allow + pm_runtime_barrier + __pm_runtime_disable + pm_runtime_enable + pm_runtime_forbid + pm_runtime_force_resume + pm_runtime_force_suspend + __pm_runtime_idle + pm_runtime_irq_safe + pm_runtime_no_callbacks + __pm_runtime_resume + pm_runtime_set_autosuspend_delay + __pm_runtime_set_status + __pm_runtime_suspend + __pm_runtime_use_autosuspend + __pm_stay_awake + pm_stay_awake + pm_wakeup_dev_event + pm_wakeup_ws_event + power_supply_changed + power_supply_get_by_name + power_supply_get_drvdata + power_supply_get_property + power_supply_put + power_supply_register + power_supply_reg_notifier + power_supply_set_property + power_supply_unregister + power_supply_unreg_notifier + prandom_u32 + preempt_schedule + preempt_schedule_notrace + prepare_to_wait_event + print_hex_dump + printk + printk_deferred + proc_dointvec + proc_dointvec_minmax + proc_dostring + proc_douintvec_minmax + proto_register + proto_unregister + __pskb_pull_tail + put_device + put_disk + put_iova_domain + __put_page + put_pid + put_sg_io_hdr + __put_task_struct + put_unused_fd + pwm_apply_state + pwmchip_add + pwmchip_remove + qcom_smem_state_get + qcom_smem_state_register + qcom_smem_state_unregister + qcom_smem_state_update_bits + queue_delayed_work_on + queue_work_on + radix_tree_insert + radix_tree_iter_delete + radix_tree_lookup + radix_tree_next_chunk + ___ratelimit + rational_best_approximation + raw_notifier_call_chain + raw_notifier_chain_register + raw_notifier_chain_unregister + _raw_read_lock + _raw_read_lock_bh + _raw_read_lock_irq + _raw_read_lock_irqsave + _raw_read_unlock + _raw_read_unlock_bh + _raw_read_unlock_irq + _raw_read_unlock_irqrestore + _raw_spin_lock + _raw_spin_lock_bh + _raw_spin_lock_irq + _raw_spin_lock_irqsave + _raw_spin_trylock + _raw_spin_trylock_bh + _raw_spin_unlock + _raw_spin_unlock_bh + _raw_spin_unlock_irq + _raw_spin_unlock_irqrestore + _raw_write_lock + _raw_write_lock_bh + _raw_write_lock_irq + _raw_write_lock_irqsave + _raw_write_unlock + _raw_write_unlock_bh + _raw_write_unlock_irq + _raw_write_unlock_irqrestore + rb_erase + rb_first + rb_insert_color + rb_last + rb_next + rb_prev + __rcu_read_lock + __rcu_read_unlock + rdev_get_drvdata + reboot_mode + refcount_dec_and_lock + refcount_dec_not_one + refcount_warn_saturate + register_blkdev + __register_chrdev + register_chrdev_region + register_console + register_die_notifier + register_ftrace_export + register_kretprobe + register_memory_notifier + register_module_notifier + register_pm_notifier + register_reboot_notifier + register_restart_handler + __register_rpmsg_driver + register_shrinker + register_syscore_ops + register_sysctl_table + regmap_bulk_read + regmap_bulk_write + regmap_check_range_table + regmap_field_read + regmap_field_update_bits_base + __regmap_init + regmap_mmio_detach_clk + regmap_read + regmap_update_bits_base + regmap_write + regulator_allow_bypass + regulator_bulk_disable + regulator_count_voltages + regulator_disable + regulator_disable_deferred + regulator_enable + regulator_force_disable + regulator_get + regulator_get_drvdata + regulator_get_mode + regulator_get_voltage + regulator_get_voltage_rdev + regulator_is_enabled + regulator_is_supported_voltage + regulator_list_voltage_linear + regulator_notifier_call_chain + regulator_put + regulator_register_notifier + regulator_set_current_limit + regulator_set_load + regulator_set_mode + regulator_set_voltage + regulator_unregister_notifier + release_firmware + release_sock + remap_pfn_range + remove_cpu + remove_memory_subsection + report_iommu_fault + request_any_context_irq + request_firmware + request_firmware_into_buf + request_firmware_nowait + __request_module + __request_percpu_irq + request_threaded_irq + resched_curr + reset_control_assert + reset_control_deassert + resume_cpus + revalidate_disk_size + rfkill_alloc + rfkill_destroy + rfkill_init_sw_state + rfkill_register + rfkill_unregister + rndis_deregister + rndis_free_response + rndis_get_next_response + rndis_msg_parser + rndis_register + rndis_set_host_mac + rndis_set_param_dev + rndis_set_param_medium + rndis_set_param_vendor + rndis_signal_connect + rndis_uninit + root_task_group + round_jiffies_relative + rpmsg_get_signals + rpmsg_poll + rpmsg_register_device + rpmsg_send + rpmsg_set_signals + rpmsg_trysend + rpmsg_unregister_device + rproc_add + rproc_add_subdev + rproc_alloc + rproc_boot + rproc_coredump_add_custom_segment + rproc_coredump_add_segment + rproc_coredump_set_elf_info + rproc_coredump_using_sections + rproc_del + rproc_free + rproc_get_by_child + rproc_get_by_phandle + rproc_put + rproc_remove_subdev + rproc_report_crash + rproc_shutdown + rtc_class_close + rtc_class_open + rtc_read_time + __rtc_register_device + rtc_time64_to_tm + rtc_tm_to_time64 + rtc_update_irq + rtc_valid_tm + runqueues + sbitmap_add_wait_queue + sbitmap_any_bit_set + sbitmap_del_wait_queue + sbitmap_init_node + sbitmap_queue_clear + __sbitmap_queue_get + sbitmap_queue_init_node + sbitmap_queue_min_shallow_depth + sbitmap_queue_resize + sbitmap_queue_show + sched_clock + sched_feat_keys + sched_feat_names + sched_setattr + sched_set_fifo + sched_set_normal + sched_setscheduler + sched_setscheduler_nocheck + sched_uclamp_used + schedule + schedule_timeout + scnprintf + scsi_autopm_get_device + scsi_autopm_put_device + scsi_block_when_processing_errors + scsi_command_size_tbl + scsi_compat_ioctl + scsi_device_get + scsi_device_put + scsi_device_quiesce + scsi_ioctl + scsi_ioctl_block_when_processing_errors + __scsi_iterate_devices + scsi_normalize_sense + __scsi_print_sense + scsi_print_sense_hdr + scsi_register_interface + scsi_remove_device + sdev_prefix_printk + __sdhci_add_host + sdhci_add_host + sdhci_cleanup_host + sdhci_cqe_disable + sdhci_cqe_enable + sdhci_cqe_irq + sdhci_enable_clk + sdhci_get_property + sdhci_pltfm_free + sdhci_pltfm_init + sdhci_remove_host + sdhci_reset + sdhci_set_bus_width + sdhci_set_power_noreg + sdhci_setup_host + seq_buf_printf + seq_list_next + seq_list_start + seq_lseek + seq_open + seq_printf + seq_putc + seq_puts + seq_read + seq_release + set_cpus_allowed_ptr + set_normalized_timespec64 + set_page_dirty_lock + __SetPageMovable + set_task_cpu + set_user_nice + sg_alloc_table + sg_alloc_table_from_pages + sg_free_table + sg_init_one + sg_init_table + sg_miter_next + sg_miter_start + sg_miter_stop + sg_next + __sg_page_iter_dma_next + __sg_page_iter_next + __sg_page_iter_start + sg_scsi_ioctl + show_regs + sigprocmask + si_meminfo + simple_attr_open + simple_attr_release + simple_open + simple_read_from_buffer + simple_write_to_buffer + single_open + single_release + si_swapinfo + sk_alloc + skb_clone + skb_copy_bits + skb_copy_datagram_iter + skb_dequeue + skb_free_datagram + __skb_pad + skb_push + skb_put + skb_queue_purge + skb_queue_tail + skb_recv_datagram + skb_set_owner_w + skb_store_bits + skb_trim + sk_free + skip_spaces + smp_call_function_single + snd_pcm_format_width + snd_soc_add_component_controls + snd_soc_info_volsw + snd_soc_register_component + snd_soc_unregister_component + snd_usb_enable_audio_stream + snprintf + soc_device_register + soc_device_unregister + sock_alloc_send_skb + sock_create_kern + sock_gettstamp + sock_init_data + sock_no_accept + sock_no_listen + sock_no_mmap + sock_no_sendpage + sock_no_shutdown + sock_no_socketpair + sock_queue_rcv_skb + sock_register + sock_release + sock_setsockopt + sock_unregister + sort + __spi_alloc_controller + spi_register_controller + spi_unregister_controller + spmi_controller_add + spmi_controller_alloc + spmi_controller_remove + __spmi_driver_register + spmi_ext_register_read + spmi_ext_register_readl + spmi_ext_register_write + spmi_ext_register_writel + spmi_register_read + spmi_register_write + spmi_register_zero_write + sprintf + srcu_init_notifier_head + srcu_notifier_call_chain + srcu_notifier_chain_register + srcu_notifier_chain_unregister + __srcu_read_lock + __srcu_read_unlock + sscanf + __stack_chk_fail + __stack_chk_guard + stack_trace_save_tsk + static_key_disable + stop_machine + stop_one_cpu_nowait + strcmp + strcpy + strim + strlcat + strlcpy + strlen + strncasecmp + strnchr + strncmp + strncpy + strncpy_from_user + strnlen + strnstr + strpbrk + strrchr + strscpy + strsep + strstr + __sw_hweight32 + __sw_hweight64 + __sw_hweight8 + sync_file_create + sync_file_get_fence + synchronize_irq + synchronize_rcu + synchronize_srcu + syscon_node_to_regmap + syscon_regmap_lookup_by_phandle + sysctl_sched_features + sysctl_vals + sysfs_add_file_to_group + sysfs_add_link_to_group + sysfs_create_bin_file + sysfs_create_file_ns + sysfs_create_files + sysfs_create_group + sysfs_create_link + sysfs_emit + __sysfs_match_string + sysfs_notify + sysfs_remove_bin_file + sysfs_remove_file_from_group + sysfs_remove_file_ns + sysfs_remove_files + sysfs_remove_group + sysfs_remove_link + sysfs_remove_link_from_group + sysfs_streq + sysrq_mask + system_freezable_wq + system_highpri_wq + system_unbound_wq + system_wq + sys_tz + task_active_pid_ns + __tasklet_hi_schedule + tasklet_init + tasklet_kill + __tasklet_schedule + tasklet_setup + tasklist_lock + task_may_not_preempt + __task_pid_nr_ns + __task_rq_lock + thermal_cooling_device_unregister + thermal_of_cooling_device_register + thermal_pressure + thermal_zone_device_enable + thermal_zone_device_register + thermal_zone_device_unregister + thermal_zone_device_update + thermal_zone_get_slope + thermal_zone_get_temp + thermal_zone_get_zone_by_name + thermal_zone_of_sensor_register + thermal_zone_of_sensor_unregister + tick_nohz_get_sleep_length + time64_to_tm + timer_reduce + topology_set_thermal_pressure + total_swapcache_pages + trace_array_get_by_name + trace_array_put + trace_array_set_clr_event + trace_event_buffer_commit + trace_event_buffer_reserve + trace_event_ignore_this_pid + trace_event_raw_init + trace_event_reg + trace_handle_return + __traceiter_android_rvh_account_irq + __traceiter_android_rvh_build_perf_domains + __traceiter_android_rvh_can_migrate_task + __traceiter_android_rvh_check_preempt_wakeup + __traceiter_android_rvh_cpu_cgroup_attach + __traceiter_android_rvh_cpu_cgroup_online + __traceiter_android_rvh_dequeue_task + __traceiter_android_rvh_enqueue_task + __traceiter_android_rvh_find_busiest_queue + __traceiter_android_rvh_find_lowest_rq + __traceiter_android_rvh_flush_task + __traceiter_android_rvh_migrate_queued_task + __traceiter_android_rvh_new_task_stats + __traceiter_android_rvh_replace_next_task_fair + __traceiter_android_rvh_resume_cpus + __traceiter_android_rvh_sched_cpu_dying + __traceiter_android_rvh_sched_cpu_starting + __traceiter_android_rvh_sched_exec + __traceiter_android_rvh_sched_fork + __traceiter_android_rvh_sched_fork_init + __traceiter_android_rvh_sched_newidle_balance + __traceiter_android_rvh_sched_nohz_balancer_kick + __traceiter_android_rvh_sched_setaffinity + __traceiter_android_rvh_schedule + __traceiter_android_rvh_select_task_rq_fair + __traceiter_android_rvh_select_task_rq_rt + __traceiter_android_rvh_set_gfp_zone_flags + __traceiter_android_rvh_set_readahead_gfp_mask + __traceiter_android_rvh_set_skip_swapcache_flags + __traceiter_android_rvh_set_task_cpu + __traceiter_android_rvh_tick_entry + __traceiter_android_rvh_try_to_wake_up + __traceiter_android_rvh_try_to_wake_up_success + __traceiter_android_rvh_ttwu_cond + __traceiter_android_rvh_update_cpu_capacity + __traceiter_android_rvh_update_cpus_allowed + __traceiter_android_rvh_update_misfit_status + __traceiter_android_rvh_wake_up_new_task + __traceiter_android_vh_allow_domain_state + __traceiter_android_vh_binder_restore_priority + __traceiter_android_vh_binder_set_priority + __traceiter_android_vh_binder_wakeup_ilocked + __traceiter_android_vh_cpu_idle_enter + __traceiter_android_vh_cpu_idle_exit + __traceiter_android_vh_ftrace_dump_buffer + __traceiter_android_vh_ftrace_format_check + __traceiter_android_vh_ftrace_oops_enter + __traceiter_android_vh_ftrace_oops_exit + __traceiter_android_vh_ftrace_size_check + __traceiter_android_vh_iommu_setup_dma_ops + __traceiter_android_vh_ipi_stop + __traceiter_android_vh_jiffies_update + __traceiter_android_vh_mmc_attach_sd + __traceiter_android_vh_mmc_blk_mq_rw_recovery + __traceiter_android_vh_mmc_blk_reset + __traceiter_android_vh_mmc_gpio_cd_irqt + __traceiter_android_vh_printk_hotplug + __traceiter_android_vh_scheduler_tick + __traceiter_android_vh_sdhci_get_cd + __traceiter_android_vh_sd_update_bus_speed_mode + __traceiter_android_vh_show_max_freq + __traceiter_android_vh_show_resume_epoch_val + __traceiter_android_vh_show_suspend_epoch_val + __traceiter_android_vh_timer_calc_index + __traceiter_android_vh_ufs_check_int_errors + __traceiter_android_vh_ufs_compl_command + __traceiter_android_vh_ufs_send_command + __traceiter_android_vh_ufs_update_sdev + __traceiter_binder_transaction_received + __traceiter_cpu_frequency_limits + __traceiter_cpu_idle + __traceiter_dwc3_complete_trb + __traceiter_dwc3_ctrl_req + __traceiter_dwc3_event + __traceiter_ipi_entry + __traceiter_ipi_raise + __traceiter_rwmmio_post_read + __traceiter_rwmmio_read + __traceiter_rwmmio_write + __traceiter_suspend_resume + __traceiter_usb_gadget_connect + __traceiter_usb_gadget_disconnect + __tracepoint_android_rvh_account_irq + __tracepoint_android_rvh_build_perf_domains + __tracepoint_android_rvh_can_migrate_task + __tracepoint_android_rvh_check_preempt_wakeup + __tracepoint_android_rvh_cpu_cgroup_attach + __tracepoint_android_rvh_cpu_cgroup_online + __tracepoint_android_rvh_dequeue_task + __tracepoint_android_rvh_enqueue_task + __tracepoint_android_rvh_find_busiest_queue + __tracepoint_android_rvh_find_lowest_rq + __tracepoint_android_rvh_flush_task + __tracepoint_android_rvh_migrate_queued_task + __tracepoint_android_rvh_new_task_stats + __tracepoint_android_rvh_replace_next_task_fair + __tracepoint_android_rvh_resume_cpus + __tracepoint_android_rvh_sched_cpu_dying + __tracepoint_android_rvh_sched_cpu_starting + __tracepoint_android_rvh_sched_exec + __tracepoint_android_rvh_sched_fork + __tracepoint_android_rvh_sched_fork_init + __tracepoint_android_rvh_sched_newidle_balance + __tracepoint_android_rvh_sched_nohz_balancer_kick + __tracepoint_android_rvh_sched_setaffinity + __tracepoint_android_rvh_schedule + __tracepoint_android_rvh_select_task_rq_fair + __tracepoint_android_rvh_select_task_rq_rt + __tracepoint_android_rvh_set_gfp_zone_flags + __tracepoint_android_rvh_set_readahead_gfp_mask + __tracepoint_android_rvh_set_skip_swapcache_flags + __tracepoint_android_rvh_set_task_cpu + __tracepoint_android_rvh_tick_entry + __tracepoint_android_rvh_try_to_wake_up + __tracepoint_android_rvh_try_to_wake_up_success + __tracepoint_android_rvh_ttwu_cond + __tracepoint_android_rvh_update_cpu_capacity + __tracepoint_android_rvh_update_cpus_allowed + __tracepoint_android_rvh_update_misfit_status + __tracepoint_android_rvh_wake_up_new_task + __tracepoint_android_vh_allow_domain_state + __tracepoint_android_vh_binder_restore_priority + __tracepoint_android_vh_binder_set_priority + __tracepoint_android_vh_binder_wakeup_ilocked + __tracepoint_android_vh_cpu_idle_enter + __tracepoint_android_vh_cpu_idle_exit + __tracepoint_android_vh_ftrace_dump_buffer + __tracepoint_android_vh_ftrace_format_check + __tracepoint_android_vh_ftrace_oops_enter + __tracepoint_android_vh_ftrace_oops_exit + __tracepoint_android_vh_ftrace_size_check + __tracepoint_android_vh_iommu_setup_dma_ops + __tracepoint_android_vh_ipi_stop + __tracepoint_android_vh_jiffies_update + __tracepoint_android_vh_mmc_attach_sd + __tracepoint_android_vh_mmc_blk_mq_rw_recovery + __tracepoint_android_vh_mmc_blk_reset + __tracepoint_android_vh_mmc_gpio_cd_irqt + __tracepoint_android_vh_printk_hotplug + __tracepoint_android_vh_scheduler_tick + __tracepoint_android_vh_sdhci_get_cd + __tracepoint_android_vh_sd_update_bus_speed_mode + __tracepoint_android_vh_show_max_freq + __tracepoint_android_vh_show_resume_epoch_val + __tracepoint_android_vh_show_suspend_epoch_val + __tracepoint_android_vh_timer_calc_index + __tracepoint_android_vh_ufs_check_int_errors + __tracepoint_android_vh_ufs_compl_command + __tracepoint_android_vh_ufs_send_command + __tracepoint_android_vh_ufs_update_sdev + __tracepoint_binder_transaction_received + __tracepoint_cpu_frequency_limits + __tracepoint_cpu_idle + __tracepoint_dwc3_complete_trb + __tracepoint_dwc3_ctrl_req + __tracepoint_dwc3_event + __tracepoint_ipi_entry + __tracepoint_ipi_raise + tracepoint_probe_register + tracepoint_probe_register_prio + tracepoint_probe_unregister + __tracepoint_rwmmio_post_read + __tracepoint_rwmmio_read + __tracepoint_rwmmio_write + __tracepoint_suspend_resume + __tracepoint_usb_gadget_connect + __tracepoint_usb_gadget_disconnect + trace_print_array_seq + trace_print_flags_seq + trace_print_symbols_seq + trace_raw_output_prep + trace_seq_printf + trace_seq_putc + try_module_get + try_wait_for_completion + tty_flip_buffer_push + __tty_insert_flip_char + tty_insert_flip_string_fixed_flag + uart_add_one_port + uart_console_device + uart_console_write + uart_get_baud_rate + uart_insert_char + uart_parse_options + uart_register_driver + uart_remove_one_port + uart_resume_port + uart_set_options + uart_suspend_port + uart_try_toggle_sysrq + uart_unregister_driver + uart_update_timeout + uart_write_wakeup + uclamp_eff_value + ucsi_connector_change + ucsi_create + ucsi_destroy + ucsi_get_drvdata + ucsi_register + ucsi_set_drvdata + ucsi_unregister + __udelay + ufshcd_auto_hibern8_update + ufshcd_dme_get_attr + ufshcd_dme_set_attr + ufshcd_dump_regs + ufshcd_fixup_dev_quirks + ufshcd_get_local_unipro_ver + ufshcd_pltfrm_init + ufshcd_pltfrm_resume + ufshcd_pltfrm_runtime_idle + ufshcd_pltfrm_runtime_resume + ufshcd_pltfrm_runtime_suspend + ufshcd_pltfrm_suspend + ufshcd_query_attr + ufshcd_query_attr_retry + ufshcd_query_descriptor_retry + ufshcd_query_flag + ufshcd_read_desc_param + ufshcd_remove + ufshcd_shutdown + ufshcd_uic_hibern8_enter + ufshcd_uic_hibern8_exit + __uio_register_device + uio_unregister_device + unlock_page + unregister_blkdev + __unregister_chrdev + unregister_chrdev_region + unregister_console + unregister_die_notifier + unregister_ftrace_export + unregister_kretprobe + unregister_module_notifier + unregister_pm_notifier + unregister_reboot_notifier + unregister_restart_handler + unregister_rpmsg_driver + unregister_shrinker + unregister_syscore_ops + update_devfreq + update_rq_clock + up_read + up_write + usb_add_phy_dev + usb_alloc_coherent + usb_alloc_dev + usb_alloc_urb + usb_assign_descriptors + usb_composite_setup_continue + usb_control_msg + usb_deregister + usb_ep_alloc_request + usb_ep_autoconfig + usb_ep_dequeue + usb_ep_disable + usb_ep_enable + usb_ep_free_request + usb_ep_queue + usb_ep_set_halt + usb_find_common_endpoints + usb_free_all_descriptors + usb_free_coherent + usb_free_urb + usb_function_register + usb_function_unregister + usb_gadget_wakeup + usb_ifnum_to_if + usb_interface_id + usb_phy_set_charger_current + usb_poison_urb + usb_put_dev + usb_put_function_instance + usb_register_driver + usb_register_notify + usb_remove_phy + usb_role_switch_find_by_fwnode + usb_role_switch_get_drvdata + usb_role_switch_register + usb_role_switch_set_role + usb_role_switch_unregister + usb_set_device_state + usb_speed_string + usb_string_id + usb_submit_urb + usb_unregister_notify + __usecs_to_jiffies + usleep_range + v4l2_compat_ioctl32 + v4l2_ctrl_handler_free + v4l2_device_register + v4l2_device_unregister + vabits_actual + vchan_dma_desc_free_list + vchan_find_desc + vchan_init + vchan_tx_desc_free + vchan_tx_submit + vfree + video_devdata + video_device_release_empty + video_ioctl2 + __video_register_device + video_unregister_device + vmalloc + vmalloc_nr_pages + vmalloc_to_page + vmalloc_to_pfn + vmap + vmf_insert_pfn + vm_insert_page + vm_iomap_memory + vm_map_pages + vm_node_stat + vm_zone_stat + vscnprintf + vsnprintf + vunmap + vzalloc + wait_for_completion + wait_for_completion_interruptible + wait_for_completion_interruptible_timeout + wait_for_completion_killable + wait_for_completion_timeout + __wake_up + wake_up_if_idle + wake_up_process + wakeup_source_add + wakeup_source_register + wakeup_source_remove + wakeup_source_unregister + __warn_printk + ww_mutex_lock + ww_mutex_unlock + __xa_alloc + xa_destroy + xa_erase + xa_find + xa_find_after + xa_load + xa_store + xhci_alloc_command + xhci_alloc_erst + xhci_free_command + xhci_get_endpoint_index + xhci_queue_stop_endpoint + xhci_ring_alloc + xhci_ring_cmd_db + xhci_ring_free + xhci_trb_virt_to_dma + zone_watermark_ok_safe diff --git a/android/abi_gki_aarch64_xiaomi b/android/abi_gki_aarch64_xiaomi index 867cd0739539..8391dff8489d 100644 --- a/android/abi_gki_aarch64_xiaomi +++ b/android/abi_gki_aarch64_xiaomi @@ -1,10 +1,9 @@ [abi_symbol_list] # commonly used symbols -# required by xxx.ko - # required by touch module proc_mkdir_data + proc_create_seq_private # required by aw8697-haptic.ko devm_gpio_free @@ -37,6 +36,10 @@ scsi_report_bus_reset scsi_scan_host scsi_unblock_requests + scsi_change_queue_depth + scsi_print_command + scsi_dma_map + scsi_host_alloc sg_copy_from_buffer sg_copy_to_buffer ufshcd_alloc_host @@ -47,10 +50,14 @@ ufshcd_map_desc_id_to_length ufshcd_query_attr_retry ufshcd_query_flag_retry + ufshcd_update_evt_hist wait_for_completion_io_timeout __scsi_add_device __scsi_execute blk_mq_free_tag_set + blk_queue_update_dma_alignment + blk_queue_update_dma_pad + blk_ksm_get_slot_idx #required by cs35l41 module regmap_raw_write_async @@ -112,3 +119,39 @@ simple_strtoul sync_blockdev wait_for_device_probe + +#required by millet.ko + freezer_cgrp_subsys + __traceiter_android_vh_do_send_sig_info + __traceiter_android_vh_binder_preset + __traceiter_android_vh_binder_wait_for_work + __traceiter_android_vh_binder_trans + __traceiter_android_vh_binder_reply + __traceiter_android_vh_binder_alloc_new_buf_locked + __tracepoint_android_vh_do_send_sig_info + __tracepoint_android_vh_binder_preset + __tracepoint_android_vh_binder_wait_for_work + __tracepoint_android_vh_binder_trans + __tracepoint_android_vh_binder_reply + __tracepoint_android_vh_binder_alloc_new_buf_locked + +#required by mi_sched.ko + __traceiter_android_vh_free_task + __tracepoint_android_vh_free_task + jiffies_64 + +#required by pm8941-pwrkey.ko module + console_printk + +#required by binderinfo.ko module + __traceiter_android_vh_binder_transaction_init + __traceiter_android_vh_binder_print_transaction_info + __tracepoint_android_vh_binder_transaction_init + __tracepoint_android_vh_binder_print_transaction_info + +#required by reclaim module + __traceiter_android_vh_tune_scan_type + __tracepoint_android_vh_tune_scan_type + __traceiter_android_vh_tune_swappiness + __tracepoint_android_vh_tune_swappiness + diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 002e0cf025f5..e485c4813441 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -51,6 +51,7 @@ config ARM select GENERIC_ATOMIC64 if CPU_V7M || CPU_V6 || !CPU_32v6K || !AEABI select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_IRQ_IPI if SMP + select ARCH_WANTS_IRQ_RAW if GENERIC_IRQ_IPI select GENERIC_CPU_AUTOPROBE select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP diff --git a/arch/arm/OWNERS b/arch/arm/OWNERS deleted file mode 100644 index 1e390c75956e..000000000000 --- a/arch/arm/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/arch/arm/OWNERS diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index e3ae634a36d5..ba27e184402a 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -742,6 +742,10 @@ void __init set_smp_ipi_range(int ipi_base, int n) ipi_desc[i] = irq_to_desc(ipi_base + i); irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); + + /* The recheduling IPI is special... */ + if (i == IPI_RESCHEDULE) + __irq_modify_status(ipi_base + i, 0, IRQ_RAW, ~0); } ipi_irq_base = ipi_base; diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a7c07ae524d9..cf21e80963b5 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -111,6 +111,7 @@ config ARM64 select GENERIC_EARLY_IOREMAP select GENERIC_IDLE_POLL_SETUP select GENERIC_IRQ_IPI + select ARCH_WANTS_IRQ_RAW select GENERIC_IRQ_MULTI_HANDLER select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW diff --git a/arch/arm64/OWNERS b/arch/arm64/OWNERS deleted file mode 100644 index 257f4cf26809..000000000000 --- a/arch/arm64/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/arch/arm64/OWNERS diff --git a/arch/arm64/configs/db845c_gki.fragment b/arch/arm64/configs/db845c_gki.fragment index d487757cfa3c..e7c8f04055e6 100644 --- a/arch/arm64/configs/db845c_gki.fragment +++ b/arch/arm64/configs/db845c_gki.fragment @@ -1,3 +1,8 @@ +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_MAC80211=m CONFIG_QRTR=m CONFIG_QRTR_TUN=m CONFIG_SCSI_UFS_QCOM=m diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 2289194dae73..530e618d8d25 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -15,6 +15,7 @@ CONFIG_IKHEADERS=y CONFIG_UCLAMP_TASK=y CONFIG_UCLAMP_BUCKETS_COUNT=20 CONFIG_CGROUPS=y +CONFIG_MEMCG=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_SCHED=y CONFIG_UCLAMP_TASK_GROUP=y @@ -48,6 +49,7 @@ CONFIG_PROFILING=y CONFIG_ARCH_SUNXI=y CONFIG_ARCH_HISI=y CONFIG_ARCH_QCOM=y +CONFIG_ARCH_SPRD=y CONFIG_SCHED_MC=y CONFIG_NR_CPUS=32 CONFIG_PARAVIRT=y @@ -59,7 +61,7 @@ CONFIG_CP15_BARRIER_EMULATION=y CONFIG_SETEND_EMULATION=y CONFIG_RANDOMIZE_BASE=y # CONFIG_RANDOMIZE_MODULE_REGION_FULL is not set -CONFIG_CMDLINE="stack_depot_disable=on kasan.stacktrace=off kvm-arm.mode=protected" +CONFIG_CMDLINE="stack_depot_disable=on kasan.stacktrace=off kvm-arm.mode=protected cgroup_disable=pressure cgroup.memory=nokmem" CONFIG_CMDLINE_EXTEND=y # CONFIG_DMI is not set CONFIG_PM_WAKELOCKS=y @@ -96,6 +98,7 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SCMVERSION=y +CONFIG_BLK_CGROUP_IOCOST=y CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y CONFIG_IOSCHED_BFQ=y @@ -255,7 +258,9 @@ CONFIG_NET_ACT_GACT=y CONFIG_NET_ACT_MIRRED=y CONFIG_NET_ACT_SKBEDIT=y CONFIG_VSOCKETS=y +CONFIG_CGROUP_NET_PRIO=y CONFIG_BPF_JIT=y +CONFIG_CAN=y CONFIG_BT=y CONFIG_BT_RFCOMM=y CONFIG_BT_RFCOMM_TTY=y @@ -265,15 +270,12 @@ CONFIG_BT_HCIUART=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_BCM=y CONFIG_BT_HCIUART_QCA=y -CONFIG_CFG80211=y -CONFIG_NL80211_TESTMODE=y -# CONFIG_CFG80211_DEFAULT_PS is not set -# CONFIG_CFG80211_CRDA_SUPPORT is not set -CONFIG_MAC80211=y CONFIG_RFKILL=y +CONFIG_NFC=y CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCIEAER=y +CONFIG_PCI_IOV=y CONFIG_PCI_HOST_GENERIC=y CONFIG_PCIE_DW_PLAT_EP=y CONFIG_PCIE_QCOM=y @@ -300,6 +302,7 @@ CONFIG_SCSI_UFS_DWC_TC_PLATFORM=y CONFIG_SCSI_UFS_HISI=y CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFS_CRYPTO=y +CONFIG_SCSI_UFS_HPB=y CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=y @@ -436,7 +439,6 @@ CONFIG_SND=y CONFIG_SND_HRTIMER=y CONFIG_SND_DYNAMIC_MINORS=y # CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_DRIVERS is not set CONFIG_SND_USB_AUDIO=y CONFIG_SND_SOC=y @@ -469,6 +471,7 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_OTG=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_ACM=y CONFIG_USB_STORAGE=y @@ -518,6 +521,7 @@ CONFIG_STAGING=y CONFIG_ASHMEM=y CONFIG_DEBUG_KINFO=y CONFIG_COMMON_CLK_SCPI=y +# CONFIG_SPRD_COMMON_CLK is not set # CONFIG_CLK_SUNXI is not set # CONFIG_SUNXI_CCU is not set CONFIG_HWSPINLOCK=y @@ -665,7 +669,6 @@ CONFIG_UBSAN_LOCAL_BOUNDS=y # CONFIG_UBSAN_MISC is not set CONFIG_PAGE_OWNER=y CONFIG_PAGE_PINNER=y -CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_KASAN=y CONFIG_KASAN_HW_TAGS=y diff --git a/arch/arm64/configs/hikey960_gki.fragment b/arch/arm64/configs/hikey960_gki.fragment index ba7e473b55ae..fcc01e20dc7f 100644 --- a/arch/arm64/configs/hikey960_gki.fragment +++ b/arch/arm64/configs/hikey960_gki.fragment @@ -50,3 +50,8 @@ CONFIG_PHY_HI3660_USB=m CONFIG_PINCTRL_SINGLE=m CONFIG_DMABUF_HEAPS_CMA=m CONFIG_DMABUF_HEAPS_SYSTEM=m +CONFIG_CFG80211=m +CONFIG_NL80211_TESTMODE=y +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_MAC80211=m diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 9f0ec21d6327..88d20f04c64a 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -165,25 +165,6 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl) isb(); } -/* - * Ensure that reads of the counter are treated the same as memory reads - * for the purposes of ordering by subsequent memory barriers. - * - * This insanity brought to you by speculative system register reads, - * out-of-order memory accesses, sequence locks and Thomas Gleixner. - * - * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html - */ -#define arch_counter_enforce_ordering(val) do { \ - u64 tmp, _val = (val); \ - \ - asm volatile( \ - " eor %0, %1, %1\n" \ - " add %0, sp, %0\n" \ - " ldr xzr, [%0]" \ - : "=r" (tmp) : "r" (_val)); \ -} while (0) - static __always_inline u64 __arch_counter_get_cntpct_stable(void) { u64 cnt; @@ -224,8 +205,6 @@ static __always_inline u64 __arch_counter_get_cntvct(void) return cnt; } -#undef arch_counter_enforce_ordering - static inline int arch_timer_arch_init(void) { return 0; diff --git a/arch/arm64/include/asm/asm_pointer_auth.h b/arch/arm64/include/asm/asm_pointer_auth.h index 52dead2a8640..8ca2dc0661ee 100644 --- a/arch/arm64/include/asm/asm_pointer_auth.h +++ b/arch/arm64/include/asm/asm_pointer_auth.h @@ -13,30 +13,12 @@ * so use the base value of ldp as thread.keys_user and offset as * thread.keys_user.ap*. */ - .macro ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3 + .macro __ptrauth_keys_install_user tsk, tmp1, tmp2, tmp3 mov \tmp1, #THREAD_KEYS_USER add \tmp1, \tsk, \tmp1 -alternative_if_not ARM64_HAS_ADDRESS_AUTH - b .Laddr_auth_skip_\@ -alternative_else_nop_endif ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_USER_KEY_APIA] msr_s SYS_APIAKEYLO_EL1, \tmp2 msr_s SYS_APIAKEYHI_EL1, \tmp3 - ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_USER_KEY_APIB] - msr_s SYS_APIBKEYLO_EL1, \tmp2 - msr_s SYS_APIBKEYHI_EL1, \tmp3 - ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_USER_KEY_APDA] - msr_s SYS_APDAKEYLO_EL1, \tmp2 - msr_s SYS_APDAKEYHI_EL1, \tmp3 - ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_USER_KEY_APDB] - msr_s SYS_APDBKEYLO_EL1, \tmp2 - msr_s SYS_APDBKEYHI_EL1, \tmp3 -.Laddr_auth_skip_\@: -alternative_if ARM64_HAS_GENERIC_AUTH - ldp \tmp2, \tmp3, [\tmp1, #PTRAUTH_USER_KEY_APGA] - msr_s SYS_APGAKEYLO_EL1, \tmp2 - msr_s SYS_APGAKEYHI_EL1, \tmp3 -alternative_else_nop_endif .endm .macro __ptrauth_keys_install_kernel_nosync tsk, tmp1, tmp2, tmp3 diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h index 5a8367a2b868..bffa8860af1c 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -71,6 +71,25 @@ static inline unsigned long array_index_mask_nospec(unsigned long idx, return mask; } +/* + * Ensure that reads of the counter are treated the same as memory reads + * for the purposes of ordering by subsequent memory barriers. + * + * This insanity brought to you by speculative system register reads, + * out-of-order memory accesses, sequence locks and Thomas Gleixner. + * + * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html + */ +#define arch_counter_enforce_ordering(val) do { \ + u64 tmp, _val = (val); \ + \ + asm volatile( \ + " eor %0, %1, %1\n" \ + " add %0, sp, %0\n" \ + " ldr xzr, [%0]" \ + : "=r" (tmp) : "r" (_val)); \ +} while (0) + #define __smp_mb() dmb(ish) #define __smp_rmb() dmb(ishld) #define __smp_wmb() dmb(ishst) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index e573bc2b1b83..923ffa4cbc5f 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -405,6 +405,8 @@ struct kvm_vcpu_arch { #define KVM_ARM64_GUEST_HAS_PTRAUTH (1 << 7) /* PTRAUTH exposed to guest */ #define KVM_ARM64_PENDING_EXCEPTION (1 << 8) /* Exception pending */ #define KVM_ARM64_EXCEPT_MASK (7 << 9) /* Target EL/MODE */ +#define KVM_ARM64_DEBUG_STATE_SAVE_SPE (1 << 12) /* Save SPE context if active */ +#define KVM_ARM64_DEBUG_STATE_SAVE_TRBE (1 << 13) /* Save TRBE context if active */ /* * When KVM_ARM64_PENDING_EXCEPTION is set, KVM_ARM64_EXCEPT_MASK can @@ -733,6 +735,10 @@ static inline bool kvm_pmu_counter_deferred(struct perf_event_attr *attr) return (!has_vhe() && attr->exclude_host); } +/* Flags for host debug state */ +void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu); +void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu); + #ifdef CONFIG_KVM /* Avoid conflicts with core headers if CONFIG_KVM=n */ static inline int kvm_arch_vcpu_run_pid_change(struct kvm_vcpu *vcpu) { diff --git a/arch/arm64/include/asm/lse.h b/arch/arm64/include/asm/lse.h index 5d10051c3e62..29d0719bd2ed 100644 --- a/arch/arm64/include/asm/lse.h +++ b/arch/arm64/include/asm/lse.h @@ -4,7 +4,7 @@ #include -#ifdef CONFIG_ARM64_LSE_ATOMICS +#if defined(CONFIG_ARM64_LSE_ATOMICS) && !defined(BUILD_FIPS140_KO) #define __LSE_PREAMBLE ".arch_extension lse\n" diff --git a/arch/arm64/include/asm/mte.h b/arch/arm64/include/asm/mte.h index 51006e08c1e9..67bf259ae768 100644 --- a/arch/arm64/include/asm/mte.h +++ b/arch/arm64/include/asm/mte.h @@ -37,9 +37,10 @@ void mte_free_tag_storage(char *storage); /* track which pages have valid allocation tags */ #define PG_mte_tagged PG_arch_2 +void mte_zero_clear_page_tags(void *addr); void mte_sync_tags(pte_t *ptep, pte_t pte); void mte_copy_page_tags(void *kto, const void *kfrom); -void flush_mte_state(void); +void mte_thread_init_user(void); void mte_thread_switch(struct task_struct *next); void mte_suspend_enter(void); void mte_suspend_exit(void); @@ -53,13 +54,16 @@ int mte_ptrace_copy_tags(struct task_struct *child, long request, /* unused if !CONFIG_ARM64_MTE, silence the compiler */ #define PG_mte_tagged 0 +static inline void mte_zero_clear_page_tags(void *addr) +{ +} static inline void mte_sync_tags(pte_t *ptep, pte_t pte) { } static inline void mte_copy_page_tags(void *kto, const void *kfrom) { } -static inline void flush_mte_state(void) +static inline void mte_thread_init_user(void) { } static inline void mte_thread_switch(struct task_struct *next) diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 27990db54347..ed1b9dcf12b2 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -13,6 +13,7 @@ #ifndef __ASSEMBLY__ #include /* for READ_IMPLIES_EXEC */ +#include /* for gfp_t */ #include struct page; @@ -28,10 +29,13 @@ void copy_user_highpage(struct page *to, struct page *from, void copy_highpage(struct page *to, struct page *from); #define __HAVE_ARCH_COPY_HIGHPAGE -#define alloc_zeroed_user_highpage_movable(vma, vaddr) \ - alloc_page_vma(GFP_HIGHUSER_MOVABLE | __GFP_ZERO | __GFP_CMA, vma, vaddr) +struct page *alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma, + unsigned long vaddr); #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE_MOVABLE +void tag_clear_highpage(struct page *to); +#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGE + #define clear_user_page(page, vaddr, pg) clear_page(page) #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) diff --git a/arch/arm64/include/asm/pointer_auth.h b/arch/arm64/include/asm/pointer_auth.h index b112a11e9302..592968f0bc22 100644 --- a/arch/arm64/include/asm/pointer_auth.h +++ b/arch/arm64/include/asm/pointer_auth.h @@ -3,12 +3,16 @@ #define __ASM_POINTER_AUTH_H #include +#include #include #include #include #include +#define PR_PAC_ENABLED_KEYS_MASK \ + (PR_PAC_APIAKEY | PR_PAC_APIBKEY | PR_PAC_APDAKEY | PR_PAC_APDBKEY) + #ifdef CONFIG_ARM64_PTR_AUTH /* * Each key is a 128-bit quantity which is split across a pair of 64-bit @@ -34,6 +38,25 @@ struct ptrauth_keys_kernel { struct ptrauth_key apia; }; +#define __ptrauth_key_install_nosync(k, v) \ +do { \ + struct ptrauth_key __pki_v = (v); \ + write_sysreg_s(__pki_v.lo, SYS_ ## k ## KEYLO_EL1); \ + write_sysreg_s(__pki_v.hi, SYS_ ## k ## KEYHI_EL1); \ +} while (0) + +static inline void ptrauth_keys_install_user(struct ptrauth_keys_user *keys) +{ + if (system_supports_address_auth()) { + __ptrauth_key_install_nosync(APIB, keys->apib); + __ptrauth_key_install_nosync(APDA, keys->apda); + __ptrauth_key_install_nosync(APDB, keys->apdb); + } + + if (system_supports_generic_auth()) + __ptrauth_key_install_nosync(APGA, keys->apga); +} + static inline void ptrauth_keys_init_user(struct ptrauth_keys_user *keys) { if (system_supports_address_auth()) { @@ -45,14 +68,9 @@ static inline void ptrauth_keys_init_user(struct ptrauth_keys_user *keys) if (system_supports_generic_auth()) get_random_bytes(&keys->apga, sizeof(keys->apga)); -} -#define __ptrauth_key_install_nosync(k, v) \ -do { \ - struct ptrauth_key __pki_v = (v); \ - write_sysreg_s(__pki_v.lo, SYS_ ## k ## KEYLO_EL1); \ - write_sysreg_s(__pki_v.hi, SYS_ ## k ## KEYHI_EL1); \ -} while (0) + ptrauth_keys_install_user(keys); +} static __always_inline void ptrauth_keys_init_kernel(struct ptrauth_keys_kernel *keys) { @@ -71,6 +89,10 @@ static __always_inline void ptrauth_keys_switch_kernel(struct ptrauth_keys_kerne extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg); +extern int ptrauth_set_enabled_keys(struct task_struct *tsk, unsigned long keys, + unsigned long enabled); +extern int ptrauth_get_enabled_keys(struct task_struct *tsk); + static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr) { return ptrauth_clear_pac(ptr); @@ -85,8 +107,23 @@ static __always_inline void ptrauth_enable(void) isb(); } -#define ptrauth_thread_init_user(tsk) \ - ptrauth_keys_init_user(&(tsk)->thread.keys_user) +#define ptrauth_suspend_exit() \ + ptrauth_keys_install_user(¤t->thread.keys_user) + +#define ptrauth_thread_init_user() \ + do { \ + ptrauth_keys_init_user(¤t->thread.keys_user); \ + \ + /* enable all keys */ \ + if (system_supports_address_auth()) \ + ptrauth_set_enabled_keys(current, \ + PR_PAC_ENABLED_KEYS_MASK, \ + PR_PAC_ENABLED_KEYS_MASK); \ + } while (0) + +#define ptrauth_thread_switch_user(tsk) \ + ptrauth_keys_install_user(&(tsk)->thread.keys_user) + #define ptrauth_thread_init_kernel(tsk) \ ptrauth_keys_init_kernel(&(tsk)->thread.keys_kernel) #define ptrauth_thread_switch_kernel(tsk) \ @@ -95,9 +132,13 @@ static __always_inline void ptrauth_enable(void) #else /* CONFIG_ARM64_PTR_AUTH */ #define ptrauth_enable() #define ptrauth_prctl_reset_keys(tsk, arg) (-EINVAL) +#define ptrauth_set_enabled_keys(tsk, keys, enabled) (-EINVAL) +#define ptrauth_get_enabled_keys(tsk) (-EINVAL) #define ptrauth_strip_insn_pac(lr) (lr) -#define ptrauth_thread_init_user(tsk) +#define ptrauth_suspend_exit() +#define ptrauth_thread_init_user() #define ptrauth_thread_init_kernel(tsk) +#define ptrauth_thread_switch_user(tsk) #define ptrauth_thread_switch_kernel(tsk) #endif /* CONFIG_ARM64_PTR_AUTH */ diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index e1ad8bb0c79d..e85a712f1e3d 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -19,6 +19,12 @@ */ #define NET_IP_ALIGN 0 +#define MTE_CTRL_GCR_USER_EXCL_SHIFT 0 +#define MTE_CTRL_GCR_USER_EXCL_MASK 0xffff + +#define MTE_CTRL_TCF_SYNC (1UL << 16) +#define MTE_CTRL_TCF_ASYNC (1UL << 17) + #ifndef __ASSEMBLY__ #include @@ -156,12 +162,14 @@ struct thread_struct { struct ptrauth_keys_kernel keys_kernel; #endif #ifdef CONFIG_ARM64_MTE - u64 gcr_user_excl; + u64 mte_ctrl; #endif u64 sctlr_user; }; -#define SCTLR_USER_MASK SCTLR_EL1_TCF0_MASK +#define SCTLR_USER_MASK \ + (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | SCTLR_ELx_ENDA | SCTLR_ELx_ENDB | \ + SCTLR_EL1_TCF0_MASK) static inline void arch_thread_struct_whitelist(unsigned long *offset, unsigned long *size) @@ -254,7 +262,7 @@ extern void release_thread(struct task_struct *); unsigned long get_wchan(struct task_struct *p); -void set_task_sctlr_el1(u64 sctlr); +void update_sctlr_el1(u64 sctlr); /* Thread switching */ extern struct task_struct *cpu_switch_to(struct task_struct *prev, @@ -310,6 +318,11 @@ extern void __init minsigstksz_setup(void); /* PR_PAC_RESET_KEYS prctl */ #define PAC_RESET_KEYS(tsk, arg) ptrauth_prctl_reset_keys(tsk, arg) +/* PR_PAC_{SET,GET}_ENABLED_KEYS prctl */ +#define PAC_SET_ENABLED_KEYS(tsk, keys, enabled) \ + ptrauth_set_enabled_keys(tsk, keys, enabled) +#define PAC_GET_ENABLED_KEYS(tsk) ptrauth_get_enabled_keys(tsk) + #ifdef CONFIG_ARM64_TAGGED_ADDR_ABI /* PR_{SET,GET}_TAGGED_ADDR_CTRL prctl */ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg); diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 1093196db31d..2f09c856b6bc 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -610,8 +610,10 @@ #define SCTLR_ELx_TCF_ASYNC (UL(0x2) << SCTLR_ELx_TCF_SHIFT) #define SCTLR_ELx_TCF_MASK (UL(0x3) << SCTLR_ELx_TCF_SHIFT) +#define SCTLR_ELx_ENIA_SHIFT 31 + #define SCTLR_ELx_ITFSB (BIT(37)) -#define SCTLR_ELx_ENIA (BIT(31)) +#define SCTLR_ELx_ENIA (BIT(SCTLR_ELx_ENIA_SHIFT)) #define SCTLR_ELx_ENIB (BIT(30)) #define SCTLR_ELx_ENDA (BIT(27)) #define SCTLR_ELx_EE (BIT(25)) @@ -682,8 +684,7 @@ (SCTLR_ELx_M | SCTLR_ELx_C | SCTLR_ELx_SA | SCTLR_EL1_SA0 | \ SCTLR_EL1_SED | SCTLR_ELx_I | SCTLR_EL1_DZE | SCTLR_EL1_UCT | \ SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN | SCTLR_ELx_ITFSB | \ - SCTLR_ELx_ATA | SCTLR_EL1_ATA0 | ENDIAN_SET_EL1 | SCTLR_EL1_UCI | \ - SCTLR_EL1_RES1) + ENDIAN_SET_EL1 | SCTLR_EL1_UCI | SCTLR_EL1_RES1) /* MAIR_ELx memory attributes (used by Linux) */ #define MAIR_ATTR_DEVICE_nGnRnE UL(0x00) diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h index 631ab1281633..4b4c0dac0e14 100644 --- a/arch/arm64/include/asm/vdso/gettimeofday.h +++ b/arch/arm64/include/asm/vdso/gettimeofday.h @@ -83,11 +83,7 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode, */ isb(); asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory"); - /* - * This isb() is required to prevent that the seq lock is - * speculated.# - */ - isb(); + arch_counter_enforce_ordering(res); return res; } diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index f396d951ee54..93da876a58e6 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -44,12 +44,13 @@ int main(void) #endif BLANK(); DEFINE(THREAD_CPU_CONTEXT, offsetof(struct task_struct, thread.cpu_context)); + DEFINE(THREAD_SCTLR_USER, offsetof(struct task_struct, thread.sctlr_user)); #ifdef CONFIG_ARM64_PTR_AUTH DEFINE(THREAD_KEYS_USER, offsetof(struct task_struct, thread.keys_user)); DEFINE(THREAD_KEYS_KERNEL, offsetof(struct task_struct, thread.keys_kernel)); #endif #ifdef CONFIG_ARM64_MTE - DEFINE(THREAD_GCR_EL1_USER, offsetof(struct task_struct, thread.gcr_user_excl)); + DEFINE(THREAD_MTE_CTRL, offsetof(struct task_struct, thread.mte_ctrl)); #endif BLANK(); DEFINE(S_X0, offsetof(struct pt_regs, regs[0])); @@ -153,10 +154,6 @@ int main(void) #endif #ifdef CONFIG_ARM64_PTR_AUTH DEFINE(PTRAUTH_USER_KEY_APIA, offsetof(struct ptrauth_keys_user, apia)); - DEFINE(PTRAUTH_USER_KEY_APIB, offsetof(struct ptrauth_keys_user, apib)); - DEFINE(PTRAUTH_USER_KEY_APDA, offsetof(struct ptrauth_keys_user, apda)); - DEFINE(PTRAUTH_USER_KEY_APDB, offsetof(struct ptrauth_keys_user, apdb)); - DEFINE(PTRAUTH_USER_KEY_APGA, offsetof(struct ptrauth_keys_user, apga)); DEFINE(PTRAUTH_KERNEL_KEY_APIA, offsetof(struct ptrauth_keys_kernel, apia)); BLANK(); #endif diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index c9711b504e8f..d9e5c16f2037 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1835,6 +1835,9 @@ static void bti_enable(const struct arm64_cpu_capabilities *__unused) #ifdef CONFIG_ARM64_MTE static void cpu_enable_mte(struct arm64_cpu_capabilities const *cap) { + sysreg_clear_set(sctlr_el1, 0, SCTLR_ELx_ATA | SCTLR_EL1_ATA0); + isb(); + /* * Clear the tags in the zero page. This needs to be done via the * linear map which has the Tagged attribute. diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 1deb241eb74f..29c423933e99 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -148,42 +148,46 @@ alternative_cb_end .endm /* Check for MTE asynchronous tag check faults */ - .macro check_mte_async_tcf, tmp, ti_flags + .macro check_mte_async_tcf, tmp, ti_flags, thread_sctlr #ifdef CONFIG_ARM64_MTE .arch_extension lse alternative_if_not ARM64_MTE b 1f alternative_else_nop_endif + /* + * Asynchronous tag check faults are only possible in ASYNC (2) or + * ASYM (3) modes. In each of these modes bit 1 of SCTLR_EL1.TCF0 is + * set, so skip the check if it is unset. + */ + tbz \thread_sctlr, #(SCTLR_EL1_TCF0_SHIFT + 1), 1f mrs_s \tmp, SYS_TFSRE0_EL1 tbz \tmp, #SYS_TFSR_EL1_TF0_SHIFT, 1f /* Asynchronous TCF occurred for TTBR0 access, set the TI flag */ mov \tmp, #_TIF_MTE_ASYNC_FAULT add \ti_flags, tsk, #TSK_TI_FLAGS stset \tmp, [\ti_flags] - msr_s SYS_TFSRE0_EL1, xzr 1: #endif .endm /* Clear the MTE asynchronous tag check faults */ - .macro clear_mte_async_tcf + .macro clear_mte_async_tcf thread_sctlr #ifdef CONFIG_ARM64_MTE alternative_if ARM64_MTE + /* See comment in check_mte_async_tcf above. */ + tbz \thread_sctlr, #(SCTLR_EL1_TCF0_SHIFT + 1), 1f dsb ish msr_s SYS_TFSRE0_EL1, xzr +1: alternative_else_nop_endif #endif .endm - .macro mte_set_gcr, tmp, tmp2 + .macro mte_set_gcr, mte_ctrl, tmp #ifdef CONFIG_ARM64_MTE - /* - * Calculate and set the exclude mask preserving - * the RRND (bit[16]) setting. - */ - mrs_s \tmp2, SYS_GCR_EL1 - bfi \tmp2, \tmp, #0, #16 - msr_s SYS_GCR_EL1, \tmp2 + ubfx \tmp, \mte_ctrl, #MTE_CTRL_GCR_USER_EXCL_SHIFT, #16 + orr \tmp, \tmp, #SYS_GCR_EL1_RRND + msr_s SYS_GCR_EL1, \tmp #endif .endm @@ -195,7 +199,6 @@ alternative_else_nop_endif ldr_l \tmp, gcr_kernel_excl mte_set_gcr \tmp, \tmp2 - isb 1: #endif .endm @@ -205,7 +208,7 @@ alternative_else_nop_endif alternative_if_not ARM64_MTE b 1f alternative_else_nop_endif - ldr \tmp, [\tsk, #THREAD_GCR_EL1_USER] + ldr \tmp, [\tsk, #THREAD_MTE_CTRL] mte_set_gcr \tmp, \tmp2 1: @@ -246,13 +249,48 @@ alternative_else_nop_endif disable_step_tsk x19, x20 /* Check for asynchronous tag check faults in user space */ - check_mte_async_tcf x22, x23 + ldr x0, [tsk, THREAD_SCTLR_USER] + check_mte_async_tcf x22, x23, x0 + +#ifdef CONFIG_ARM64_PTR_AUTH +alternative_if ARM64_HAS_ADDRESS_AUTH + /* + * Enable IA for in-kernel PAC if the task had it disabled. Although + * this could be implemented with an unconditional MRS which would avoid + * a load, this was measured to be slower on Cortex-A75 and Cortex-A76. + * + * Install the kernel IA key only if IA was enabled in the task. If IA + * was disabled on kernel exit then we would have left the kernel IA + * installed so there is no need to install it again. + */ + tbz x0, SCTLR_ELx_ENIA_SHIFT, 1f + __ptrauth_keys_install_kernel_nosync tsk, x20, x22, x23 + b 2f +1: + mrs x0, sctlr_el1 + orr x0, x0, SCTLR_ELx_ENIA + msr sctlr_el1, x0 +2: +alternative_else_nop_endif +#endif + apply_ssbd 1, x22, x23 - ptrauth_keys_install_kernel tsk, x20, x22, x23 - mte_set_kernel_gcr x22, x23 + /* + * Any non-self-synchronizing system register updates required for + * kernel entry should be placed before this point. + */ +alternative_if ARM64_MTE + isb + b 1f +alternative_else_nop_endif +alternative_if ARM64_HAS_ADDRESS_AUTH + isb +alternative_else_nop_endif +1: + scs_load tsk, x20 .else add x21, sp, #S_FRAME_SIZE @@ -367,8 +405,29 @@ alternative_else_nop_endif 3: scs_save tsk, x0 - /* No kernel C function calls after this as user keys are set. */ - ptrauth_keys_install_user tsk, x0, x1, x2 + /* Ignore asynchronous tag check faults in the uaccess routines */ + ldr x0, [tsk, THREAD_SCTLR_USER] + clear_mte_async_tcf x0 + +#ifdef CONFIG_ARM64_PTR_AUTH +alternative_if ARM64_HAS_ADDRESS_AUTH + /* + * IA was enabled for in-kernel PAC. Disable it now if needed, or + * alternatively install the user's IA. All other per-task keys and + * SCTLR bits were updated on task switch. + * + * No kernel C function calls after this. + */ + tbz x0, SCTLR_ELx_ENIA_SHIFT, 1f + __ptrauth_keys_install_user tsk, x0, x1, x2 + b 2f +1: + mrs x0, sctlr_el1 + bic x0, x0, SCTLR_ELx_ENIA + msr sctlr_el1, x0 +2: +alternative_else_nop_endif +#endif mte_set_user_gcr tsk, x0, x1 @@ -784,8 +843,6 @@ SYM_CODE_START_LOCAL(ret_to_user) cbnz x2, work_pending finish_ret_to_user: user_enter_irqoff - /* Ignore asynchronous tag check faults in the uaccess routines */ - clear_mte_async_tcf enable_step_tsk x19, x2 #ifdef CONFIG_GCC_PLUGIN_STACKLEAK bl stackleak_erase diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c index cc071712c6f9..81b7ecb69cd1 100644 --- a/arch/arm64/kernel/idreg-override.c +++ b/arch/arm64/kernel/idreg-override.c @@ -42,6 +42,7 @@ static const struct ftr_set_desc pfr1 __initconst = { .override = &id_aa64pfr1_override, .fields = { { "bt", ID_AA64PFR1_BT_SHIFT }, + { "mte", ID_AA64PFR1_MTE_SHIFT}, {} }, }; @@ -88,6 +89,7 @@ static const struct { { "arm64.nopauth", "id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 " "id_aa64isar1.api=0 id_aa64isar1.apa=0" }, + { "arm64.nomte", "id_aa64pfr1.mte=0" }, { "nokaslr", "kaslr.disabled=1" }, }; diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c index 8da597e41795..50ae1a7435ae 100644 --- a/arch/arm64/kernel/mte.c +++ b/arch/arm64/kernel/mte.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -26,6 +27,8 @@ u64 gcr_kernel_excl __ro_after_init; static bool report_fault_once = true; +static DEFINE_PER_CPU_READ_MOSTLY(u64, mte_tcf_preferred); + #ifdef CONFIG_KASAN_HW_TAGS /* Whether the MTE asynchronous mode is enabled. */ DEFINE_STATIC_KEY_FALSE(mte_async_mode); @@ -197,17 +200,29 @@ static void update_gcr_el1_excl(u64 excl) sysreg_clear_set_s(SYS_GCR_EL1, SYS_GCR_EL1_EXCL_MASK, excl); } -static void set_gcr_el1_excl(u64 excl) +static void mte_update_sctlr_user(struct task_struct *task) { - current->thread.gcr_user_excl = excl; - /* - * SYS_GCR_EL1 will be set to current->thread.gcr_user_excl value - * by mte_set_user_gcr() in kernel_exit, + * This must be called with preemption disabled and can only be called + * on the current or next task since the CPU must match where the thread + * is going to run. The caller is responsible for calling + * update_sctlr_el1() later in the same preemption disabled block. */ + unsigned long sctlr = task->thread.sctlr_user; + unsigned long mte_ctrl = task->thread.mte_ctrl; + unsigned long pref, resolved_mte_tcf; + + pref = __this_cpu_read(mte_tcf_preferred); + resolved_mte_tcf = (mte_ctrl & pref) ? pref : mte_ctrl; + sctlr &= ~SCTLR_EL1_TCF0_MASK; + if (resolved_mte_tcf & MTE_CTRL_TCF_ASYNC) + sctlr |= SCTLR_EL1_TCF0_ASYNC; + else if (resolved_mte_tcf & MTE_CTRL_TCF_SYNC) + sctlr |= SCTLR_EL1_TCF0_SYNC; + task->thread.sctlr_user = sctlr; } -void flush_mte_state(void) +void mte_thread_init_user(void) { if (!system_supports_mte()) return; @@ -216,15 +231,14 @@ void flush_mte_state(void) dsb(ish); write_sysreg_s(0, SYS_TFSRE0_EL1); clear_thread_flag(TIF_MTE_ASYNC_FAULT); - /* disable tag checking */ - set_task_sctlr_el1((current->thread.sctlr_user & ~SCTLR_EL1_TCF0_MASK) | - SCTLR_EL1_TCF0_NONE); - /* reset tag generation mask */ - set_gcr_el1_excl(SYS_GCR_EL1_EXCL_MASK); + /* disable tag checking and reset tag generation mask */ + set_mte_ctrl(current, 0); } void mte_thread_switch(struct task_struct *next) { + mte_update_sctlr_user(next); + /* * Check if an async tag exception occurred at EL1. * @@ -262,33 +276,23 @@ void mte_suspend_exit(void) long set_mte_ctrl(struct task_struct *task, unsigned long arg) { - u64 sctlr = task->thread.sctlr_user & ~SCTLR_EL1_TCF0_MASK; - u64 gcr_excl = ~((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT) & - SYS_GCR_EL1_EXCL_MASK; + u64 mte_ctrl = (~((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT) & + SYS_GCR_EL1_EXCL_MASK) << MTE_CTRL_GCR_USER_EXCL_SHIFT; if (!system_supports_mte()) return 0; - switch (arg & PR_MTE_TCF_MASK) { - case PR_MTE_TCF_NONE: - sctlr |= SCTLR_EL1_TCF0_NONE; - break; - case PR_MTE_TCF_SYNC: - sctlr |= SCTLR_EL1_TCF0_SYNC; - break; - case PR_MTE_TCF_ASYNC: - sctlr |= SCTLR_EL1_TCF0_ASYNC; - break; - default: - return -EINVAL; - } + if (arg & PR_MTE_TCF_ASYNC) + mte_ctrl |= MTE_CTRL_TCF_ASYNC; + if (arg & PR_MTE_TCF_SYNC) + mte_ctrl |= MTE_CTRL_TCF_SYNC; - if (task != current) { - task->thread.sctlr_user = sctlr; - task->thread.gcr_user_excl = gcr_excl; - } else { - set_task_sctlr_el1(sctlr); - set_gcr_el1_excl(gcr_excl); + task->thread.mte_ctrl = mte_ctrl; + if (task == current) { + preempt_disable(); + mte_update_sctlr_user(task); + update_sctlr_el1(task->thread.sctlr_user); + preempt_enable(); } return 0; @@ -297,24 +301,18 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg) long get_mte_ctrl(struct task_struct *task) { unsigned long ret; - u64 incl = ~task->thread.gcr_user_excl & SYS_GCR_EL1_EXCL_MASK; + u64 mte_ctrl = task->thread.mte_ctrl; + u64 incl = (~mte_ctrl >> MTE_CTRL_GCR_USER_EXCL_SHIFT) & + SYS_GCR_EL1_EXCL_MASK; if (!system_supports_mte()) return 0; ret = incl << PR_MTE_TAG_SHIFT; - - switch (task->thread.sctlr_user & SCTLR_EL1_TCF0_MASK) { - case SCTLR_EL1_TCF0_NONE: - ret |= PR_MTE_TCF_NONE; - break; - case SCTLR_EL1_TCF0_SYNC: - ret |= PR_MTE_TCF_SYNC; - break; - case SCTLR_EL1_TCF0_ASYNC: + if (mte_ctrl & MTE_CTRL_TCF_ASYNC) ret |= PR_MTE_TCF_ASYNC; - break; - } + if (mte_ctrl & MTE_CTRL_TCF_SYNC) + ret |= PR_MTE_TCF_SYNC; return ret; } @@ -453,3 +451,54 @@ int mte_ptrace_copy_tags(struct task_struct *child, long request, return ret; } + +static ssize_t mte_tcf_preferred_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + switch (per_cpu(mte_tcf_preferred, dev->id)) { + case MTE_CTRL_TCF_ASYNC: + return sysfs_emit(buf, "async\n"); + case MTE_CTRL_TCF_SYNC: + return sysfs_emit(buf, "sync\n"); + default: + return sysfs_emit(buf, "???\n"); + } +} + +static ssize_t mte_tcf_preferred_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + u64 tcf; + + if (sysfs_streq(buf, "async")) + tcf = MTE_CTRL_TCF_ASYNC; + else if (sysfs_streq(buf, "sync")) + tcf = MTE_CTRL_TCF_SYNC; + else + return -EINVAL; + + device_lock(dev); + per_cpu(mte_tcf_preferred, dev->id) = tcf; + device_unlock(dev); + + return count; +} +static DEVICE_ATTR_RW(mte_tcf_preferred); + +static int register_mte_tcf_preferred_sysctl(void) +{ + unsigned int cpu; + + if (!system_supports_mte()) + return 0; + + for_each_possible_cpu(cpu) { + per_cpu(mte_tcf_preferred, cpu) = MTE_CTRL_TCF_ASYNC; + device_create_file(get_cpu_device(cpu), + &dev_attr_mte_tcf_preferred); + } + + return 0; +} +subsys_initcall(register_mte_tcf_preferred_sysctl); diff --git a/arch/arm64/kernel/pointer_auth.c b/arch/arm64/kernel/pointer_auth.c index adb955fd9bdd..2708b620b4ae 100644 --- a/arch/arm64/kernel/pointer_auth.c +++ b/arch/arm64/kernel/pointer_auth.c @@ -43,6 +43,71 @@ int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg) get_random_bytes(&keys->apdb, sizeof(keys->apdb)); if (arg & PR_PAC_APGAKEY) get_random_bytes(&keys->apga, sizeof(keys->apga)); + ptrauth_keys_install_user(keys); return 0; } + +static u64 arg_to_enxx_mask(unsigned long arg) +{ + u64 sctlr_enxx_mask = 0; + + WARN_ON(arg & ~PR_PAC_ENABLED_KEYS_MASK); + if (arg & PR_PAC_APIAKEY) + sctlr_enxx_mask |= SCTLR_ELx_ENIA; + if (arg & PR_PAC_APIBKEY) + sctlr_enxx_mask |= SCTLR_ELx_ENIB; + if (arg & PR_PAC_APDAKEY) + sctlr_enxx_mask |= SCTLR_ELx_ENDA; + if (arg & PR_PAC_APDBKEY) + sctlr_enxx_mask |= SCTLR_ELx_ENDB; + return sctlr_enxx_mask; +} + +int ptrauth_set_enabled_keys(struct task_struct *tsk, unsigned long keys, + unsigned long enabled) +{ + u64 sctlr; + + if (!system_supports_address_auth()) + return -EINVAL; + + if (is_compat_thread(task_thread_info(tsk))) + return -EINVAL; + + if ((keys & ~PR_PAC_ENABLED_KEYS_MASK) || (enabled & ~keys)) + return -EINVAL; + + preempt_disable(); + sctlr = tsk->thread.sctlr_user; + sctlr &= ~arg_to_enxx_mask(keys); + sctlr |= arg_to_enxx_mask(enabled); + tsk->thread.sctlr_user = sctlr; + if (tsk == current) + update_sctlr_el1(sctlr); + preempt_enable(); + + return 0; +} + +int ptrauth_get_enabled_keys(struct task_struct *tsk) +{ + int retval = 0; + + if (!system_supports_address_auth()) + return -EINVAL; + + if (is_compat_thread(task_thread_info(tsk))) + return -EINVAL; + + if (tsk->thread.sctlr_user & SCTLR_ELx_ENIA) + retval |= PR_PAC_APIAKEY; + if (tsk->thread.sctlr_user & SCTLR_ELx_ENIB) + retval |= PR_PAC_APIBKEY; + if (tsk->thread.sctlr_user & SCTLR_ELx_ENDA) + retval |= PR_PAC_APDAKEY; + if (tsk->thread.sctlr_user & SCTLR_ELx_ENDB) + retval |= PR_PAC_APDBKEY; + + return retval; +} diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 365d30301ac7..0909e46f2056 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -339,7 +339,6 @@ void flush_thread(void) tls_thread_flush(); flush_ptrace_hw_breakpoint(current); flush_tagged_addr_state(); - flush_mte_state(); } void release_thread(struct task_struct *dead_task) @@ -540,27 +539,24 @@ static void erratum_1418040_thread_switch(struct task_struct *prev, write_sysreg(val, cntkctl_el1); } -static void update_sctlr_el1(u64 sctlr) +/* + * __switch_to() checks current->thread.sctlr_user as an optimisation. Therefore + * this function must be called with preemption disabled and the update to + * sctlr_user must be made in the same preemption disabled block so that + * __switch_to() does not see the variable update before the SCTLR_EL1 one. + */ +void update_sctlr_el1(u64 sctlr) { - sysreg_clear_set(sctlr_el1, SCTLR_USER_MASK, sctlr); + /* + * EnIA must not be cleared while in the kernel as this is necessary for + * in-kernel PAC. It will be cleared on kernel exit if needed. + */ + sysreg_clear_set(sctlr_el1, SCTLR_USER_MASK & ~SCTLR_ELx_ENIA, sctlr); /* ISB required for the kernel uaccess routines when setting TCF0. */ isb(); } -void set_task_sctlr_el1(u64 sctlr) -{ - /* - * __switch_to() checks current->thread.sctlr as an - * optimisation. Disable preemption so that it does not see - * the variable update before the SCTLR_EL1 one. - */ - preempt_disable(); - current->thread.sctlr_user = sctlr; - update_sctlr_el1(sctlr); - preempt_enable(); -} - /* * Thread switching. */ @@ -577,6 +573,7 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, uao_thread_switch(next); ssbs_thread_switch(next); erratum_1418040_thread_switch(prev, next); + ptrauth_thread_switch_user(next); /* * vendor hook is needed before the dsb(), * because MPAM is related to cache maintenance. @@ -668,7 +665,8 @@ void arch_setup_new_exec(void) } current->mm->context.flags = mmflags; - ptrauth_thread_init_user(current); + ptrauth_thread_init_user(); + mte_thread_init_user(); if (task_spec_ssb_noexec(current)) { arch_prctl_spec_ctrl_set(current, PR_SPEC_STORE_BYPASS, diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 1d75471979cb..7d84854bc0e8 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -908,6 +908,38 @@ static int pac_mask_get(struct task_struct *target, return membuf_write(&to, &uregs, sizeof(uregs)); } +static int pac_enabled_keys_get(struct task_struct *target, + const struct user_regset *regset, + struct membuf to) +{ + long enabled_keys = ptrauth_get_enabled_keys(target); + + if (IS_ERR_VALUE(enabled_keys)) + return enabled_keys; + + return membuf_write(&to, &enabled_keys, sizeof(enabled_keys)); +} + +static int pac_enabled_keys_set(struct task_struct *target, + const struct user_regset *regset, + unsigned int pos, unsigned int count, + const void *kbuf, const void __user *ubuf) +{ + int ret; + long enabled_keys = ptrauth_get_enabled_keys(target); + + if (IS_ERR_VALUE(enabled_keys)) + return enabled_keys; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &enabled_keys, 0, + sizeof(long)); + if (ret) + return ret; + + return ptrauth_set_enabled_keys(target, PR_PAC_ENABLED_KEYS_MASK, + enabled_keys); +} + #ifdef CONFIG_CHECKPOINT_RESTORE static __uint128_t pac_key_to_user(const struct ptrauth_key *key) { @@ -1073,6 +1105,7 @@ enum aarch64_regset { #endif #ifdef CONFIG_ARM64_PTR_AUTH REGSET_PAC_MASK, + REGSET_PAC_ENABLED_KEYS, #ifdef CONFIG_CHECKPOINT_RESTORE REGSET_PACA_KEYS, REGSET_PACG_KEYS, @@ -1159,6 +1192,14 @@ static const struct user_regset aarch64_regsets[] = { .regset_get = pac_mask_get, /* this cannot be set dynamically */ }, + [REGSET_PAC_ENABLED_KEYS] = { + .core_note_type = NT_ARM_PAC_ENABLED_KEYS, + .n = 1, + .size = sizeof(long), + .align = sizeof(long), + .regset_get = pac_enabled_keys_get, + .set = pac_enabled_keys_set, + }, #ifdef CONFIG_CHECKPOINT_RESTORE [REGSET_PACA_KEYS] = { .core_note_type = NT_ARM_PACA_KEYS, diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 3e42884f1591..22c65fbbf4c5 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -1005,6 +1005,10 @@ void __init set_smp_ipi_range(int ipi_base, int n) ipi_desc[i] = irq_to_desc(ipi_base + i); irq_set_status_flags(ipi_base + i, IRQ_HIDDEN); + + /* The recheduling IPI is special... */ + if (i == IPI_RESCHEDULE) + __irq_modify_status(ipi_base + i, 0, IRQ_RAW, ~0); } ipi_irq_base = ipi_base; diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index adf86a26e252..1e8dc6f7d178 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -75,8 +75,9 @@ void notrace __cpu_suspend_exit(void) */ spectre_v4_enable_mitigation(NULL); - /* Restore additional MTE-specific configuration */ + /* Restore additional feature-specific configuration */ mte_suspend_exit(); + ptrauth_suspend_exit(); } /* diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index f86d781e7180..51cbe394075d 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -181,6 +181,8 @@ SECTIONS /* everything from this point to __init_begin will be marked RO NX */ RO_DATA(PAGE_SIZE) + HYPERVISOR_DATA_SECTIONS + idmap_pg_dir = .; . += IDMAP_DIR_SIZE; idmap_pg_end = .; @@ -262,8 +264,6 @@ SECTIONS _sdata = .; RW_DATA(L1_CACHE_BYTES, PAGE_SIZE, THREAD_ALIGN) - HYPERVISOR_DATA_SECTIONS - /* * Data written with the MMU off but read with the MMU on requires * cache lines to be invalidated, discarding up to a Cache Writeback diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 93f21e4a9b1e..4705db5c81d3 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -416,10 +417,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (vcpu_has_ptrauth(vcpu)) vcpu_ptrauth_disable(vcpu); + kvm_arch_vcpu_load_debug_state_flags(vcpu); } void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) { + kvm_arch_vcpu_put_debug_state_flags(vcpu); kvm_arch_vcpu_put_fp(vcpu); if (has_vhe()) kvm_vcpu_put_sysregs_vhe(vcpu); @@ -1943,6 +1946,12 @@ static int finalize_hyp_mode(void) if (ret) return ret; + /* + * Exclude HYP BSS from kmemleak so that it doesn't get peeked + * at, which would end badly once the section is inaccessible. + * None of other sections should ever be introspected. + */ + kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start); ret = pkvm_mark_hyp_section(__hyp_bss); if (ret) return ret; diff --git a/arch/arm64/kvm/debug.c b/arch/arm64/kvm/debug.c index 2484b2cca74b..d2b120ec577f 100644 --- a/arch/arm64/kvm/debug.c +++ b/arch/arm64/kvm/debug.c @@ -141,7 +141,13 @@ void kvm_arm_reset_debug_ptr(struct kvm_vcpu *vcpu) * @vcpu: the vcpu pointer * * This is called before each entry into the hypervisor to setup any - * debug related registers. + * debug related registers. Currently this just ensures we will trap + * access to: + * - Performance monitors (MDCR_EL2_TPM/MDCR_EL2_TPMCR) + * - Debug ROM Address (MDCR_EL2_TDRA) + * - OS related registers (MDCR_EL2_TDOSA) + * - Statistical profiler (MDCR_EL2_TPMS/MDCR_EL2_E2PB) + * - Self-hosted Trace (MDCR_EL2_TTRF/MDCR_EL2_E2TB) * * Additionally, KVM only traps guest accesses to the debug registers if * the guest is not actively using them (see the KVM_ARM64_DEBUG_DIRTY @@ -263,3 +269,32 @@ void kvm_arm_clear_debug(struct kvm_vcpu *vcpu) } } } + +void kvm_arch_vcpu_load_debug_state_flags(struct kvm_vcpu *vcpu) +{ + u64 dfr0; + + /* For VHE, there is nothing to do */ + if (has_vhe()) + return; + + dfr0 = read_sysreg(id_aa64dfr0_el1); + /* + * If SPE is present on this CPU and is available at current EL, + * we may need to check if the host state needs to be saved. + */ + if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_PMSVER_SHIFT) && + !(read_sysreg_s(SYS_PMBIDR_EL1) & BIT(SYS_PMBIDR_EL1_P_SHIFT))) + vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_SPE; + + /* Check if we have TRBE implemented and available at the host */ + if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_TRBE_SHIFT) && + !(read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_PROG)) + vcpu->arch.flags |= KVM_ARM64_DEBUG_STATE_SAVE_TRBE; +} + +void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu) +{ + vcpu->arch.flags &= ~(KVM_ARM64_DEBUG_STATE_SAVE_SPE | + KVM_ARM64_DEBUG_STATE_SAVE_TRBE); +} diff --git a/arch/arm64/kvm/hyp/nvhe/debug-sr.c b/arch/arm64/kvm/hyp/nvhe/debug-sr.c index 9499e18dd28f..7d3f25868cae 100644 --- a/arch/arm64/kvm/hyp/nvhe/debug-sr.c +++ b/arch/arm64/kvm/hyp/nvhe/debug-sr.c @@ -21,17 +21,11 @@ static void __debug_save_spe(u64 *pmscr_el1) /* Clear pmscr in case of early return */ *pmscr_el1 = 0; - /* SPE present on this CPU? */ - if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1), - ID_AA64DFR0_PMSVER_SHIFT)) - return; - - /* Yes; is it owned by EL3? */ - reg = read_sysreg_s(SYS_PMBIDR_EL1); - if (reg & BIT(SYS_PMBIDR_EL1_P_SHIFT)) - return; - - /* No; is the host actually using the thing? */ + /* + * At this point, we know that this CPU implements + * SPE and is available to the host. + * Check if the host is actually using it ? + */ reg = read_sysreg_s(SYS_PMBLIMITR_EL1); if (!(reg & BIT(SYS_PMBLIMITR_EL1_E_SHIFT))) return; @@ -60,18 +54,8 @@ static void __debug_restore_spe(u64 pmscr_el1) static void __debug_save_trace(u64 *trfcr_el1) { - *trfcr_el1 = 0; - /* Check if we have TRBE */ - if (!cpuid_feature_extract_unsigned_field(read_sysreg(id_aa64dfr0_el1), - ID_AA64DFR0_TRBE_SHIFT)) - return; - - /* Check we can access the TRBE */ - if ((read_sysreg_s(SYS_TRBIDR_EL1) & TRBIDR_PROG)) - return; - /* Check if the TRBE is enabled */ if (!(read_sysreg_s(SYS_TRBLIMITR_EL1) & TRBLIMITR_ENABLE)) return; @@ -100,9 +84,11 @@ static void __debug_restore_trace(u64 trfcr_el1) void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu) { /* Disable and flush SPE data generation */ - __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); + if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE) + __debug_save_spe(&vcpu->arch.host_debug_state.pmscr_el1); /* Disable and flush Self-Hosted Trace generation */ - __debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1); + if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE) + __debug_save_trace(&vcpu->arch.host_debug_state.trfcr_el1); } void __debug_switch_to_guest(struct kvm_vcpu *vcpu) @@ -112,8 +98,10 @@ void __debug_switch_to_guest(struct kvm_vcpu *vcpu) void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu) { - __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); - __debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1); + if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_SPE) + __debug_restore_spe(vcpu->arch.host_debug_state.pmscr_el1); + if (vcpu->arch.flags & KVM_ARM64_DEBUG_STATE_SAVE_TRBE) + __debug_restore_trace(vcpu->arch.host_debug_state.trfcr_el1); } void __debug_switch_to_host(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index 9cc4c9ebfd8f..e9f6ea704d07 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c @@ -193,12 +193,11 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu) __sysreg_save_state_nvhe(host_ctxt); /* - * For nVHE, we must save and disable any SPE - * buffers, as the translation regime is going - * to be loaded with that of the guest. And we must - * save host context for SPE, before we change the - * ownership to EL2 (via MDCR_EL2_E2PB == 0) and before - * we load guest Stage1. + * We must flush and disable the SPE buffer for nVHE, as + * the translation regime(EL1&0) is going to be loaded with + * that of the guest. And we must do this before we change the + * translation regime to EL2 (via MDCR_EL2_E2PB == 0) and + * before we load guest Stage1. */ __debug_save_host_buffers_nvhe(vcpu); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index cdd073d8ea32..47b05731b16c 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1472,6 +1472,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_GCR_EL1), undef_access }, { SYS_DESC(SYS_ZCR_EL1), NULL, reset_val, ZCR_EL1, 0, .visibility = sve_visibility }, + { SYS_DESC(SYS_TRFCR_EL1), undef_access }, { SYS_DESC(SYS_TTBR0_EL1), access_vm_reg, reset_unknown, TTBR0_EL1 }, { SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 }, { SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 }, diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S index cceed41bba15..ebb6337faaf9 100644 --- a/arch/arm64/lib/mte.S +++ b/arch/arm64/lib/mte.S @@ -36,6 +36,26 @@ SYM_FUNC_START(mte_clear_page_tags) ret SYM_FUNC_END(mte_clear_page_tags) +/* + * Zero the page and tags at the same time + * + * Parameters: + * x0 - address to the beginning of the page + */ +SYM_FUNC_START(mte_zero_clear_page_tags) + mrs x1, dczid_el0 + and w1, w1, #0xf + mov x2, #4 + lsl x1, x2, x1 + and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag + +1: dc gzva, x0 + add x0, x0, x1 + tst x0, #(PAGE_SIZE - 1) + b.ne 1b + ret +SYM_FUNC_END(mte_zero_clear_page_tags) + /* * Copy the tags from the source page to the destination one * x0 - address of the destination page diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 3e8dfa52b2c4..37806735f722 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -968,3 +968,29 @@ void do_debug_exception(unsigned long addr_if_watchpoint, unsigned int esr, debug_exception_exit(regs); } NOKPROBE_SYMBOL(do_debug_exception); + +/* + * Used during anonymous page fault handling. + */ +struct page *alloc_zeroed_user_highpage_movable(struct vm_area_struct *vma, + unsigned long vaddr) +{ + gfp_t flags = GFP_HIGHUSER_MOVABLE | __GFP_ZERO | __GFP_CMA; + + /* + * If the page is mapped with PROT_MTE, initialise the tags at the + * point of allocation and page zeroing as this is usually faster than + * separate DC ZVA and STGM. + */ + if (vma->vm_flags & VM_MTE) + flags |= __GFP_ZEROTAGS; + + return alloc_page_vma(flags, vma, vaddr); +} + +void tag_clear_highpage(struct page *page) +{ + mte_zero_clear_page_tags(page_address(page)); + page_kasan_tag_reset(page); + set_bit(PG_mte_tagged, &page->flags); +} diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index e750859c8c07..715c0f9b54b5 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -46,9 +46,13 @@ #endif #ifdef CONFIG_KASAN_HW_TAGS -#define TCR_KASAN_HW_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1 +#define TCR_MTE_FLAGS SYS_TCR_EL1_TCMA1 | TCR_TBI1 | TCR_TBID1 #else -#define TCR_KASAN_HW_FLAGS 0 +/* + * The mte_zero_clear_page_tags() implementation uses DC GZVA, which relies on + * TBI being enabled at EL1. + */ +#define TCR_MTE_FLAGS TCR_TBI1 | TCR_TBID1 #endif /* @@ -462,7 +466,7 @@ SYM_FUNC_START(__cpu_setup) msr_s SYS_TFSRE0_EL1, xzr /* set the TCR_EL1 bits */ - mov_q mte_tcr, TCR_KASAN_HW_FLAGS + mov_q mte_tcr, TCR_MTE_FLAGS 1: #endif msr mair_el1, x5 diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 75b49418c89e..c824dc6acea4 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -199,8 +199,9 @@ endif KBUILD_LDFLAGS += -m elf_$(UTS_MACHINE) ifdef CONFIG_LTO_CLANG -KBUILD_LDFLAGS += -plugin-opt=-code-model=kernel \ - -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8) +ifeq ($(shell test $(CONFIG_LLD_VERSION) -lt 130000; echo $$?),0) +KBUILD_LDFLAGS += -plugin-opt=-stack-alignment=$(if $(CONFIG_X86_32),4,8) +endif endif ifdef CONFIG_X86_NEED_RELOCS diff --git a/arch/x86/OWNERS b/arch/x86/OWNERS deleted file mode 100644 index ae2c29f6c3b7..000000000000 --- a/arch/x86/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/arch/x86/OWNERS diff --git a/arch/x86/configs/gki_defconfig b/arch/x86/configs/gki_defconfig index 70f2af205cbf..9656e18e7ec2 100644 --- a/arch/x86/configs/gki_defconfig +++ b/arch/x86/configs/gki_defconfig @@ -17,6 +17,7 @@ CONFIG_IKHEADERS=y CONFIG_UCLAMP_TASK=y CONFIG_UCLAMP_BUCKETS_COUNT=20 CONFIG_CGROUPS=y +CONFIG_MEMCG=y CONFIG_BLK_CGROUP=y CONFIG_CGROUP_SCHED=y CONFIG_UCLAMP_TASK_GROUP=y @@ -51,9 +52,10 @@ CONFIG_X86_X2APIC=y CONFIG_HYPERVISOR_GUEST=y CONFIG_PARAVIRT=y CONFIG_NR_CPUS=32 +# CONFIG_X86_MCE is not set CONFIG_EFI=y CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="stack_depot_disable=on" +CONFIG_CMDLINE="stack_depot_disable=on cgroup_disable=pressure cgroup.memory=nokmem" CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=0 # CONFIG_PM_WAKELOCKS_GC is not set @@ -73,6 +75,7 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SCMVERSION=y +CONFIG_BLK_CGROUP_IOCOST=y CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y CONFIG_IOSCHED_BFQ=y @@ -232,7 +235,9 @@ CONFIG_NET_ACT_GACT=y CONFIG_NET_ACT_MIRRED=y CONFIG_NET_ACT_SKBEDIT=y CONFIG_VSOCKETS=y +CONFIG_CGROUP_NET_PRIO=y CONFIG_BPF_JIT=y +CONFIG_CAN=y CONFIG_BT=y CONFIG_BT_RFCOMM=y CONFIG_BT_RFCOMM_TTY=y @@ -242,16 +247,13 @@ CONFIG_BT_HCIUART=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_BCM=y CONFIG_BT_HCIUART_QCA=y -CONFIG_CFG80211=y -CONFIG_NL80211_TESTMODE=y -# CONFIG_CFG80211_DEFAULT_PS is not set -# CONFIG_CFG80211_CRDA_SUPPORT is not set -CONFIG_MAC80211=y CONFIG_RFKILL=y +CONFIG_NFC=y CONFIG_PCI=y CONFIG_PCIEPORTBUS=y CONFIG_PCIEAER=y CONFIG_PCI_MSI=y +CONFIG_PCI_IOV=y CONFIG_PCIE_DW_PLAT_EP=y CONFIG_PCI_ENDPOINT=y CONFIG_FW_LOADER_USER_HELPER=y @@ -273,6 +275,7 @@ CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_DWC_TC_PLATFORM=y CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFS_CRYPTO=y +CONFIG_SCSI_UFS_HPB=y CONFIG_MD=y CONFIG_BLK_DEV_DM=y CONFIG_DM_CRYPT=y @@ -358,7 +361,6 @@ CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_CPU_THERMAL=y CONFIG_DEVFREQ_THERMAL=y CONFIG_THERMAL_EMULATION=y -# CONFIG_X86_PKG_TEMP_THERMAL is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y CONFIG_MFD_SYSCON=y @@ -390,7 +392,6 @@ CONFIG_SND=y CONFIG_SND_HRTIMER=y CONFIG_SND_DYNAMIC_MINORS=y # CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_VERBOSE_PROCFS is not set # CONFIG_SND_DRIVERS is not set CONFIG_SND_USB_AUDIO=y CONFIG_SND_SOC=y @@ -422,6 +423,7 @@ CONFIG_USB_HIDDEV=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_ACM=y CONFIG_USB_STORAGE=y @@ -601,7 +603,6 @@ CONFIG_UBSAN_LOCAL_BOUNDS=y # CONFIG_UBSAN_MISC is not set CONFIG_PAGE_OWNER=y CONFIG_PAGE_PINNER=y -CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_KFENCE=y CONFIG_KFENCE_SAMPLE_INTERVAL=500 diff --git a/block/Kconfig b/block/Kconfig index e657e2bd8059..aabfb8588e9d 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -133,6 +133,13 @@ config BLK_WBT dynamically on an algorithm loosely based on CoDel, factoring in the realtime performance of the disk. +config BLK_WBT_MQ + bool "Enable writeback throttling by default" + default y + depends on BLK_WBT + help + Enable writeback throttling by default for request-based block devices. + config BLK_CGROUP_IOLATENCY bool "Enable support for latency based cgroup IO protection" depends on BLK_CGROUP=y @@ -155,12 +162,14 @@ config BLK_CGROUP_IOCOST distributes IO capacity between different groups based on their share of the overall weight distribution. -config BLK_WBT_MQ - bool "Multiqueue writeback throttling" - default y - depends on BLK_WBT +config BLK_CGROUP_IOPRIO + bool "Cgroup I/O controller for assigning an I/O priority class" + depends on BLK_CGROUP help - Enable writeback throttling by default on multiqueue devices. + Enable the .prio interface for assigning an I/O priority class to + requests. The I/O priority class affects the order in which an I/O + scheduler and block devices process requests. Only some I/O schedulers + and some block devices support I/O priorities. config BLK_DEBUG_FS bool "Block layer debugging information in debugfs" diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched index 2f2158e05a91..64053d67a97b 100644 --- a/block/Kconfig.iosched +++ b/block/Kconfig.iosched @@ -9,6 +9,12 @@ config MQ_IOSCHED_DEADLINE help MQ version of the deadline IO scheduler. +config MQ_IOSCHED_DEADLINE_CGROUP + tristate + default y + depends on MQ_IOSCHED_DEADLINE + depends on BLK_CGROUP + config MQ_IOSCHED_KYBER tristate "Kyber I/O scheduler" default y diff --git a/block/Makefile b/block/Makefile index 8d841f5f986f..b9db5d4edfc8 100644 --- a/block/Makefile +++ b/block/Makefile @@ -17,9 +17,12 @@ obj-$(CONFIG_BLK_DEV_BSGLIB) += bsg-lib.o obj-$(CONFIG_BLK_CGROUP) += blk-cgroup.o obj-$(CONFIG_BLK_CGROUP_RWSTAT) += blk-cgroup-rwstat.o obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o +obj-$(CONFIG_BLK_CGROUP_IOPRIO) += blk-ioprio.o obj-$(CONFIG_BLK_CGROUP_IOLATENCY) += blk-iolatency.o obj-$(CONFIG_BLK_CGROUP_IOCOST) += blk-iocost.o obj-$(CONFIG_MQ_IOSCHED_DEADLINE) += mq-deadline.o +mq-deadline-y += mq-deadline-main.o +mq-deadline-$(CONFIG_MQ_IOSCHED_DEADLINE_CGROUP)+= mq-deadline-cgroup.o obj-$(CONFIG_MQ_IOSCHED_KYBER) += kyber-iosched.o bfq-y := bfq-iosched.o bfq-wf2q.o bfq-cgroup.o obj-$(CONFIG_IOSCHED_BFQ) += bfq.o diff --git a/block/OWNERS b/block/OWNERS deleted file mode 100644 index 7786d734d5c6..000000000000 --- a/block/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/block/OWNERS diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index c91dca641eb4..5f1b5f77826a 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -4499,7 +4499,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd) bfqq = bfqq->bic->bfqq[0]; else if (bfq_bfqq_has_waker(bfqq) && bfq_bfqq_busy(bfqq->waker_bfqq) && - bfqq->next_rq && + bfqq->waker_bfqq->next_rq && bfq_serv_to_charge(bfqq->waker_bfqq->next_rq, bfqq->waker_bfqq) <= bfq_bfqq_budget_left(bfqq->waker_bfqq) @@ -4640,9 +4640,6 @@ static bool bfq_has_work(struct blk_mq_hw_ctx *hctx) { struct bfq_data *bfqd = hctx->queue->elevator->elevator_data; - if (!atomic_read(&hctx->elevator_queued)) - return false; - /* * Avoiding lock: a race on bfqd->busy_queues should cause at * most a call to dispatch for nothing @@ -5557,7 +5554,6 @@ static void bfq_insert_requests(struct blk_mq_hw_ctx *hctx, rq = list_first_entry(list, struct request, queuelist); list_del_init(&rq->queuelist); bfq_insert_request(hctx, rq, at_head); - atomic_inc(&hctx->elevator_queued); } } @@ -5925,7 +5921,6 @@ static void bfq_finish_requeue_request(struct request *rq) bfq_completed_request(bfqq, bfqd); bfq_finish_requeue_request_body(bfqq); - atomic_dec(&rq->mq_hctx->elevator_queued); spin_unlock_irqrestore(&bfqd->lock, flags); } else { diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index f13688c4b931..e798d196ac36 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -31,6 +31,7 @@ #include #include #include "blk.h" +#include "blk-ioprio.h" #define MAX_KEY_LEN 100 @@ -1181,15 +1182,18 @@ int blkcg_init_queue(struct request_queue *q) if (preloaded) radix_tree_preload_end(); + ret = blk_iolatency_init(q); + if (ret) + goto err_destroy_all; + + ret = blk_ioprio_init(q); + if (ret) + goto err_destroy_all; + ret = blk_throtl_init(q); if (ret) goto err_destroy_all; - ret = blk_iolatency_init(q); - if (ret) { - blk_throtl_exit(q); - goto err_destroy_all; - } return 0; err_destroy_all: diff --git a/block/blk-core.c b/block/blk-core.c index 2d53e2ff48ff..a00bce9f46d8 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -441,8 +440,7 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) * responsible for ensuring that that counter is * globally visible before the queue is unfrozen. */ - if ((pm && queue_rpm_status(q) != RPM_SUSPENDED) || - !blk_queue_pm_only(q)) { + if (pm || !blk_queue_pm_only(q)) { success = true; } else { percpu_ref_put(&q->q_usage_counter); @@ -467,7 +465,8 @@ int blk_queue_enter(struct request_queue *q, blk_mq_req_flags_t flags) wait_event(q->mq_freeze_wq, (!q->mq_freeze_depth && - blk_pm_resume_queue(pm, q)) || + (pm || (blk_pm_request_resume(q), + !blk_queue_pm_only(q)))) || blk_queue_dying(q)); if (blk_queue_dying(q)) return -ENODEV; diff --git a/block/blk-ioprio.c b/block/blk-ioprio.c new file mode 100644 index 000000000000..332a07761bf8 --- /dev/null +++ b/block/blk-ioprio.c @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Block rq-qos policy for assigning an I/O priority class to requests. + * + * Using an rq-qos policy for assigning I/O priority class has two advantages + * over using the ioprio_set() system call: + * + * - This policy is cgroup based so it has all the advantages of cgroups. + * - While ioprio_set() does not affect page cache writeback I/O, this rq-qos + * controller affects page cache writeback I/O for filesystems that support + * assiociating a cgroup with writeback I/O. See also + * Documentation/admin-guide/cgroup-v2.rst. + */ + +#include +#include +#include +#include +#include +#include "blk-ioprio.h" +#include "blk-rq-qos.h" + +/** + * enum prio_policy - I/O priority class policy. + * @POLICY_NO_CHANGE: (default) do not modify the I/O priority class. + * @POLICY_NONE_TO_RT: modify IOPRIO_CLASS_NONE into IOPRIO_CLASS_RT. + * @POLICY_RESTRICT_TO_BE: modify IOPRIO_CLASS_NONE and IOPRIO_CLASS_RT into + * IOPRIO_CLASS_BE. + * @POLICY_ALL_TO_IDLE: change the I/O priority class into IOPRIO_CLASS_IDLE. + * + * See also . + */ +enum prio_policy { + POLICY_NO_CHANGE = 0, + POLICY_NONE_TO_RT = 1, + POLICY_RESTRICT_TO_BE = 2, + POLICY_ALL_TO_IDLE = 3, +}; + +static const char *policy_name[] = { + [POLICY_NO_CHANGE] = "no-change", + [POLICY_NONE_TO_RT] = "none-to-rt", + [POLICY_RESTRICT_TO_BE] = "restrict-to-be", + [POLICY_ALL_TO_IDLE] = "idle", +}; + +static struct blkcg_policy ioprio_policy; + +/** + * struct ioprio_blkg - Per (cgroup, request queue) data. + * @pd: blkg_policy_data structure. + */ +struct ioprio_blkg { + struct blkg_policy_data pd; +}; + +/** + * struct ioprio_blkcg - Per cgroup data. + * @cpd: blkcg_policy_data structure. + * @prio_policy: One of the IOPRIO_CLASS_* values. See also . + */ +struct ioprio_blkcg { + struct blkcg_policy_data cpd; + enum prio_policy prio_policy; +}; + +static inline struct ioprio_blkg *pd_to_ioprio(struct blkg_policy_data *pd) +{ + return pd ? container_of(pd, struct ioprio_blkg, pd) : NULL; +} + +static struct ioprio_blkcg *blkcg_to_ioprio_blkcg(struct blkcg *blkcg) +{ + return container_of(blkcg_to_cpd(blkcg, &ioprio_policy), + struct ioprio_blkcg, cpd); +} + +static struct ioprio_blkcg * +ioprio_blkcg_from_css(struct cgroup_subsys_state *css) +{ + return blkcg_to_ioprio_blkcg(css_to_blkcg(css)); +} + +static struct ioprio_blkcg *ioprio_blkcg_from_bio(struct bio *bio) +{ + struct blkg_policy_data *pd = blkg_to_pd(bio->bi_blkg, &ioprio_policy); + + if (!pd) + return NULL; + + return blkcg_to_ioprio_blkcg(pd->blkg->blkcg); +} + +static int ioprio_show_prio_policy(struct seq_file *sf, void *v) +{ + struct ioprio_blkcg *blkcg = ioprio_blkcg_from_css(seq_css(sf)); + + seq_printf(sf, "%s\n", policy_name[blkcg->prio_policy]); + return 0; +} + +static ssize_t ioprio_set_prio_policy(struct kernfs_open_file *of, char *buf, + size_t nbytes, loff_t off) +{ + struct ioprio_blkcg *blkcg = ioprio_blkcg_from_css(of_css(of)); + int ret; + + if (off != 0) + return -EIO; + /* kernfs_fop_write_iter() terminates 'buf' with '\0'. */ + ret = sysfs_match_string(policy_name, buf); + if (ret < 0) + return ret; + blkcg->prio_policy = ret; + + return nbytes; +} + +static struct blkg_policy_data * +ioprio_alloc_pd(gfp_t gfp, struct request_queue *q, struct blkcg *blkcg) +{ + struct ioprio_blkg *ioprio_blkg; + + ioprio_blkg = kzalloc(sizeof(*ioprio_blkg), gfp); + if (!ioprio_blkg) + return NULL; + + return &ioprio_blkg->pd; +} + +static void ioprio_free_pd(struct blkg_policy_data *pd) +{ + struct ioprio_blkg *ioprio_blkg = pd_to_ioprio(pd); + + kfree(ioprio_blkg); +} + +static struct blkcg_policy_data *ioprio_alloc_cpd(gfp_t gfp) +{ + struct ioprio_blkcg *blkcg; + + blkcg = kzalloc(sizeof(*blkcg), gfp); + if (!blkcg) + return NULL; + blkcg->prio_policy = POLICY_NO_CHANGE; + return &blkcg->cpd; +} + +static void ioprio_free_cpd(struct blkcg_policy_data *cpd) +{ + struct ioprio_blkcg *blkcg = container_of(cpd, typeof(*blkcg), cpd); + + kfree(blkcg); +} + +#define IOPRIO_ATTRS \ + { \ + .name = "prio.class", \ + .seq_show = ioprio_show_prio_policy, \ + .write = ioprio_set_prio_policy, \ + }, \ + { } /* sentinel */ + +/* cgroup v2 attributes */ +static struct cftype ioprio_files[] = { + IOPRIO_ATTRS +}; + +/* cgroup v1 attributes */ +static struct cftype ioprio_legacy_files[] = { + IOPRIO_ATTRS +}; + +static struct blkcg_policy ioprio_policy = { + .dfl_cftypes = ioprio_files, + .legacy_cftypes = ioprio_legacy_files, + + .cpd_alloc_fn = ioprio_alloc_cpd, + .cpd_free_fn = ioprio_free_cpd, + + .pd_alloc_fn = ioprio_alloc_pd, + .pd_free_fn = ioprio_free_pd, +}; + +struct blk_ioprio { + struct rq_qos rqos; +}; + +static void blkcg_ioprio_track(struct rq_qos *rqos, struct request *rq, + struct bio *bio) +{ + struct ioprio_blkcg *blkcg = ioprio_blkcg_from_bio(bio); + + /* + * Except for IOPRIO_CLASS_NONE, higher I/O priority numbers + * correspond to a lower priority. Hence, the max_t() below selects + * the lower priority of bi_ioprio and the cgroup I/O priority class. + * If the cgroup policy has been set to POLICY_NO_CHANGE == 0, the + * bio I/O priority is not modified. If the bio I/O priority equals + * IOPRIO_CLASS_NONE, the cgroup I/O priority is assigned to the bio. + */ + bio->bi_ioprio = max_t(u16, bio->bi_ioprio, + IOPRIO_PRIO_VALUE(blkcg->prio_policy, 0)); +} + +static void blkcg_ioprio_exit(struct rq_qos *rqos) +{ + struct blk_ioprio *blkioprio_blkg = + container_of(rqos, typeof(*blkioprio_blkg), rqos); + + blkcg_deactivate_policy(rqos->q, &ioprio_policy); + kfree(blkioprio_blkg); +} + +static struct rq_qos_ops blkcg_ioprio_ops = { + .track = blkcg_ioprio_track, + .exit = blkcg_ioprio_exit, +}; + +int blk_ioprio_init(struct request_queue *q) +{ + struct blk_ioprio *blkioprio_blkg; + struct rq_qos *rqos; + int ret; + + blkioprio_blkg = kzalloc(sizeof(*blkioprio_blkg), GFP_KERNEL); + if (!blkioprio_blkg) + return -ENOMEM; + + ret = blkcg_activate_policy(q, &ioprio_policy); + if (ret) { + kfree(blkioprio_blkg); + return ret; + } + + rqos = &blkioprio_blkg->rqos; + rqos->id = RQ_QOS_IOPRIO; + rqos->ops = &blkcg_ioprio_ops; + rqos->q = q; + + /* + * Registering the rq-qos policy after activating the blk-cgroup + * policy guarantees that ioprio_blkcg_from_bio(bio) != NULL in the + * rq-qos callbacks. + */ + rq_qos_add(q, rqos); + + return 0; +} + +static int __init ioprio_init(void) +{ + return blkcg_policy_register(&ioprio_policy); +} + +static void __exit ioprio_exit(void) +{ + blkcg_policy_unregister(&ioprio_policy); +} + +module_init(ioprio_init); +module_exit(ioprio_exit); diff --git a/block/blk-ioprio.h b/block/blk-ioprio.h new file mode 100644 index 000000000000..a7785c2f1aea --- /dev/null +++ b/block/blk-ioprio.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _BLK_IOPRIO_H_ +#define _BLK_IOPRIO_H_ + +#include + +struct request_queue; + +#ifdef CONFIG_BLK_CGROUP_IOPRIO +int blk_ioprio_init(struct request_queue *q); +#else +static inline int blk_ioprio_init(struct request_queue *q) +{ + return 0; +} +#endif + +#endif /* _BLK_IOPRIO_H_ */ diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index 4de03da9a624..34a5eff632bf 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -939,6 +939,21 @@ void blk_mq_debugfs_unregister_sched(struct request_queue *q) q->sched_debugfs_dir = NULL; } +static const char *rq_qos_id_to_name(enum rq_qos_id id) +{ + switch (id) { + case RQ_QOS_WBT: + return "wbt"; + case RQ_QOS_LATENCY: + return "latency"; + case RQ_QOS_COST: + return "cost"; + case RQ_QOS_IOPRIO: + return "ioprio"; + } + return "unknown"; +} + void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos) { debugfs_remove_recursive(rqos->debugfs_dir); diff --git a/block/blk-mq-tag.h b/block/blk-mq-tag.h index f887988e5ef6..689cd1e9d7ed 100644 --- a/block/blk-mq-tag.h +++ b/block/blk-mq-tag.h @@ -26,6 +26,8 @@ struct blk_mq_tags { * request pool */ spinlock_t lock; + + ANDROID_OEM_DATA(1); }; extern struct blk_mq_tags *blk_mq_init_tags(unsigned int nr_tags, diff --git a/block/blk-mq.c b/block/blk-mq.c index 06b45114eaab..a55c0449f411 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -41,6 +41,8 @@ #include "blk-mq-sched.h" #include "blk-rq-qos.h" +#include + static DEFINE_PER_CPU(struct list_head, blk_cpu_done); static void blk_mq_poll_stats_start(struct request_queue *q); @@ -341,6 +343,7 @@ static struct request *blk_mq_rq_ctx_init(struct blk_mq_alloc_data *data, } data->hctx->queued++; + trace_android_vh_blk_rq_ctx_init(rq, tags, data, alloc_time_ns); return rq; } @@ -1668,6 +1671,42 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async) } EXPORT_SYMBOL(blk_mq_run_hw_queue); +/* + * Is the request queue handled by an IO scheduler that does not respect + * hardware queues when dispatching? + */ +static bool blk_mq_has_sqsched(struct request_queue *q) +{ + struct elevator_queue *e = q->elevator; + + if (e && e->type->ops.dispatch_request && + !(e->type->elevator_features & ELEVATOR_F_MQ_AWARE)) + return true; + return false; +} + +/* + * Return prefered queue to dispatch from (if any) for non-mq aware IO + * scheduler. + */ +static struct blk_mq_hw_ctx *blk_mq_get_sq_hctx(struct request_queue *q) +{ + struct blk_mq_hw_ctx *hctx; + + /* + * If the IO scheduler does not respect hardware queues when + * dispatching, we just don't bother with multiple HW queues and + * dispatch from hctx for the current CPU since running multiple queues + * just causes lock contention inside the scheduler and pointless cache + * bouncing. + */ + hctx = blk_mq_map_queue_type(q, HCTX_TYPE_DEFAULT, + raw_smp_processor_id()); + if (!blk_mq_hctx_stopped(hctx)) + return hctx; + return NULL; +} + /** * blk_mq_run_hw_queues - Run all hardware queues in a request queue. * @q: Pointer to the request queue to run. @@ -1675,14 +1714,23 @@ EXPORT_SYMBOL(blk_mq_run_hw_queue); */ void blk_mq_run_hw_queues(struct request_queue *q, bool async) { - struct blk_mq_hw_ctx *hctx; + struct blk_mq_hw_ctx *hctx, *sq_hctx; int i; + sq_hctx = NULL; + if (blk_mq_has_sqsched(q)) + sq_hctx = blk_mq_get_sq_hctx(q); queue_for_each_hw_ctx(q, hctx, i) { if (blk_mq_hctx_stopped(hctx)) continue; - - blk_mq_run_hw_queue(hctx, async); + /* + * Dispatch from this hctx either if there's no hctx preferred + * by IO scheduler or if it has requests that bypass the + * scheduler. + */ + if (!sq_hctx || sq_hctx == hctx || + !list_empty_careful(&hctx->dispatch)) + blk_mq_run_hw_queue(hctx, async); } } EXPORT_SYMBOL(blk_mq_run_hw_queues); @@ -1694,14 +1742,23 @@ EXPORT_SYMBOL(blk_mq_run_hw_queues); */ void blk_mq_delay_run_hw_queues(struct request_queue *q, unsigned long msecs) { - struct blk_mq_hw_ctx *hctx; + struct blk_mq_hw_ctx *hctx, *sq_hctx; int i; + sq_hctx = NULL; + if (blk_mq_has_sqsched(q)) + sq_hctx = blk_mq_get_sq_hctx(q); queue_for_each_hw_ctx(q, hctx, i) { if (blk_mq_hctx_stopped(hctx)) continue; - - blk_mq_delay_run_hw_queue(hctx, msecs); + /* + * Dispatch from this hctx either if there's no hctx preferred + * by IO scheduler or if it has requests that bypass the + * scheduler. + */ + if (!sq_hctx || sq_hctx == hctx || + !list_empty_careful(&hctx->dispatch)) + blk_mq_delay_run_hw_queue(hctx, msecs); } } EXPORT_SYMBOL(blk_mq_delay_run_hw_queues); @@ -2429,6 +2486,7 @@ int blk_mq_alloc_rqs(struct blk_mq_tag_set *set, struct blk_mq_tags *tags, */ rq_size = round_up(sizeof(struct request) + set->cmd_size, cache_line_size()); + trace_android_vh_blk_alloc_rqs(&rq_size, set, tags); left = rq_size * depth; for (i = 0; i < depth; ) { @@ -2740,7 +2798,6 @@ blk_mq_alloc_hctx(struct request_queue *q, struct blk_mq_tag_set *set, goto free_hctx; atomic_set(&hctx->nr_active, 0); - atomic_set(&hctx->elevator_queued, 0); if (node == NUMA_NO_NODE) node = set->numa_node; hctx->numa_node = node; diff --git a/block/blk-mq.h b/block/blk-mq.h index f792a0920ebb..d533ab59fcfd 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h @@ -35,6 +35,8 @@ struct blk_mq_ctx { struct request_queue *queue; struct blk_mq_ctxs *ctxs; struct kobject kobj; + + ANDROID_OEM_DATA_ARRAY(1, 2); } ____cacheline_aligned_in_smp; void blk_mq_exit_queue(struct request_queue *q); diff --git a/block/blk-pm.h b/block/blk-pm.h index a2283cc9f716..ea5507d23e75 100644 --- a/block/blk-pm.h +++ b/block/blk-pm.h @@ -6,14 +6,11 @@ #include #ifdef CONFIG_PM -static inline int blk_pm_resume_queue(const bool pm, struct request_queue *q) +static inline void blk_pm_request_resume(struct request_queue *q) { - if (!q->dev || !blk_queue_pm_only(q)) - return 1; /* Nothing to do */ - if (pm && q->rpm_status != RPM_SUSPENDED) - return 1; /* Request allowed */ - pm_request_resume(q->dev); - return 0; + if (q->dev && (q->rpm_status == RPM_SUSPENDED || + q->rpm_status == RPM_SUSPENDING)) + pm_request_resume(q->dev); } static inline void blk_pm_mark_last_busy(struct request *rq) @@ -47,9 +44,8 @@ static inline void blk_pm_put_request(struct request *rq) --rq->q->nr_pending; } #else -static inline int blk_pm_resume_queue(const bool pm, struct request_queue *q) +static inline void blk_pm_request_resume(struct request_queue *q) { - return 1; } static inline void blk_pm_mark_last_busy(struct request *rq) diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h index 2bc43e94f4c4..52728614fb27 100644 --- a/block/blk-rq-qos.h +++ b/block/blk-rq-qos.h @@ -16,6 +16,7 @@ enum rq_qos_id { RQ_QOS_WBT, RQ_QOS_LATENCY, RQ_QOS_COST, + RQ_QOS_IOPRIO, }; struct rq_wait { @@ -78,19 +79,6 @@ static inline struct rq_qos *blkcg_rq_qos(struct request_queue *q) return rq_qos_id(q, RQ_QOS_LATENCY); } -static inline const char *rq_qos_id_to_name(enum rq_qos_id id) -{ - switch (id) { - case RQ_QOS_WBT: - return "wbt"; - case RQ_QOS_LATENCY: - return "latency"; - case RQ_QOS_COST: - return "cost"; - } - return "unknown"; -} - static inline void rq_wait_init(struct rq_wait *rq_wait) { atomic_set(&rq_wait->inflight, 0); diff --git a/block/elevator.c b/block/elevator.c index 293c5c81397a..50230a94dc09 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -621,6 +621,9 @@ static inline bool elv_support_iosched(struct request_queue *q) */ static struct elevator_type *elevator_get_default(struct request_queue *q) { + if (q->tag_set && q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT) + return NULL; + if (q->nr_hw_queues != 1) return NULL; diff --git a/block/kyber-iosched.c b/block/kyber-iosched.c index 7f9ef773bf44..54e6de6bdfd9 100644 --- a/block/kyber-iosched.c +++ b/block/kyber-iosched.c @@ -1030,6 +1030,7 @@ static struct elevator_type kyber_sched = { #endif .elevator_attrs = kyber_sched_attrs, .elevator_name = "kyber", + .elevator_features = ELEVATOR_F_MQ_AWARE, .elevator_owner = THIS_MODULE, }; diff --git a/block/mq-deadline-cgroup.c b/block/mq-deadline-cgroup.c new file mode 100644 index 000000000000..3b4bfddec39f --- /dev/null +++ b/block/mq-deadline-cgroup.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include + +#include "mq-deadline-cgroup.h" + +static struct blkcg_policy dd_blkcg_policy; + +static struct blkcg_policy_data *dd_cpd_alloc(gfp_t gfp) +{ + struct dd_blkcg *pd; + + pd = kzalloc(sizeof(*pd), gfp); + if (!pd) + return NULL; + pd->stats = alloc_percpu_gfp(typeof(*pd->stats), + GFP_KERNEL | __GFP_ZERO); + if (!pd->stats) { + kfree(pd); + return NULL; + } + return &pd->cpd; +} + +static void dd_cpd_free(struct blkcg_policy_data *cpd) +{ + struct dd_blkcg *dd_blkcg = container_of(cpd, typeof(*dd_blkcg), cpd); + + free_percpu(dd_blkcg->stats); + kfree(dd_blkcg); +} + +static struct dd_blkcg *dd_blkcg_from_pd(struct blkg_policy_data *pd) +{ + return container_of(blkcg_to_cpd(pd->blkg->blkcg, &dd_blkcg_policy), + struct dd_blkcg, cpd); +} + +/* + * Convert an association between a block cgroup and a request queue into a + * pointer to the mq-deadline information associated with a (blkcg, queue) pair. + */ +struct dd_blkcg *dd_blkcg_from_bio(struct bio *bio) +{ + struct blkg_policy_data *pd; + + pd = blkg_to_pd(bio->bi_blkg, &dd_blkcg_policy); + if (!pd) + return NULL; + + return dd_blkcg_from_pd(pd); +} + +static size_t dd_pd_stat(struct blkg_policy_data *pd, char *buf, size_t size) +{ + static const char *const prio_class_name[] = { + [IOPRIO_CLASS_NONE] = "NONE", + [IOPRIO_CLASS_RT] = "RT", + [IOPRIO_CLASS_BE] = "BE", + [IOPRIO_CLASS_IDLE] = "IDLE", + }; + struct dd_blkcg *blkcg = dd_blkcg_from_pd(pd); + int res = 0; + u8 prio; + + for (prio = 0; prio < ARRAY_SIZE(blkcg->stats->stats); prio++) + res += scnprintf(buf + res, size - res, + " [%s] dispatched=%u inserted=%u merged=%u", + prio_class_name[prio], + ddcg_sum(blkcg, dispatched, prio) + + ddcg_sum(blkcg, merged, prio) - + ddcg_sum(blkcg, completed, prio), + ddcg_sum(blkcg, inserted, prio) - + ddcg_sum(blkcg, completed, prio), + ddcg_sum(blkcg, merged, prio)); + + return res; +} + +static struct blkg_policy_data *dd_pd_alloc(gfp_t gfp, struct request_queue *q, + struct blkcg *blkcg) +{ + struct dd_blkg *pd; + + pd = kzalloc(sizeof(*pd), gfp); + if (!pd) + return NULL; + return &pd->pd; +} + +static void dd_pd_free(struct blkg_policy_data *pd) +{ + struct dd_blkg *dd_blkg = container_of(pd, typeof(*dd_blkg), pd); + + kfree(dd_blkg); +} + +static struct blkcg_policy dd_blkcg_policy = { + .cpd_alloc_fn = dd_cpd_alloc, + .cpd_free_fn = dd_cpd_free, + + .pd_alloc_fn = dd_pd_alloc, + .pd_free_fn = dd_pd_free, + .pd_stat_fn = dd_pd_stat, +}; + +int dd_activate_policy(struct request_queue *q) +{ + return blkcg_activate_policy(q, &dd_blkcg_policy); +} + +void dd_deactivate_policy(struct request_queue *q) +{ + blkcg_deactivate_policy(q, &dd_blkcg_policy); +} + +int __init dd_blkcg_init(void) +{ + return blkcg_policy_register(&dd_blkcg_policy); +} + +void __exit dd_blkcg_exit(void) +{ + blkcg_policy_unregister(&dd_blkcg_policy); +} diff --git a/block/mq-deadline-cgroup.h b/block/mq-deadline-cgroup.h new file mode 100644 index 000000000000..0143fd74f3ce --- /dev/null +++ b/block/mq-deadline-cgroup.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#if !defined(_MQ_DEADLINE_CGROUP_H_) +#define _MQ_DEADLINE_CGROUP_H_ + +#include + +struct request_queue; + +/** + * struct io_stats_per_prio - I/O statistics per I/O priority class. + * @inserted: Number of inserted requests. + * @merged: Number of merged requests. + * @dispatched: Number of dispatched requests. + * @completed: Number of I/O completions. + */ +struct io_stats_per_prio { + local_t inserted; + local_t merged; + local_t dispatched; + local_t completed; +}; + +/* I/O statistics per I/O cgroup per I/O priority class (IOPRIO_CLASS_*). */ +struct blkcg_io_stats { + struct io_stats_per_prio stats[4]; +}; + +/** + * struct dd_blkcg - Per cgroup data. + * @cpd: blkcg_policy_data structure. + * @stats: I/O statistics. + */ +struct dd_blkcg { + struct blkcg_policy_data cpd; /* must be the first member */ + struct blkcg_io_stats __percpu *stats; +}; + +/* + * Count one event of type 'event_type' and with I/O priority class + * 'prio_class'. + */ +#define ddcg_count(ddcg, event_type, prio_class) do { \ +if (ddcg) { \ + struct blkcg_io_stats *io_stats = get_cpu_ptr((ddcg)->stats); \ + \ + BUILD_BUG_ON(!__same_type((ddcg), struct dd_blkcg *)); \ + BUILD_BUG_ON(!__same_type((prio_class), u8)); \ + local_inc(&io_stats->stats[(prio_class)].event_type); \ + put_cpu_ptr(io_stats); \ +} \ +} while (0) + +/* + * Returns the total number of ddcg_count(ddcg, event_type, prio_class) calls + * across all CPUs. No locking or barriers since it is fine if the returned + * sum is slightly outdated. + */ +#define ddcg_sum(ddcg, event_type, prio) ({ \ + unsigned int cpu; \ + u32 sum = 0; \ + \ + BUILD_BUG_ON(!__same_type((ddcg), struct dd_blkcg *)); \ + BUILD_BUG_ON(!__same_type((prio), u8)); \ + for_each_present_cpu(cpu) \ + sum += local_read(&per_cpu_ptr((ddcg)->stats, cpu)-> \ + stats[(prio)].event_type); \ + sum; \ +}) + +#ifdef CONFIG_BLK_CGROUP + +/** + * struct dd_blkg - Per (cgroup, request queue) data. + * @pd: blkg_policy_data structure. + */ +struct dd_blkg { + struct blkg_policy_data pd; /* must be the first member */ +}; + +struct dd_blkcg *dd_blkcg_from_bio(struct bio *bio); +int dd_activate_policy(struct request_queue *q); +void dd_deactivate_policy(struct request_queue *q); +int __init dd_blkcg_init(void); +void __exit dd_blkcg_exit(void); + +#else /* CONFIG_BLK_CGROUP */ + +static inline struct dd_blkcg *dd_blkcg_from_bio(struct bio *bio) +{ + return NULL; +} + +static inline int dd_activate_policy(struct request_queue *q) +{ + return 0; +} + +static inline void dd_deactivate_policy(struct request_queue *q) +{ +} + +static inline int dd_blkcg_init(void) +{ + return 0; +} + +static inline void dd_blkcg_exit(void) +{ +} + +#endif /* CONFIG_BLK_CGROUP */ + +#endif /* _MQ_DEADLINE_CGROUP_H_ */ diff --git a/block/mq-deadline-main.c b/block/mq-deadline-main.c new file mode 100644 index 000000000000..ada893d6374d --- /dev/null +++ b/block/mq-deadline-main.c @@ -0,0 +1,1170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MQ Deadline i/o scheduler - adaptation of the legacy deadline scheduler, + * for the blk-mq scheduling framework + * + * Copyright (C) 2016 Jens Axboe + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "blk.h" +#include "blk-mq.h" +#include "blk-mq-debugfs.h" +#include "blk-mq-tag.h" +#include "blk-mq-sched.h" +#include "mq-deadline-cgroup.h" + +/* + * See Documentation/block/deadline-iosched.rst + */ +static const int read_expire = HZ / 2; /* max time before a read is submitted. */ +static const int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */ +/* + * Time after which to dispatch lower priority requests even if higher + * priority requests are pending. + */ +static const int aging_expire = 10 * HZ; +static const int writes_starved = 2; /* max times reads can starve a write */ +static const int fifo_batch = 16; /* # of sequential requests treated as one + by the above parameters. For throughput. */ + +enum dd_data_dir { + DD_READ = READ, + DD_WRITE = WRITE, +}; + +enum { DD_DIR_COUNT = 2 }; + +enum dd_prio { + DD_RT_PRIO = 0, + DD_BE_PRIO = 1, + DD_IDLE_PRIO = 2, + DD_PRIO_MAX = 2, +}; + +enum { DD_PRIO_COUNT = 3 }; + +/* I/O statistics for all I/O priorities (enum dd_prio). */ +struct io_stats { + struct io_stats_per_prio stats[DD_PRIO_COUNT]; +}; + +/* + * Deadline scheduler data per I/O priority (enum dd_prio). Requests are + * present on both sort_list[] and fifo_list[]. + */ +struct dd_per_prio { + struct list_head dispatch; + struct rb_root sort_list[DD_DIR_COUNT]; + struct list_head fifo_list[DD_DIR_COUNT]; + /* Next request in FIFO order. Read, write or both are NULL. */ + struct request *next_rq[DD_DIR_COUNT]; +}; + +struct deadline_data { + /* + * run time data + */ + + /* Request queue that owns this data structure. */ + struct request_queue *queue; + + struct dd_per_prio per_prio[DD_PRIO_COUNT]; + + /* Data direction of latest dispatched request. */ + enum dd_data_dir last_dir; + unsigned int batching; /* number of sequential requests made */ + unsigned int starved; /* times reads have starved writes */ + + struct io_stats __percpu *stats; + + /* + * settings that change how the i/o scheduler behaves + */ + int fifo_expire[DD_DIR_COUNT]; + int fifo_batch; + int writes_starved; + int front_merges; + u32 async_depth; + int aging_expire; + + spinlock_t lock; + spinlock_t zone_lock; +}; + +/* Count one event of type 'event_type' and with I/O priority 'prio' */ +#define dd_count(dd, event_type, prio) do { \ + struct io_stats *io_stats = get_cpu_ptr((dd)->stats); \ + \ + BUILD_BUG_ON(!__same_type((dd), struct deadline_data *)); \ + BUILD_BUG_ON(!__same_type((prio), enum dd_prio)); \ + local_inc(&io_stats->stats[(prio)].event_type); \ + put_cpu_ptr(io_stats); \ +} while (0) + +/* + * Returns the total number of dd_count(dd, event_type, prio) calls across all + * CPUs. No locking or barriers since it is fine if the returned sum is slightly + * outdated. + */ +#define dd_sum(dd, event_type, prio) ({ \ + unsigned int cpu; \ + u32 sum = 0; \ + \ + BUILD_BUG_ON(!__same_type((dd), struct deadline_data *)); \ + BUILD_BUG_ON(!__same_type((prio), enum dd_prio)); \ + for_each_present_cpu(cpu) \ + sum += local_read(&per_cpu_ptr((dd)->stats, cpu)-> \ + stats[(prio)].event_type); \ + sum; \ +}) + +/* Maps an I/O priority class to a deadline scheduler priority. */ +static const enum dd_prio ioprio_class_to_prio[] = { + [IOPRIO_CLASS_NONE] = DD_BE_PRIO, + [IOPRIO_CLASS_RT] = DD_RT_PRIO, + [IOPRIO_CLASS_BE] = DD_BE_PRIO, + [IOPRIO_CLASS_IDLE] = DD_IDLE_PRIO, +}; + +static inline struct rb_root * +deadline_rb_root(struct dd_per_prio *per_prio, struct request *rq) +{ + return &per_prio->sort_list[rq_data_dir(rq)]; +} + +/* + * Returns the I/O priority class (IOPRIO_CLASS_*) that has been assigned to a + * request. + */ +static u8 dd_rq_ioclass(struct request *rq) +{ + return IOPRIO_PRIO_CLASS(req_get_ioprio(rq)); +} + +/* + * get the request after `rq' in sector-sorted order + */ +static inline struct request * +deadline_latter_request(struct request *rq) +{ + struct rb_node *node = rb_next(&rq->rb_node); + + if (node) + return rb_entry_rq(node); + + return NULL; +} + +static void +deadline_add_rq_rb(struct dd_per_prio *per_prio, struct request *rq) +{ + struct rb_root *root = deadline_rb_root(per_prio, rq); + + elv_rb_add(root, rq); +} + +static inline void +deadline_del_rq_rb(struct dd_per_prio *per_prio, struct request *rq) +{ + const enum dd_data_dir data_dir = rq_data_dir(rq); + + if (per_prio->next_rq[data_dir] == rq) + per_prio->next_rq[data_dir] = deadline_latter_request(rq); + + elv_rb_del(deadline_rb_root(per_prio, rq), rq); +} + +/* + * remove rq from rbtree and fifo. + */ +static void deadline_remove_request(struct request_queue *q, + struct dd_per_prio *per_prio, + struct request *rq) +{ + list_del_init(&rq->queuelist); + + /* + * We might not be on the rbtree, if we are doing an insert merge + */ + if (!RB_EMPTY_NODE(&rq->rb_node)) + deadline_del_rq_rb(per_prio, rq); + + elv_rqhash_del(q, rq); + if (q->last_merge == rq) + q->last_merge = NULL; +} + +static void dd_request_merged(struct request_queue *q, struct request *req, + enum elv_merge type) +{ + struct deadline_data *dd = q->elevator->elevator_data; + const u8 ioprio_class = dd_rq_ioclass(req); + const enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + + /* + * if the merge was a front merge, we need to reposition request + */ + if (type == ELEVATOR_FRONT_MERGE) { + elv_rb_del(deadline_rb_root(per_prio, req), req); + deadline_add_rq_rb(per_prio, req); + } +} + +/* + * Callback function that is invoked after @next has been merged into @req. + */ +static void dd_merged_requests(struct request_queue *q, struct request *req, + struct request *next) +{ + struct deadline_data *dd = q->elevator->elevator_data; + const u8 ioprio_class = dd_rq_ioclass(next); + const enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; + struct dd_blkcg *blkcg = next->elv.priv[0]; + + dd_count(dd, merged, prio); + ddcg_count(blkcg, merged, ioprio_class); + + /* + * if next expires before rq, assign its expire time to rq + * and move into next position (next will be deleted) in fifo + */ + if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) { + if (time_before((unsigned long)next->fifo_time, + (unsigned long)req->fifo_time)) { + list_move(&req->queuelist, &next->queuelist); + req->fifo_time = next->fifo_time; + } + } + + /* + * kill knowledge of next, this one is a goner + */ + deadline_remove_request(q, &dd->per_prio[prio], next); +} + +/* + * move an entry to dispatch queue + */ +static void +deadline_move_request(struct deadline_data *dd, struct dd_per_prio *per_prio, + struct request *rq) +{ + const enum dd_data_dir data_dir = rq_data_dir(rq); + + per_prio->next_rq[data_dir] = deadline_latter_request(rq); + + /* + * take it off the sort and fifo list + */ + deadline_remove_request(rq->q, per_prio, rq); +} + +/* Number of requests queued for a given priority level. */ +static u32 dd_queued(struct deadline_data *dd, enum dd_prio prio) +{ + return dd_sum(dd, inserted, prio) - dd_sum(dd, completed, prio); +} + +/* + * deadline_check_fifo returns 0 if there are no expired requests on the fifo, + * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir]) + */ +static inline int deadline_check_fifo(struct dd_per_prio *per_prio, + enum dd_data_dir data_dir) +{ + struct request *rq = rq_entry_fifo(per_prio->fifo_list[data_dir].next); + + /* + * rq is expired! + */ + if (time_after_eq(jiffies, (unsigned long)rq->fifo_time)) + return 1; + + return 0; +} + +/* + * For the specified data direction, return the next request to + * dispatch using arrival ordered lists. + */ +static struct request * +deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio, + enum dd_data_dir data_dir) +{ + struct request *rq; + unsigned long flags; + + if (list_empty(&per_prio->fifo_list[data_dir])) + return NULL; + + rq = rq_entry_fifo(per_prio->fifo_list[data_dir].next); + if (data_dir == DD_READ || !blk_queue_is_zoned(rq->q)) + return rq; + + /* + * Look for a write request that can be dispatched, that is one with + * an unlocked target zone. + */ + spin_lock_irqsave(&dd->zone_lock, flags); + list_for_each_entry(rq, &per_prio->fifo_list[DD_WRITE], queuelist) { + if (blk_req_can_dispatch_to_zone(rq)) + goto out; + } + rq = NULL; +out: + spin_unlock_irqrestore(&dd->zone_lock, flags); + + return rq; +} + +/* + * For the specified data direction, return the next request to + * dispatch using sector position sorted lists. + */ +static struct request * +deadline_next_request(struct deadline_data *dd, struct dd_per_prio *per_prio, + enum dd_data_dir data_dir) +{ + struct request *rq; + unsigned long flags; + + rq = per_prio->next_rq[data_dir]; + if (!rq) + return NULL; + + if (data_dir == DD_READ || !blk_queue_is_zoned(rq->q)) + return rq; + + /* + * Look for a write request that can be dispatched, that is one with + * an unlocked target zone. + */ + spin_lock_irqsave(&dd->zone_lock, flags); + while (rq) { + if (blk_req_can_dispatch_to_zone(rq)) + break; + rq = deadline_latter_request(rq); + } + spin_unlock_irqrestore(&dd->zone_lock, flags); + + return rq; +} + +/* + * deadline_dispatch_requests selects the best request according to + * read/write expire, fifo_batch, etc and with a start time <= @latest. + */ +static struct request *__dd_dispatch_request(struct deadline_data *dd, + struct dd_per_prio *per_prio, + u64 latest_start_ns) +{ + struct request *rq, *next_rq; + enum dd_data_dir data_dir; + struct dd_blkcg *blkcg; + enum dd_prio prio; + u8 ioprio_class; + + lockdep_assert_held(&dd->lock); + + if (!list_empty(&per_prio->dispatch)) { + rq = list_first_entry(&per_prio->dispatch, struct request, + queuelist); + if (rq->start_time_ns > latest_start_ns) + return NULL; + list_del_init(&rq->queuelist); + goto done; + } + + /* + * batches are currently reads XOR writes + */ + rq = deadline_next_request(dd, per_prio, dd->last_dir); + if (rq && dd->batching < dd->fifo_batch) + /* we have a next request are still entitled to batch */ + goto dispatch_request; + + /* + * at this point we are not running a batch. select the appropriate + * data direction (read / write) + */ + + if (!list_empty(&per_prio->fifo_list[DD_READ])) { + BUG_ON(RB_EMPTY_ROOT(&per_prio->sort_list[DD_READ])); + + if (deadline_fifo_request(dd, per_prio, DD_WRITE) && + (dd->starved++ >= dd->writes_starved)) + goto dispatch_writes; + + data_dir = DD_READ; + + goto dispatch_find_request; + } + + /* + * there are either no reads or writes have been starved + */ + + if (!list_empty(&per_prio->fifo_list[DD_WRITE])) { +dispatch_writes: + BUG_ON(RB_EMPTY_ROOT(&per_prio->sort_list[DD_WRITE])); + + dd->starved = 0; + + data_dir = DD_WRITE; + + goto dispatch_find_request; + } + + return NULL; + +dispatch_find_request: + /* + * we are not running a batch, find best request for selected data_dir + */ + next_rq = deadline_next_request(dd, per_prio, data_dir); + if (deadline_check_fifo(per_prio, data_dir) || !next_rq) { + /* + * A deadline has expired, the last request was in the other + * direction, or we have run out of higher-sectored requests. + * Start again from the request with the earliest expiry time. + */ + rq = deadline_fifo_request(dd, per_prio, data_dir); + } else { + /* + * The last req was the same dir and we have a next request in + * sort order. No expired requests so continue on from here. + */ + rq = next_rq; + } + + /* + * For a zoned block device, if we only have writes queued and none of + * them can be dispatched, rq will be NULL. + */ + if (!rq) + return NULL; + + dd->last_dir = data_dir; + dd->batching = 0; + +dispatch_request: + if (rq->start_time_ns > latest_start_ns) + return NULL; + /* + * rq is the selected appropriate request. + */ + dd->batching++; + deadline_move_request(dd, per_prio, rq); +done: + ioprio_class = dd_rq_ioclass(rq); + prio = ioprio_class_to_prio[ioprio_class]; + dd_count(dd, dispatched, prio); + blkcg = rq->elv.priv[0]; + ddcg_count(blkcg, dispatched, ioprio_class); + /* + * If the request needs its target zone locked, do it. + */ + blk_req_zone_write_lock(rq); + rq->rq_flags |= RQF_STARTED; + return rq; +} + +/* + * Called from blk_mq_run_hw_queue() -> __blk_mq_sched_dispatch_requests(). + * + * One confusing aspect here is that we get called for a specific + * hardware queue, but we may return a request that is for a + * different hardware queue. This is because mq-deadline has shared + * state for all hardware queues, in terms of sorting, FIFOs, etc. + */ +static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) +{ + struct deadline_data *dd = hctx->queue->elevator->elevator_data; + const u64 now_ns = ktime_get_ns(); + struct request *rq = NULL; + enum dd_prio prio; + + spin_lock(&dd->lock); + /* + * Start with dispatching requests whose deadline expired more than + * aging_expire jiffies ago. + */ + for (prio = DD_BE_PRIO; prio <= DD_PRIO_MAX; prio++) { + rq = __dd_dispatch_request(dd, &dd->per_prio[prio], now_ns - + jiffies_to_nsecs(dd->aging_expire)); + if (rq) + goto unlock; + } + /* + * Next, dispatch requests in priority order. Ignore lower priority + * requests if any higher priority requests are pending. + */ + for (prio = 0; prio <= DD_PRIO_MAX; prio++) { + rq = __dd_dispatch_request(dd, &dd->per_prio[prio], now_ns); + if (rq || dd_queued(dd, prio)) + break; + } + +unlock: + spin_unlock(&dd->lock); + + return rq; +} + +/* + * Called by __blk_mq_alloc_request(). The shallow_depth value set by this + * function is used by __blk_mq_get_tag(). + */ +static void dd_limit_depth(unsigned int op, struct blk_mq_alloc_data *data) +{ + struct deadline_data *dd = data->q->elevator->elevator_data; + + /* Do not throttle synchronous reads. */ + if (op_is_sync(op) && !op_is_write(op)) + return; + + /* + * Throttle asynchronous requests and writes such that these requests + * do not block the allocation of synchronous requests. + */ + data->shallow_depth = dd->async_depth; +} + +/* Called by blk_mq_update_nr_requests(). */ +static void dd_depth_updated(struct blk_mq_hw_ctx *hctx) +{ + struct request_queue *q = hctx->queue; + struct deadline_data *dd = q->elevator->elevator_data; + struct blk_mq_tags *tags = hctx->sched_tags; + + dd->async_depth = max(1UL, 3 * q->nr_requests / 4); + + sbitmap_queue_min_shallow_depth(tags->bitmap_tags, dd->async_depth); +} + +/* Called by blk_mq_init_hctx() and blk_mq_init_sched(). */ +static int dd_init_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx) +{ + dd_depth_updated(hctx); + return 0; +} + +static void dd_exit_sched(struct elevator_queue *e) +{ + struct deadline_data *dd = e->elevator_data; + enum dd_prio prio; + + dd_deactivate_policy(dd->queue); + + for (prio = 0; prio <= DD_PRIO_MAX; prio++) { + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + + WARN_ON_ONCE(!list_empty(&per_prio->fifo_list[DD_READ])); + WARN_ON_ONCE(!list_empty(&per_prio->fifo_list[DD_WRITE])); + } + + free_percpu(dd->stats); + + kfree(dd); +} + +/* + * Initialize elevator private data (deadline_data) and associate with blkcg. + */ +static int dd_init_sched(struct request_queue *q, struct elevator_type *e) +{ + struct deadline_data *dd; + struct elevator_queue *eq; + enum dd_prio prio; + int ret = -ENOMEM; + + /* + * Initialization would be very tricky if the queue is not frozen, + * hence the warning statement below. + */ + WARN_ON_ONCE(!percpu_ref_is_zero(&q->q_usage_counter)); + + eq = elevator_alloc(q, e); + if (!eq) + return ret; + + dd = kzalloc_node(sizeof(*dd), GFP_KERNEL, q->node); + if (!dd) + goto put_eq; + + eq->elevator_data = dd; + + dd->stats = alloc_percpu_gfp(typeof(*dd->stats), + GFP_KERNEL | __GFP_ZERO); + if (!dd->stats) + goto free_dd; + + dd->queue = q; + + for (prio = 0; prio <= DD_PRIO_MAX; prio++) { + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + + INIT_LIST_HEAD(&per_prio->dispatch); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_READ]); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_WRITE]); + per_prio->sort_list[DD_READ] = RB_ROOT; + per_prio->sort_list[DD_WRITE] = RB_ROOT; + } + dd->fifo_expire[DD_READ] = read_expire; + dd->fifo_expire[DD_WRITE] = write_expire; + dd->writes_starved = writes_starved; + dd->front_merges = 1; + dd->last_dir = DD_WRITE; + dd->fifo_batch = fifo_batch; + dd->aging_expire = aging_expire; + spin_lock_init(&dd->lock); + spin_lock_init(&dd->zone_lock); + + ret = dd_activate_policy(q); + if (ret) + goto free_stats; + + ret = 0; + q->elevator = eq; + return 0; + +free_stats: + free_percpu(dd->stats); + +free_dd: + kfree(dd); + +put_eq: + kobject_put(&eq->kobj); + return ret; +} + +/* + * Try to merge @bio into an existing request. If @bio has been merged into + * an existing request, store the pointer to that request into *@rq. + */ +static int dd_request_merge(struct request_queue *q, struct request **rq, + struct bio *bio) +{ + struct deadline_data *dd = q->elevator->elevator_data; + const u8 ioprio_class = IOPRIO_PRIO_CLASS(bio->bi_ioprio); + const enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + sector_t sector = bio_end_sector(bio); + struct request *__rq; + + if (!dd->front_merges) + return ELEVATOR_NO_MERGE; + + __rq = elv_rb_find(&per_prio->sort_list[bio_data_dir(bio)], sector); + if (__rq) { + BUG_ON(sector != blk_rq_pos(__rq)); + + if (elv_bio_merge_ok(__rq, bio)) { + *rq = __rq; + return ELEVATOR_FRONT_MERGE; + } + } + + return ELEVATOR_NO_MERGE; +} + +/* + * Attempt to merge a bio into an existing request. This function is called + * before @bio is associated with a request. + */ +static bool dd_bio_merge(struct request_queue *q, struct bio *bio, + unsigned int nr_segs) +{ + struct deadline_data *dd = q->elevator->elevator_data; + struct request *free = NULL; + bool ret; + + spin_lock(&dd->lock); + ret = blk_mq_sched_try_merge(q, bio, nr_segs, &free); + spin_unlock(&dd->lock); + + if (free) + blk_mq_free_request(free); + + return ret; +} + +/* + * add rq to rbtree and fifo + */ +static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + bool at_head) +{ + struct request_queue *q = hctx->queue; + struct deadline_data *dd = q->elevator->elevator_data; + const enum dd_data_dir data_dir = rq_data_dir(rq); + u16 ioprio = req_get_ioprio(rq); + u8 ioprio_class = IOPRIO_PRIO_CLASS(ioprio); + struct dd_per_prio *per_prio; + enum dd_prio prio; + struct dd_blkcg *blkcg; + + lockdep_assert_held(&dd->lock); + + /* + * This may be a requeue of a write request that has locked its + * target zone. If it is the case, this releases the zone lock. + */ + blk_req_zone_write_unlock(rq); + + /* + * If a block cgroup has been associated with the submitter and if an + * I/O priority has been set in the associated block cgroup, use the + * lowest of the cgroup priority and the request priority for the + * request. If no priority has been set in the request, use the cgroup + * priority. + */ + prio = ioprio_class_to_prio[ioprio_class]; + dd_count(dd, inserted, prio); + blkcg = dd_blkcg_from_bio(rq->bio); + ddcg_count(blkcg, inserted, ioprio_class); + rq->elv.priv[0] = blkcg; + + if (blk_mq_sched_try_insert_merge(q, rq)) + return; + + blk_mq_sched_request_inserted(rq); + + per_prio = &dd->per_prio[prio]; + if (at_head) { + list_add(&rq->queuelist, &per_prio->dispatch); + } else { + deadline_add_rq_rb(per_prio, rq); + + if (rq_mergeable(rq)) { + elv_rqhash_add(q, rq); + if (!q->last_merge) + q->last_merge = rq; + } + + /* + * set expire time and add to fifo list + */ + rq->fifo_time = jiffies + dd->fifo_expire[data_dir]; + list_add_tail(&rq->queuelist, &per_prio->fifo_list[data_dir]); + } +} + +/* + * Called from blk_mq_sched_insert_request() or blk_mq_sched_insert_requests(). + */ +static void dd_insert_requests(struct blk_mq_hw_ctx *hctx, + struct list_head *list, bool at_head) +{ + struct request_queue *q = hctx->queue; + struct deadline_data *dd = q->elevator->elevator_data; + + spin_lock(&dd->lock); + while (!list_empty(list)) { + struct request *rq; + + rq = list_first_entry(list, struct request, queuelist); + list_del_init(&rq->queuelist); + dd_insert_request(hctx, rq, at_head); + } + spin_unlock(&dd->lock); +} + +/* Callback from inside blk_mq_rq_ctx_init(). */ +static void dd_prepare_request(struct request *rq) +{ + rq->elv.priv[0] = NULL; +} + +/* + * Callback from inside blk_mq_free_request(). + * + * For zoned block devices, write unlock the target zone of + * completed write requests. Do this while holding the zone lock + * spinlock so that the zone is never unlocked while deadline_fifo_request() + * or deadline_next_request() are executing. This function is called for + * all requests, whether or not these requests complete successfully. + * + * For a zoned block device, __dd_dispatch_request() may have stopped + * dispatching requests if all the queued requests are write requests directed + * at zones that are already locked due to on-going write requests. To ensure + * write request dispatch progress in this case, mark the queue as needing a + * restart to ensure that the queue is run again after completion of the + * request and zones being unlocked. + */ +static void dd_finish_request(struct request *rq) +{ + struct request_queue *q = rq->q; + struct deadline_data *dd = q->elevator->elevator_data; + struct dd_blkcg *blkcg = rq->elv.priv[0]; + const u8 ioprio_class = dd_rq_ioclass(rq); + const enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + + dd_count(dd, completed, prio); + ddcg_count(blkcg, completed, ioprio_class); + + if (blk_queue_is_zoned(q)) { + unsigned long flags; + + spin_lock_irqsave(&dd->zone_lock, flags); + blk_req_zone_write_unlock(rq); + if (!list_empty(&per_prio->fifo_list[DD_WRITE])) + blk_mq_sched_mark_restart_hctx(rq->mq_hctx); + spin_unlock_irqrestore(&dd->zone_lock, flags); + } +} + +static bool dd_has_work_for_prio(struct dd_per_prio *per_prio) +{ + return !list_empty_careful(&per_prio->dispatch) || + !list_empty_careful(&per_prio->fifo_list[DD_READ]) || + !list_empty_careful(&per_prio->fifo_list[DD_WRITE]); +} + +static bool dd_has_work(struct blk_mq_hw_ctx *hctx) +{ + struct deadline_data *dd = hctx->queue->elevator->elevator_data; + enum dd_prio prio; + + for (prio = 0; prio <= DD_PRIO_MAX; prio++) + if (dd_has_work_for_prio(&dd->per_prio[prio])) + return true; + + return false; +} + +/* + * sysfs parts below + */ +#define SHOW_INT(__FUNC, __VAR) \ +static ssize_t __FUNC(struct elevator_queue *e, char *page) \ +{ \ + struct deadline_data *dd = e->elevator_data; \ + \ + return sysfs_emit(page, "%d\n", __VAR); \ +} +#define SHOW_JIFFIES(__FUNC, __VAR) SHOW_INT(__FUNC, jiffies_to_msecs(__VAR)) +SHOW_JIFFIES(deadline_read_expire_show, dd->fifo_expire[DD_READ]); +SHOW_JIFFIES(deadline_write_expire_show, dd->fifo_expire[DD_WRITE]); +SHOW_JIFFIES(deadline_aging_expire_show, dd->aging_expire); +SHOW_INT(deadline_writes_starved_show, dd->writes_starved); +SHOW_INT(deadline_front_merges_show, dd->front_merges); +SHOW_INT(deadline_async_depth_show, dd->front_merges); +SHOW_INT(deadline_fifo_batch_show, dd->fifo_batch); +#undef SHOW_INT +#undef SHOW_JIFFIES + +#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ +static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count) \ +{ \ + struct deadline_data *dd = e->elevator_data; \ + int __data, __ret; \ + \ + __ret = kstrtoint(page, 0, &__data); \ + if (__ret < 0) \ + return __ret; \ + if (__data < (MIN)) \ + __data = (MIN); \ + else if (__data > (MAX)) \ + __data = (MAX); \ + *(__PTR) = __CONV(__data); \ + return count; \ +} +#define STORE_INT(__FUNC, __PTR, MIN, MAX) \ + STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, ) +#define STORE_JIFFIES(__FUNC, __PTR, MIN, MAX) \ + STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, msecs_to_jiffies) +STORE_JIFFIES(deadline_read_expire_store, &dd->fifo_expire[DD_READ], 0, INT_MAX); +STORE_JIFFIES(deadline_write_expire_store, &dd->fifo_expire[DD_WRITE], 0, INT_MAX); +STORE_JIFFIES(deadline_aging_expire_store, &dd->aging_expire, 0, INT_MAX); +STORE_INT(deadline_writes_starved_store, &dd->writes_starved, INT_MIN, INT_MAX); +STORE_INT(deadline_front_merges_store, &dd->front_merges, 0, 1); +STORE_INT(deadline_async_depth_store, &dd->front_merges, 1, INT_MAX); +STORE_INT(deadline_fifo_batch_store, &dd->fifo_batch, 0, INT_MAX); +#undef STORE_FUNCTION +#undef STORE_INT +#undef STORE_JIFFIES + +#define DD_ATTR(name) \ + __ATTR(name, 0644, deadline_##name##_show, deadline_##name##_store) + +static struct elv_fs_entry deadline_attrs[] = { + DD_ATTR(read_expire), + DD_ATTR(write_expire), + DD_ATTR(writes_starved), + DD_ATTR(front_merges), + DD_ATTR(async_depth), + DD_ATTR(fifo_batch), + DD_ATTR(aging_expire), + __ATTR_NULL +}; + +#ifdef CONFIG_BLK_DEBUG_FS +#define DEADLINE_DEBUGFS_DDIR_ATTRS(prio, data_dir, name) \ +static void *deadline_##name##_fifo_start(struct seq_file *m, \ + loff_t *pos) \ + __acquires(&dd->lock) \ +{ \ + struct request_queue *q = m->private; \ + struct deadline_data *dd = q->elevator->elevator_data; \ + struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ + \ + spin_lock(&dd->lock); \ + return seq_list_start(&per_prio->fifo_list[data_dir], *pos); \ +} \ + \ +static void *deadline_##name##_fifo_next(struct seq_file *m, void *v, \ + loff_t *pos) \ +{ \ + struct request_queue *q = m->private; \ + struct deadline_data *dd = q->elevator->elevator_data; \ + struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ + \ + return seq_list_next(v, &per_prio->fifo_list[data_dir], pos); \ +} \ + \ +static void deadline_##name##_fifo_stop(struct seq_file *m, void *v) \ + __releases(&dd->lock) \ +{ \ + struct request_queue *q = m->private; \ + struct deadline_data *dd = q->elevator->elevator_data; \ + \ + spin_unlock(&dd->lock); \ +} \ + \ +static const struct seq_operations deadline_##name##_fifo_seq_ops = { \ + .start = deadline_##name##_fifo_start, \ + .next = deadline_##name##_fifo_next, \ + .stop = deadline_##name##_fifo_stop, \ + .show = blk_mq_debugfs_rq_show, \ +}; \ + \ +static int deadline_##name##_next_rq_show(void *data, \ + struct seq_file *m) \ +{ \ + struct request_queue *q = data; \ + struct deadline_data *dd = q->elevator->elevator_data; \ + struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ + struct request *rq = per_prio->next_rq[data_dir]; \ + \ + if (rq) \ + __blk_mq_debugfs_rq_show(m, rq); \ + return 0; \ +} + +DEADLINE_DEBUGFS_DDIR_ATTRS(DD_RT_PRIO, DD_READ, read0); +DEADLINE_DEBUGFS_DDIR_ATTRS(DD_RT_PRIO, DD_WRITE, write0); +DEADLINE_DEBUGFS_DDIR_ATTRS(DD_BE_PRIO, DD_READ, read1); +DEADLINE_DEBUGFS_DDIR_ATTRS(DD_BE_PRIO, DD_WRITE, write1); +DEADLINE_DEBUGFS_DDIR_ATTRS(DD_IDLE_PRIO, DD_READ, read2); +DEADLINE_DEBUGFS_DDIR_ATTRS(DD_IDLE_PRIO, DD_WRITE, write2); +#undef DEADLINE_DEBUGFS_DDIR_ATTRS + +static int deadline_batching_show(void *data, struct seq_file *m) +{ + struct request_queue *q = data; + struct deadline_data *dd = q->elevator->elevator_data; + + seq_printf(m, "%u\n", dd->batching); + return 0; +} + +static int deadline_starved_show(void *data, struct seq_file *m) +{ + struct request_queue *q = data; + struct deadline_data *dd = q->elevator->elevator_data; + + seq_printf(m, "%u\n", dd->starved); + return 0; +} + +static int dd_async_depth_show(void *data, struct seq_file *m) +{ + struct request_queue *q = data; + struct deadline_data *dd = q->elevator->elevator_data; + + seq_printf(m, "%u\n", dd->async_depth); + return 0; +} + +static int dd_queued_show(void *data, struct seq_file *m) +{ + struct request_queue *q = data; + struct deadline_data *dd = q->elevator->elevator_data; + + seq_printf(m, "%u %u %u\n", dd_queued(dd, DD_RT_PRIO), + dd_queued(dd, DD_BE_PRIO), + dd_queued(dd, DD_IDLE_PRIO)); + return 0; +} + +/* Number of requests owned by the block driver for a given priority. */ +static u32 dd_owned_by_driver(struct deadline_data *dd, enum dd_prio prio) +{ + return dd_sum(dd, dispatched, prio) + dd_sum(dd, merged, prio) + - dd_sum(dd, completed, prio); +} + +static int dd_owned_by_driver_show(void *data, struct seq_file *m) +{ + struct request_queue *q = data; + struct deadline_data *dd = q->elevator->elevator_data; + + seq_printf(m, "%u %u %u\n", dd_owned_by_driver(dd, DD_RT_PRIO), + dd_owned_by_driver(dd, DD_BE_PRIO), + dd_owned_by_driver(dd, DD_IDLE_PRIO)); + return 0; +} + +#define DEADLINE_DISPATCH_ATTR(prio) \ +static void *deadline_dispatch##prio##_start(struct seq_file *m, \ + loff_t *pos) \ + __acquires(&dd->lock) \ +{ \ + struct request_queue *q = m->private; \ + struct deadline_data *dd = q->elevator->elevator_data; \ + struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ + \ + spin_lock(&dd->lock); \ + return seq_list_start(&per_prio->dispatch, *pos); \ +} \ + \ +static void *deadline_dispatch##prio##_next(struct seq_file *m, \ + void *v, loff_t *pos) \ +{ \ + struct request_queue *q = m->private; \ + struct deadline_data *dd = q->elevator->elevator_data; \ + struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ + \ + return seq_list_next(v, &per_prio->dispatch, pos); \ +} \ + \ +static void deadline_dispatch##prio##_stop(struct seq_file *m, void *v) \ + __releases(&dd->lock) \ +{ \ + struct request_queue *q = m->private; \ + struct deadline_data *dd = q->elevator->elevator_data; \ + \ + spin_unlock(&dd->lock); \ +} \ + \ +static const struct seq_operations deadline_dispatch##prio##_seq_ops = { \ + .start = deadline_dispatch##prio##_start, \ + .next = deadline_dispatch##prio##_next, \ + .stop = deadline_dispatch##prio##_stop, \ + .show = blk_mq_debugfs_rq_show, \ +} + +DEADLINE_DISPATCH_ATTR(0); +DEADLINE_DISPATCH_ATTR(1); +DEADLINE_DISPATCH_ATTR(2); +#undef DEADLINE_DISPATCH_ATTR + +#define DEADLINE_QUEUE_DDIR_ATTRS(name) \ + {#name "_fifo_list", 0400, \ + .seq_ops = &deadline_##name##_fifo_seq_ops} +#define DEADLINE_NEXT_RQ_ATTR(name) \ + {#name "_next_rq", 0400, deadline_##name##_next_rq_show} +static const struct blk_mq_debugfs_attr deadline_queue_debugfs_attrs[] = { + DEADLINE_QUEUE_DDIR_ATTRS(read0), + DEADLINE_QUEUE_DDIR_ATTRS(write0), + DEADLINE_QUEUE_DDIR_ATTRS(read1), + DEADLINE_QUEUE_DDIR_ATTRS(write1), + DEADLINE_QUEUE_DDIR_ATTRS(read2), + DEADLINE_QUEUE_DDIR_ATTRS(write2), + DEADLINE_NEXT_RQ_ATTR(read0), + DEADLINE_NEXT_RQ_ATTR(write0), + DEADLINE_NEXT_RQ_ATTR(read1), + DEADLINE_NEXT_RQ_ATTR(write1), + DEADLINE_NEXT_RQ_ATTR(read2), + DEADLINE_NEXT_RQ_ATTR(write2), + {"batching", 0400, deadline_batching_show}, + {"starved", 0400, deadline_starved_show}, + {"async_depth", 0400, dd_async_depth_show}, + {"dispatch0", 0400, .seq_ops = &deadline_dispatch0_seq_ops}, + {"dispatch1", 0400, .seq_ops = &deadline_dispatch1_seq_ops}, + {"dispatch2", 0400, .seq_ops = &deadline_dispatch2_seq_ops}, + {"owned_by_driver", 0400, dd_owned_by_driver_show}, + {"queued", 0400, dd_queued_show}, + {}, +}; +#undef DEADLINE_QUEUE_DDIR_ATTRS +#endif + +static struct elevator_type mq_deadline = { + .ops = { + .depth_updated = dd_depth_updated, + .limit_depth = dd_limit_depth, + .insert_requests = dd_insert_requests, + .dispatch_request = dd_dispatch_request, + .prepare_request = dd_prepare_request, + .finish_request = dd_finish_request, + .next_request = elv_rb_latter_request, + .former_request = elv_rb_former_request, + .bio_merge = dd_bio_merge, + .request_merge = dd_request_merge, + .requests_merged = dd_merged_requests, + .request_merged = dd_request_merged, + .has_work = dd_has_work, + .init_sched = dd_init_sched, + .exit_sched = dd_exit_sched, + .init_hctx = dd_init_hctx, + }, + +#ifdef CONFIG_BLK_DEBUG_FS + .queue_debugfs_attrs = deadline_queue_debugfs_attrs, +#endif + .elevator_attrs = deadline_attrs, + .elevator_name = "mq-deadline", + .elevator_alias = "deadline", + .elevator_features = ELEVATOR_F_ZBD_SEQ_WRITE, + .elevator_owner = THIS_MODULE, +}; +MODULE_ALIAS("mq-deadline-iosched"); + +static int __init deadline_init(void) +{ + int ret; + + ret = elv_register(&mq_deadline); + if (ret) + goto out; + ret = dd_blkcg_init(); + if (ret) + goto unreg; + +out: + return ret; + +unreg: + elv_unregister(&mq_deadline); + goto out; +} + +static void __exit deadline_exit(void) +{ + dd_blkcg_exit(); + elv_unregister(&mq_deadline); +} + +module_init(deadline_init); +module_exit(deadline_exit); + +MODULE_AUTHOR("Jens Axboe, Damien Le Moal and Bart Van Assche"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("MQ deadline IO scheduler"); diff --git a/block/mq-deadline.c b/block/mq-deadline.c deleted file mode 100644 index 2b9635d0dcba..000000000000 --- a/block/mq-deadline.c +++ /dev/null @@ -1,822 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * MQ Deadline i/o scheduler - adaptation of the legacy deadline scheduler, - * for the blk-mq scheduling framework - * - * Copyright (C) 2016 Jens Axboe - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "blk.h" -#include "blk-mq.h" -#include "blk-mq-debugfs.h" -#include "blk-mq-tag.h" -#include "blk-mq-sched.h" - -/* - * See Documentation/block/deadline-iosched.rst - */ -static const int read_expire = HZ / 2; /* max time before a read is submitted. */ -static const int write_expire = 5 * HZ; /* ditto for writes, these limits are SOFT! */ -static const int writes_starved = 2; /* max times reads can starve a write */ -static const int fifo_batch = 16; /* # of sequential requests treated as one - by the above parameters. For throughput. */ - -struct deadline_data { - /* - * run time data - */ - - /* - * requests (deadline_rq s) are present on both sort_list and fifo_list - */ - struct rb_root sort_list[2]; - struct list_head fifo_list[2]; - - /* - * next in sort order. read, write or both are NULL - */ - struct request *next_rq[2]; - unsigned int batching; /* number of sequential requests made */ - unsigned int starved; /* times reads have starved writes */ - - /* - * settings that change how the i/o scheduler behaves - */ - int fifo_expire[2]; - int fifo_batch; - int writes_starved; - int front_merges; - - spinlock_t lock; - spinlock_t zone_lock; - struct list_head dispatch; -}; - -static inline struct rb_root * -deadline_rb_root(struct deadline_data *dd, struct request *rq) -{ - return &dd->sort_list[rq_data_dir(rq)]; -} - -/* - * get the request after `rq' in sector-sorted order - */ -static inline struct request * -deadline_latter_request(struct request *rq) -{ - struct rb_node *node = rb_next(&rq->rb_node); - - if (node) - return rb_entry_rq(node); - - return NULL; -} - -static void -deadline_add_rq_rb(struct deadline_data *dd, struct request *rq) -{ - struct rb_root *root = deadline_rb_root(dd, rq); - - elv_rb_add(root, rq); -} - -static inline void -deadline_del_rq_rb(struct deadline_data *dd, struct request *rq) -{ - const int data_dir = rq_data_dir(rq); - - if (dd->next_rq[data_dir] == rq) - dd->next_rq[data_dir] = deadline_latter_request(rq); - - elv_rb_del(deadline_rb_root(dd, rq), rq); -} - -/* - * remove rq from rbtree and fifo. - */ -static void deadline_remove_request(struct request_queue *q, struct request *rq) -{ - struct deadline_data *dd = q->elevator->elevator_data; - - list_del_init(&rq->queuelist); - - /* - * We might not be on the rbtree, if we are doing an insert merge - */ - if (!RB_EMPTY_NODE(&rq->rb_node)) - deadline_del_rq_rb(dd, rq); - - elv_rqhash_del(q, rq); - if (q->last_merge == rq) - q->last_merge = NULL; -} - -static void dd_request_merged(struct request_queue *q, struct request *req, - enum elv_merge type) -{ - struct deadline_data *dd = q->elevator->elevator_data; - - /* - * if the merge was a front merge, we need to reposition request - */ - if (type == ELEVATOR_FRONT_MERGE) { - elv_rb_del(deadline_rb_root(dd, req), req); - deadline_add_rq_rb(dd, req); - } -} - -static void dd_merged_requests(struct request_queue *q, struct request *req, - struct request *next) -{ - /* - * if next expires before rq, assign its expire time to rq - * and move into next position (next will be deleted) in fifo - */ - if (!list_empty(&req->queuelist) && !list_empty(&next->queuelist)) { - if (time_before((unsigned long)next->fifo_time, - (unsigned long)req->fifo_time)) { - list_move(&req->queuelist, &next->queuelist); - req->fifo_time = next->fifo_time; - } - } - - /* - * kill knowledge of next, this one is a goner - */ - deadline_remove_request(q, next); -} - -/* - * move an entry to dispatch queue - */ -static void -deadline_move_request(struct deadline_data *dd, struct request *rq) -{ - const int data_dir = rq_data_dir(rq); - - dd->next_rq[READ] = NULL; - dd->next_rq[WRITE] = NULL; - dd->next_rq[data_dir] = deadline_latter_request(rq); - - /* - * take it off the sort and fifo list - */ - deadline_remove_request(rq->q, rq); -} - -/* - * deadline_check_fifo returns 0 if there are no expired requests on the fifo, - * 1 otherwise. Requires !list_empty(&dd->fifo_list[data_dir]) - */ -static inline int deadline_check_fifo(struct deadline_data *dd, int ddir) -{ - struct request *rq = rq_entry_fifo(dd->fifo_list[ddir].next); - - /* - * rq is expired! - */ - if (time_after_eq(jiffies, (unsigned long)rq->fifo_time)) - return 1; - - return 0; -} - -/* - * For the specified data direction, return the next request to - * dispatch using arrival ordered lists. - */ -static struct request * -deadline_fifo_request(struct deadline_data *dd, int data_dir) -{ - struct request *rq; - unsigned long flags; - - if (WARN_ON_ONCE(data_dir != READ && data_dir != WRITE)) - return NULL; - - if (list_empty(&dd->fifo_list[data_dir])) - return NULL; - - rq = rq_entry_fifo(dd->fifo_list[data_dir].next); - if (data_dir == READ || !blk_queue_is_zoned(rq->q)) - return rq; - - /* - * Look for a write request that can be dispatched, that is one with - * an unlocked target zone. - */ - spin_lock_irqsave(&dd->zone_lock, flags); - list_for_each_entry(rq, &dd->fifo_list[WRITE], queuelist) { - if (blk_req_can_dispatch_to_zone(rq)) - goto out; - } - rq = NULL; -out: - spin_unlock_irqrestore(&dd->zone_lock, flags); - - return rq; -} - -/* - * For the specified data direction, return the next request to - * dispatch using sector position sorted lists. - */ -static struct request * -deadline_next_request(struct deadline_data *dd, int data_dir) -{ - struct request *rq; - unsigned long flags; - - if (WARN_ON_ONCE(data_dir != READ && data_dir != WRITE)) - return NULL; - - rq = dd->next_rq[data_dir]; - if (!rq) - return NULL; - - if (data_dir == READ || !blk_queue_is_zoned(rq->q)) - return rq; - - /* - * Look for a write request that can be dispatched, that is one with - * an unlocked target zone. - */ - spin_lock_irqsave(&dd->zone_lock, flags); - while (rq) { - if (blk_req_can_dispatch_to_zone(rq)) - break; - rq = deadline_latter_request(rq); - } - spin_unlock_irqrestore(&dd->zone_lock, flags); - - return rq; -} - -/* - * deadline_dispatch_requests selects the best request according to - * read/write expire, fifo_batch, etc - */ -static struct request *__dd_dispatch_request(struct deadline_data *dd) -{ - struct request *rq, *next_rq; - bool reads, writes; - int data_dir; - - if (!list_empty(&dd->dispatch)) { - rq = list_first_entry(&dd->dispatch, struct request, queuelist); - list_del_init(&rq->queuelist); - goto done; - } - - reads = !list_empty(&dd->fifo_list[READ]); - writes = !list_empty(&dd->fifo_list[WRITE]); - - /* - * batches are currently reads XOR writes - */ - rq = deadline_next_request(dd, WRITE); - if (!rq) - rq = deadline_next_request(dd, READ); - - if (rq && dd->batching < dd->fifo_batch) - /* we have a next request are still entitled to batch */ - goto dispatch_request; - - /* - * at this point we are not running a batch. select the appropriate - * data direction (read / write) - */ - - if (reads) { - BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[READ])); - - if (deadline_fifo_request(dd, WRITE) && - (dd->starved++ >= dd->writes_starved)) - goto dispatch_writes; - - data_dir = READ; - - goto dispatch_find_request; - } - - /* - * there are either no reads or writes have been starved - */ - - if (writes) { -dispatch_writes: - BUG_ON(RB_EMPTY_ROOT(&dd->sort_list[WRITE])); - - dd->starved = 0; - - data_dir = WRITE; - - goto dispatch_find_request; - } - - return NULL; - -dispatch_find_request: - /* - * we are not running a batch, find best request for selected data_dir - */ - next_rq = deadline_next_request(dd, data_dir); - if (deadline_check_fifo(dd, data_dir) || !next_rq) { - /* - * A deadline has expired, the last request was in the other - * direction, or we have run out of higher-sectored requests. - * Start again from the request with the earliest expiry time. - */ - rq = deadline_fifo_request(dd, data_dir); - } else { - /* - * The last req was the same dir and we have a next request in - * sort order. No expired requests so continue on from here. - */ - rq = next_rq; - } - - /* - * For a zoned block device, if we only have writes queued and none of - * them can be dispatched, rq will be NULL. - */ - if (!rq) - return NULL; - - dd->batching = 0; - -dispatch_request: - /* - * rq is the selected appropriate request. - */ - dd->batching++; - deadline_move_request(dd, rq); -done: - /* - * If the request needs its target zone locked, do it. - */ - blk_req_zone_write_lock(rq); - rq->rq_flags |= RQF_STARTED; - return rq; -} - -/* - * One confusing aspect here is that we get called for a specific - * hardware queue, but we may return a request that is for a - * different hardware queue. This is because mq-deadline has shared - * state for all hardware queues, in terms of sorting, FIFOs, etc. - */ -static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) -{ - struct deadline_data *dd = hctx->queue->elevator->elevator_data; - struct request *rq; - - spin_lock(&dd->lock); - rq = __dd_dispatch_request(dd); - spin_unlock(&dd->lock); - if (rq) - atomic_dec(&rq->mq_hctx->elevator_queued); - - return rq; -} - -static void dd_exit_queue(struct elevator_queue *e) -{ - struct deadline_data *dd = e->elevator_data; - - BUG_ON(!list_empty(&dd->fifo_list[READ])); - BUG_ON(!list_empty(&dd->fifo_list[WRITE])); - - kfree(dd); -} - -/* - * initialize elevator private data (deadline_data). - */ -static int dd_init_queue(struct request_queue *q, struct elevator_type *e) -{ - struct deadline_data *dd; - struct elevator_queue *eq; - - eq = elevator_alloc(q, e); - if (!eq) - return -ENOMEM; - - dd = kzalloc_node(sizeof(*dd), GFP_KERNEL, q->node); - if (!dd) { - kobject_put(&eq->kobj); - return -ENOMEM; - } - eq->elevator_data = dd; - - INIT_LIST_HEAD(&dd->fifo_list[READ]); - INIT_LIST_HEAD(&dd->fifo_list[WRITE]); - dd->sort_list[READ] = RB_ROOT; - dd->sort_list[WRITE] = RB_ROOT; - dd->fifo_expire[READ] = read_expire; - dd->fifo_expire[WRITE] = write_expire; - dd->writes_starved = writes_starved; - dd->front_merges = 1; - dd->fifo_batch = fifo_batch; - spin_lock_init(&dd->lock); - spin_lock_init(&dd->zone_lock); - INIT_LIST_HEAD(&dd->dispatch); - - q->elevator = eq; - return 0; -} - -static int dd_request_merge(struct request_queue *q, struct request **rq, - struct bio *bio) -{ - struct deadline_data *dd = q->elevator->elevator_data; - sector_t sector = bio_end_sector(bio); - struct request *__rq; - - if (!dd->front_merges) - return ELEVATOR_NO_MERGE; - - __rq = elv_rb_find(&dd->sort_list[bio_data_dir(bio)], sector); - if (__rq) { - BUG_ON(sector != blk_rq_pos(__rq)); - - if (elv_bio_merge_ok(__rq, bio)) { - *rq = __rq; - return ELEVATOR_FRONT_MERGE; - } - } - - return ELEVATOR_NO_MERGE; -} - -static bool dd_bio_merge(struct request_queue *q, struct bio *bio, - unsigned int nr_segs) -{ - struct deadline_data *dd = q->elevator->elevator_data; - struct request *free = NULL; - bool ret; - - spin_lock(&dd->lock); - ret = blk_mq_sched_try_merge(q, bio, nr_segs, &free); - spin_unlock(&dd->lock); - - if (free) - blk_mq_free_request(free); - - return ret; -} - -/* - * add rq to rbtree and fifo - */ -static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, - bool at_head) -{ - struct request_queue *q = hctx->queue; - struct deadline_data *dd = q->elevator->elevator_data; - const int data_dir = rq_data_dir(rq); - - /* - * This may be a requeue of a write request that has locked its - * target zone. If it is the case, this releases the zone lock. - */ - blk_req_zone_write_unlock(rq); - - if (blk_mq_sched_try_insert_merge(q, rq)) - return; - - blk_mq_sched_request_inserted(rq); - - if (at_head || blk_rq_is_passthrough(rq)) { - if (at_head) - list_add(&rq->queuelist, &dd->dispatch); - else - list_add_tail(&rq->queuelist, &dd->dispatch); - } else { - deadline_add_rq_rb(dd, rq); - - if (rq_mergeable(rq)) { - elv_rqhash_add(q, rq); - if (!q->last_merge) - q->last_merge = rq; - } - - /* - * set expire time and add to fifo list - */ - rq->fifo_time = jiffies + dd->fifo_expire[data_dir]; - list_add_tail(&rq->queuelist, &dd->fifo_list[data_dir]); - } -} - -static void dd_insert_requests(struct blk_mq_hw_ctx *hctx, - struct list_head *list, bool at_head) -{ - struct request_queue *q = hctx->queue; - struct deadline_data *dd = q->elevator->elevator_data; - - spin_lock(&dd->lock); - while (!list_empty(list)) { - struct request *rq; - - rq = list_first_entry(list, struct request, queuelist); - list_del_init(&rq->queuelist); - dd_insert_request(hctx, rq, at_head); - atomic_inc(&hctx->elevator_queued); - } - spin_unlock(&dd->lock); -} - -/* - * Nothing to do here. This is defined only to ensure that .finish_request - * method is called upon request completion. - */ -static void dd_prepare_request(struct request *rq) -{ -} - -/* - * For zoned block devices, write unlock the target zone of - * completed write requests. Do this while holding the zone lock - * spinlock so that the zone is never unlocked while deadline_fifo_request() - * or deadline_next_request() are executing. This function is called for - * all requests, whether or not these requests complete successfully. - * - * For a zoned block device, __dd_dispatch_request() may have stopped - * dispatching requests if all the queued requests are write requests directed - * at zones that are already locked due to on-going write requests. To ensure - * write request dispatch progress in this case, mark the queue as needing a - * restart to ensure that the queue is run again after completion of the - * request and zones being unlocked. - */ -static void dd_finish_request(struct request *rq) -{ - struct request_queue *q = rq->q; - - if (blk_queue_is_zoned(q)) { - struct deadline_data *dd = q->elevator->elevator_data; - unsigned long flags; - - spin_lock_irqsave(&dd->zone_lock, flags); - blk_req_zone_write_unlock(rq); - if (!list_empty(&dd->fifo_list[WRITE])) - blk_mq_sched_mark_restart_hctx(rq->mq_hctx); - spin_unlock_irqrestore(&dd->zone_lock, flags); - } -} - -static bool dd_has_work(struct blk_mq_hw_ctx *hctx) -{ - struct deadline_data *dd = hctx->queue->elevator->elevator_data; - - if (!atomic_read(&hctx->elevator_queued)) - return false; - - return !list_empty_careful(&dd->dispatch) || - !list_empty_careful(&dd->fifo_list[0]) || - !list_empty_careful(&dd->fifo_list[1]); -} - -/* - * sysfs parts below - */ -static ssize_t -deadline_var_show(int var, char *page) -{ - return sprintf(page, "%d\n", var); -} - -static void -deadline_var_store(int *var, const char *page) -{ - char *p = (char *) page; - - *var = simple_strtol(p, &p, 10); -} - -#define SHOW_FUNCTION(__FUNC, __VAR, __CONV) \ -static ssize_t __FUNC(struct elevator_queue *e, char *page) \ -{ \ - struct deadline_data *dd = e->elevator_data; \ - int __data = __VAR; \ - if (__CONV) \ - __data = jiffies_to_msecs(__data); \ - return deadline_var_show(__data, (page)); \ -} -SHOW_FUNCTION(deadline_read_expire_show, dd->fifo_expire[READ], 1); -SHOW_FUNCTION(deadline_write_expire_show, dd->fifo_expire[WRITE], 1); -SHOW_FUNCTION(deadline_writes_starved_show, dd->writes_starved, 0); -SHOW_FUNCTION(deadline_front_merges_show, dd->front_merges, 0); -SHOW_FUNCTION(deadline_fifo_batch_show, dd->fifo_batch, 0); -#undef SHOW_FUNCTION - -#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV) \ -static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count) \ -{ \ - struct deadline_data *dd = e->elevator_data; \ - int __data; \ - deadline_var_store(&__data, (page)); \ - if (__data < (MIN)) \ - __data = (MIN); \ - else if (__data > (MAX)) \ - __data = (MAX); \ - if (__CONV) \ - *(__PTR) = msecs_to_jiffies(__data); \ - else \ - *(__PTR) = __data; \ - return count; \ -} -STORE_FUNCTION(deadline_read_expire_store, &dd->fifo_expire[READ], 0, INT_MAX, 1); -STORE_FUNCTION(deadline_write_expire_store, &dd->fifo_expire[WRITE], 0, INT_MAX, 1); -STORE_FUNCTION(deadline_writes_starved_store, &dd->writes_starved, INT_MIN, INT_MAX, 0); -STORE_FUNCTION(deadline_front_merges_store, &dd->front_merges, 0, 1, 0); -STORE_FUNCTION(deadline_fifo_batch_store, &dd->fifo_batch, 0, INT_MAX, 0); -#undef STORE_FUNCTION - -#define DD_ATTR(name) \ - __ATTR(name, 0644, deadline_##name##_show, deadline_##name##_store) - -static struct elv_fs_entry deadline_attrs[] = { - DD_ATTR(read_expire), - DD_ATTR(write_expire), - DD_ATTR(writes_starved), - DD_ATTR(front_merges), - DD_ATTR(fifo_batch), - __ATTR_NULL -}; - -#ifdef CONFIG_BLK_DEBUG_FS -#define DEADLINE_DEBUGFS_DDIR_ATTRS(ddir, name) \ -static void *deadline_##name##_fifo_start(struct seq_file *m, \ - loff_t *pos) \ - __acquires(&dd->lock) \ -{ \ - struct request_queue *q = m->private; \ - struct deadline_data *dd = q->elevator->elevator_data; \ - \ - spin_lock(&dd->lock); \ - return seq_list_start(&dd->fifo_list[ddir], *pos); \ -} \ - \ -static void *deadline_##name##_fifo_next(struct seq_file *m, void *v, \ - loff_t *pos) \ -{ \ - struct request_queue *q = m->private; \ - struct deadline_data *dd = q->elevator->elevator_data; \ - \ - return seq_list_next(v, &dd->fifo_list[ddir], pos); \ -} \ - \ -static void deadline_##name##_fifo_stop(struct seq_file *m, void *v) \ - __releases(&dd->lock) \ -{ \ - struct request_queue *q = m->private; \ - struct deadline_data *dd = q->elevator->elevator_data; \ - \ - spin_unlock(&dd->lock); \ -} \ - \ -static const struct seq_operations deadline_##name##_fifo_seq_ops = { \ - .start = deadline_##name##_fifo_start, \ - .next = deadline_##name##_fifo_next, \ - .stop = deadline_##name##_fifo_stop, \ - .show = blk_mq_debugfs_rq_show, \ -}; \ - \ -static int deadline_##name##_next_rq_show(void *data, \ - struct seq_file *m) \ -{ \ - struct request_queue *q = data; \ - struct deadline_data *dd = q->elevator->elevator_data; \ - struct request *rq = dd->next_rq[ddir]; \ - \ - if (rq) \ - __blk_mq_debugfs_rq_show(m, rq); \ - return 0; \ -} -DEADLINE_DEBUGFS_DDIR_ATTRS(READ, read) -DEADLINE_DEBUGFS_DDIR_ATTRS(WRITE, write) -#undef DEADLINE_DEBUGFS_DDIR_ATTRS - -static int deadline_batching_show(void *data, struct seq_file *m) -{ - struct request_queue *q = data; - struct deadline_data *dd = q->elevator->elevator_data; - - seq_printf(m, "%u\n", dd->batching); - return 0; -} - -static int deadline_starved_show(void *data, struct seq_file *m) -{ - struct request_queue *q = data; - struct deadline_data *dd = q->elevator->elevator_data; - - seq_printf(m, "%u\n", dd->starved); - return 0; -} - -static void *deadline_dispatch_start(struct seq_file *m, loff_t *pos) - __acquires(&dd->lock) -{ - struct request_queue *q = m->private; - struct deadline_data *dd = q->elevator->elevator_data; - - spin_lock(&dd->lock); - return seq_list_start(&dd->dispatch, *pos); -} - -static void *deadline_dispatch_next(struct seq_file *m, void *v, loff_t *pos) -{ - struct request_queue *q = m->private; - struct deadline_data *dd = q->elevator->elevator_data; - - return seq_list_next(v, &dd->dispatch, pos); -} - -static void deadline_dispatch_stop(struct seq_file *m, void *v) - __releases(&dd->lock) -{ - struct request_queue *q = m->private; - struct deadline_data *dd = q->elevator->elevator_data; - - spin_unlock(&dd->lock); -} - -static const struct seq_operations deadline_dispatch_seq_ops = { - .start = deadline_dispatch_start, - .next = deadline_dispatch_next, - .stop = deadline_dispatch_stop, - .show = blk_mq_debugfs_rq_show, -}; - -#define DEADLINE_QUEUE_DDIR_ATTRS(name) \ - {#name "_fifo_list", 0400, .seq_ops = &deadline_##name##_fifo_seq_ops}, \ - {#name "_next_rq", 0400, deadline_##name##_next_rq_show} -static const struct blk_mq_debugfs_attr deadline_queue_debugfs_attrs[] = { - DEADLINE_QUEUE_DDIR_ATTRS(read), - DEADLINE_QUEUE_DDIR_ATTRS(write), - {"batching", 0400, deadline_batching_show}, - {"starved", 0400, deadline_starved_show}, - {"dispatch", 0400, .seq_ops = &deadline_dispatch_seq_ops}, - {}, -}; -#undef DEADLINE_QUEUE_DDIR_ATTRS -#endif - -static struct elevator_type mq_deadline = { - .ops = { - .insert_requests = dd_insert_requests, - .dispatch_request = dd_dispatch_request, - .prepare_request = dd_prepare_request, - .finish_request = dd_finish_request, - .next_request = elv_rb_latter_request, - .former_request = elv_rb_former_request, - .bio_merge = dd_bio_merge, - .request_merge = dd_request_merge, - .requests_merged = dd_merged_requests, - .request_merged = dd_request_merged, - .has_work = dd_has_work, - .init_sched = dd_init_queue, - .exit_sched = dd_exit_queue, - }, - -#ifdef CONFIG_BLK_DEBUG_FS - .queue_debugfs_attrs = deadline_queue_debugfs_attrs, -#endif - .elevator_attrs = deadline_attrs, - .elevator_name = "mq-deadline", - .elevator_alias = "deadline", - .elevator_features = ELEVATOR_F_ZBD_SEQ_WRITE, - .elevator_owner = THIS_MODULE, -}; -MODULE_ALIAS("mq-deadline-iosched"); - -static int __init deadline_init(void) -{ - return elv_register(&mq_deadline); -} - -static void __exit deadline_exit(void) -{ - elv_unregister(&mq_deadline); -} - -module_init(deadline_init); -module_exit(deadline_exit); - -MODULE_AUTHOR("Jens Axboe"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MQ deadline IO scheduler"); diff --git a/build.config.common b/build.config.common index f6492831a7be..b321ae20ecea 100644 --- a/build.config.common +++ b/build.config.common @@ -1,5 +1,5 @@ BRANCH=android12-5.10 -KMI_GENERATION=6 +KMI_GENERATION=9 LLVM=1 DEPMOD=depmod diff --git a/build.config.gki.aarch64 b/build.config.gki.aarch64 index e0ffb8869dc0..55229d9912a9 100644 --- a/build.config.gki.aarch64 +++ b/build.config.gki.aarch64 @@ -7,18 +7,24 @@ Image.lz4 " ABI_DEFINITION=android/abi_gki_aarch64.xml +TIDY_ABI=1 KMI_SYMBOL_LIST=android/abi_gki_aarch64 ADDITIONAL_KMI_SYMBOL_LISTS=" android/abi_gki_aarch64_core android/abi_gki_aarch64_db845c -android/abi_gki_aarch64_qcom -android/abi_gki_aarch64_virtual_device -android/abi_gki_aarch64_hikey960 -android/abi_gki_aarch64_generic android/abi_gki_aarch64_exynos -android/abi_gki_aarch64_mtk -android/abi_gki_aarch64_xiaomi +android/abi_gki_aarch64_exynosauto android/abi_gki_aarch64_fips140 +android/abi_gki_aarch64_galaxy +android/abi_gki_aarch64_generic +android/abi_gki_aarch64_hikey960 +android/abi_gki_aarch64_mtk +android/abi_gki_aarch64_oplus +android/abi_gki_aarch64_qcom +android/abi_gki_aarch64_rockchip +android/abi_gki_aarch64_virtual_device +android/abi_gki_aarch64_vivo +android/abi_gki_aarch64_xiaomi " FILES="${FILES} diff --git a/crypto/Kconfig b/crypto/Kconfig index ca514e82431a..d726b1c3a7f8 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -32,13 +32,35 @@ config CRYPTO_FIPS certification. You should say no unless you know what this is. +# CRYPTO_FIPS140 just enables the support in the kernel for loading fips140.ko. +# The module still needs to be built and loaded if you need FIPS 140 compliance. config CRYPTO_FIPS140 def_bool y depends on MODULES && ARM64 && ARM64_MODULE_PLTS config CRYPTO_FIPS140_MOD - bool "Enable FIPS140 integrity self-checked loadable module" + bool "Enable FIPS 140 cryptographic module" depends on LTO_CLANG && CRYPTO_FIPS140 + help + This option enables building a loadable module fips140.ko, which + contains various crypto algorithms that are also built into vmlinux. + At load time, this module overrides the built-in implementations of + these algorithms with its implementations. It also runs self-tests on + these algorithms and verifies the integrity of its code and data. If + either of these steps fails, the kernel will panic. + + This module is intended to be loaded at early boot time in order to + meet FIPS 140 and NIAP FPT_TST_EXT.1 requirements. It shouldn't be + used if you don't need to meet these requirements. + +config CRYPTO_FIPS140_MOD_ERROR_INJECTION + bool "Support injecting failures into the FIPS 140 self-tests" + depends on CRYPTO_FIPS140_MOD + help + This option adds a module parameter "broken_alg" to the fips140 module + which can be used to fail the self-tests for a particular algorithm, + causing a kernel panic. This option is for FIPS lab testing only, and + it shouldn't be enabled on production systems. config CRYPTO_ALGAPI tristate diff --git a/crypto/Makefile b/crypto/Makefile index 63874cb2d4d4..aff52de1f84b 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -228,7 +228,7 @@ $(obj)/lib-crypto-%-fips.o: $(srctree)/lib/crypto/%.c FORCE $(obj)/crypto-fips.a: $(addprefix $(obj)/,$(crypto-fips-objs)) FORCE $(call if_changed,ar_and_symver) -fips140-objs := fips140-module.o crypto-fips.a +fips140-objs := fips140-module.o fips140-selftests.o crypto-fips.a obj-m += fips140.o CFLAGS_fips140-module.o += $(FIPS140_CFLAGS) diff --git a/crypto/OWNERS b/crypto/OWNERS deleted file mode 100644 index f74b7ed228f7..000000000000 --- a/crypto/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/crypto/OWNERS diff --git a/crypto/fips140-generated-testvecs.h b/crypto/fips140-generated-testvecs.h new file mode 100644 index 000000000000..9328e9bacca7 --- /dev/null +++ b/crypto/fips140-generated-testvecs.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright 2021 Google LLC */ + +/* + * This header was automatically generated by gen_fips140_testvecs.py. + * Don't edit it directly. + */ + +static const u8 fips_message[32] __initconst = + "This is a 32-byte test message."; + +static const u8 fips_aes_key[16] __initconst = "128-bit AES key"; + +static const u8 fips_aes_iv[16] __initconst = "ABCDEFGHIJKL"; + +static const u8 fips_aes_cbc_ciphertext[32] __initconst = + "\xc4\x6d\xad\xa4\x04\x52\x11\x5a\x7a\xb3\x7c\x68\x85\x8d\x90\xf0" + "\x55\xc3\xd3\x35\xc1\x75\x31\x90\xdf\x90\x4b\x5a\x56\xfd\xa7\x89"; + +static const u8 fips_aes_ecb_ciphertext[32] __initconst = + "\xc1\x9d\xe6\xb8\xb2\x90\xff\xfe\xf2\x77\x18\xb0\x55\xd3\xee\xa9" + "\xe2\x6f\x4a\x32\x67\xfd\xb7\xa5\x2f\x4b\x6e\x1a\x86\x2b\x6e\x3a"; + +static const u8 fips_aes_ctr_ciphertext[32] __initconst = + "\x92\xbe\x23\xa1\x80\x88\x5d\x31\x27\xb3\x9c\x40\x58\x57\x1d\xde" + "\xc1\x8d\x5b\xe7\x42\x93\x09\xf8\xd4\xf7\x49\x42\xcf\x40\x62\x7e"; + +static const u8 fips_aes_gcm_assoc[22] __initconst = "associated data string"; + +static const u8 fips_aes_gcm_ciphertext[48] __initconst = + "\x37\x88\x3e\x1d\x58\x50\xda\x10\x07\xeb\x52\xdf\xea\x0a\x54\xd4" + "\x44\xbf\x88\x2a\xf3\x03\x03\x84\xaf\x8b\x96\xbd\xea\x65\x60\x6f" + "\x82\xfa\x51\xf4\x28\xad\x0c\xf1\xce\x0f\x91\xdd\x1a\x4c\x77\x5f"; + +static const u8 fips_aes_xts_key[32] __initconst = + "This is an AES-128-XTS key."; + +static const u8 fips_aes_xts_ciphertext[32] __initconst = + "\x5e\xb9\x98\xd6\x26\xb3\x55\xbf\x44\xab\x3e\xae\x73\xc0\x81\xc9" + "\xf4\x29\x0e\x17\x1e\xc5\xc8\x90\x79\x99\xf1\x43\x3a\x23\x08\x5a"; + +static const u8 fips_hmac_key[16] __initconst = "128-bit HMAC key"; + +static const u8 fips_sha1_digest[20] __initconst = + "\x1b\x78\xc7\x4b\xd5\xd4\x83\xb1\x58\xc5\x96\x83\x4f\x16\x8d\x15" + "\xb4\xaa\x22\x8c"; + +static const u8 fips_sha256_digest[32] __initconst = + "\x4e\x11\x83\x0c\x53\x80\x1e\x5f\x9b\x38\x33\x38\xe8\x74\x43\xb0" + "\xc1\x3a\xbe\xbf\x75\xf0\x12\x0f\x21\x33\xf5\x16\x33\xf1\xb0\x81"; + +static const u8 fips_hmac_sha256_digest[32] __initconst = + "\x63\x0e\xb5\x73\x79\xfc\xaf\x5f\x86\xe3\xaf\xf0\xc8\x36\xef\xd5" + "\x35\x8d\x40\x25\x38\xb3\x65\x72\x98\xf3\x59\xd8\x1e\x54\x4c\xa1"; + +static const u8 fips_sha512_digest[64] __initconst = + "\x32\xe0\x44\x23\xbd\xe3\xec\x28\xbf\xf1\x34\x11\xd5\xae\xbf\xd5" + "\xc0\x8e\xb5\xa1\x04\xef\x2f\x07\x84\xf1\xd9\x83\x0f\x6c\x31\xab" + "\xf7\xe7\x57\xfa\xf7\xae\xf0\x6f\xb2\x16\x08\x32\xcf\xc7\xef\x35" + "\xb3\x3b\x51\xb9\xfd\xe7\xff\x5e\xb2\x8b\xc6\x79\xe6\x14\x04\xb4"; + +/* + * This header was automatically generated by gen_fips140_testvecs.py. + * Don't edit it directly. + */ diff --git a/crypto/fips140-module.c b/crypto/fips140-module.c index 2b3ecd4bea5a..a91735c37c67 100644 --- a/crypto/fips140-module.c +++ b/crypto/fips140-module.c @@ -3,16 +3,17 @@ * Copyright 2021 Google LLC * Author: Ard Biesheuvel * - * This file is the core of the fips140.ko, which carries a number of crypto - * algorithms and chaining mode templates that are also built into vmlinux. - * This modules performs a load time integrity check, as mandated by FIPS 140, - * and replaces registered crypto algorithms that appear on the FIPS 140 list - * with ones provided by this module. This meets the FIPS 140 requirements for - * a cryptographic software module. + * This file is the core of fips140.ko, which contains various crypto algorithms + * that are also built into vmlinux. At load time, this module overrides the + * built-in implementations of these algorithms with its implementations. It + * also runs self-tests on these algorithms and verifies the integrity of its + * code and data. If either of these steps fails, the kernel will panic. + * + * This module is intended to be loaded at early boot time in order to meet + * FIPS 140 and NIAP FPT_TST_EXT.1 requirements. It shouldn't be used if you + * don't need to meet these requirements. */ -#define pr_fmt(fmt) "fips140: " fmt - #include #include #include @@ -23,8 +24,18 @@ #include #include +#include "fips140-module.h" #include "internal.h" +/* + * This option allows deliberately failing the self-tests for a particular + * algorithm. This is for FIPS lab testing only. + */ +#ifdef CONFIG_CRYPTO_FIPS140_MOD_ERROR_INJECTION +char *fips140_broken_alg; +module_param_named(broken_alg, fips140_broken_alg, charp, 0); +#endif + /* * FIPS 140-2 prefers the use of HMAC with a public key over a plain hash. */ @@ -52,7 +63,13 @@ const u32 *__initcall_start = &__initcall_start_marker; const u8 *__text_start = &__fips140_text_start; const u8 *__rodata_start = &__fips140_rodata_start; -static const char fips140_algorithms[][22] __initconst = { +/* + * The list of the crypto API algorithms (by cra_name) that will be unregistered + * by this module, in preparation for the module registering its own + * implementation(s) of them. When adding a new algorithm here, make sure to + * consider whether it needs a self-test added to fips140_selftests[] as well. + */ +static const char * const fips140_algorithms[] __initconst = { "aes", "gcm(aes)", @@ -73,28 +90,7 @@ static const char fips140_algorithms[][22] __initconst = { "sha384", "sha512", - "drbg_nopr_ctr_aes256", - "drbg_nopr_ctr_aes192", - "drbg_nopr_ctr_aes128", - "drbg_nopr_hmac_sha512", - "drbg_nopr_hmac_sha384", - "drbg_nopr_hmac_sha256", - "drbg_nopr_hmac_sha1", - "drbg_nopr_sha512", - "drbg_nopr_sha384", - "drbg_nopr_sha256", - "drbg_nopr_sha1", - "drbg_pr_ctr_aes256", - "drbg_pr_ctr_aes192", - "drbg_pr_ctr_aes128", - "drbg_pr_hmac_sha512", - "drbg_pr_hmac_sha384", - "drbg_pr_hmac_sha256", - "drbg_pr_hmac_sha1", - "drbg_pr_sha512", - "drbg_pr_sha384", - "drbg_pr_sha256", - "drbg_pr_sha1", + "stdrng", }; static bool __init is_fips140_algo(struct crypto_alg *alg) @@ -116,6 +112,38 @@ static bool __init is_fips140_algo(struct crypto_alg *alg) static LIST_HEAD(unchecked_fips140_algos); +/* + * Release a list of algorithms which have been removed from crypto_alg_list. + * + * Note that even though the list is a private list, we have to hold + * crypto_alg_sem while iterating through it because crypto_unregister_alg() may + * run concurrently (as we haven't taken a reference to the algorithms on the + * list), and crypto_unregister_alg() will remove the algorithm from whichever + * list it happens to be on, while holding crypto_alg_sem. That's okay, since + * in that case crypto_unregister_alg() will handle the crypto_alg_put(). + */ +static void fips140_remove_final(struct list_head *list) +{ + struct crypto_alg *alg; + struct crypto_alg *n; + + /* + * We need to take crypto_alg_sem to safely traverse the list (see + * comment above), but we have to drop it when doing each + * crypto_alg_put() as that may take crypto_alg_sem again. + */ + down_write(&crypto_alg_sem); + list_for_each_entry_safe(alg, n, list, cra_list) { + list_del_init(&alg->cra_list); + up_write(&crypto_alg_sem); + + crypto_alg_put(alg); + + down_write(&crypto_alg_sem); + } + up_write(&crypto_alg_sem); +} + static void __init unregister_existing_fips140_algos(void) { struct crypto_alg *alg, *tmp; @@ -152,25 +180,17 @@ static void __init unregister_existing_fips140_algos(void) * transformations. We will swap these out * later with integrity checked versions. */ + pr_info("found already-live algorithm '%s' ('%s')\n", + alg->cra_name, alg->cra_driver_name); list_move(&alg->cra_list, &unchecked_fips140_algos); } } } - - /* - * We haven't taken a reference to the algorithms on the remove_list, - * so technically, we may be competing with a concurrent invocation of - * crypto_unregister_alg() here. Fortunately, crypto_unregister_alg() - * just gives up with a warning if the algo that is being unregistered - * has already disappeared, so this happens to be safe. That does mean - * we need to hold on to the lock, to ensure that the algo is either on - * the list or it is not, and not in some limbo state. - */ - crypto_remove_final(&remove_list); - crypto_remove_final(&spawns); - up_write(&crypto_alg_sem); + + fips140_remove_final(&remove_list); + fips140_remove_final(&spawns); } static void __init unapply_text_relocations(void *section, int section_size, @@ -250,8 +270,8 @@ static bool __init check_fips140_module_hmac(void) textsize = &__fips140_text_end - &__fips140_text_start; rodatasize = &__fips140_rodata_end - &__fips140_rodata_start; - pr_warn("text size : 0x%x\n", textsize); - pr_warn("rodata size: 0x%x\n", rodatasize); + pr_info("text size : 0x%x\n", textsize); + pr_info("rodata size: 0x%x\n", rodatasize); textcopy = kmalloc(textsize + rodatasize, GFP_KERNEL); if (!textcopy) { @@ -283,7 +303,7 @@ static bool __init check_fips140_module_hmac(void) return false; } - pr_warn("using '%s' for integrity check\n", + pr_info("using '%s' for integrity check\n", crypto_shash_driver_name(desc->tfm)); err = crypto_shash_setkey(desc->tfm, fips140_integ_hmac_key, @@ -523,11 +543,12 @@ static bool update_fips140_library_routines(void) * let's disable CFI locally when handling the initcall array, to avoid * surpises. */ -int __init __attribute__((__no_sanitize__("cfi"))) fips140_init(void) +static int __init __attribute__((__no_sanitize__("cfi"))) +fips140_init(void) { const u32 *initcall; - pr_info("Loading FIPS 140 module\n"); + pr_info("loading module\n"); unregister_existing_fips140_algos(); @@ -536,8 +557,17 @@ int __init __attribute__((__no_sanitize__("cfi"))) fips140_init(void) initcall < &__initcall_end_marker; initcall++) { int (*init)(void) = offset_to_ptr(initcall); + int err = init(); - init(); + /* + * ENODEV is expected from initcalls that only register + * algorithms that depend on non-present CPU features. Besides + * that, errors aren't expected here. + */ + if (err && err != -ENODEV) { + pr_err("initcall %ps() failed: %d\n", init, err); + goto panic; + } } if (!update_live_fips140_algos()) @@ -553,22 +583,25 @@ int __init __attribute__((__no_sanitize__("cfi"))) fips140_init(void) */ synchronize_rcu_tasks(); - /* insert self tests here */ + if (!fips140_run_selftests()) + goto panic; /* * It may seem backward to perform the integrity check last, but this * is intentional: the check itself uses hmac(sha256) which is one of * the algorithms that are replaced with versions from this module, and - * the integrity check must use the replacement version. + * the integrity check must use the replacement version. Also, to be + * ready for FIPS 140-3, the integrity check algorithm must have already + * been self-tested. */ if (!check_fips140_module_hmac()) { - pr_crit("FIPS 140 integrity check failed -- giving up!\n"); + pr_crit("integrity check failed -- giving up!\n"); goto panic; } + pr_info("integrity check passed\n"); - pr_info("FIPS 140 integrity check successful\n"); - pr_info("FIPS 140 module successfully loaded\n"); + pr_info("module successfully loaded\n"); return 0; panic: diff --git a/crypto/fips140-module.h b/crypto/fips140-module.h new file mode 100644 index 000000000000..b30a2e2928a6 --- /dev/null +++ b/crypto/fips140-module.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2021 Google LLC + */ + +#ifndef _CRYPTO_FIPS140_MODULE_H +#define _CRYPTO_FIPS140_MODULE_H + +#include + +#undef pr_fmt +#define pr_fmt(fmt) "fips140: " fmt + +#ifdef CONFIG_CRYPTO_FIPS140_MOD_ERROR_INJECTION +extern char *fips140_broken_alg; +#endif + +bool __init __must_check fips140_run_selftests(void); + +#endif /* _CRYPTO_FIPS140_MODULE_H */ diff --git a/crypto/fips140-selftests.c b/crypto/fips140-selftests.c new file mode 100644 index 000000000000..3ebf5a914cf0 --- /dev/null +++ b/crypto/fips140-selftests.c @@ -0,0 +1,867 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2021 Google LLC + * + * Authors: Elena Petrova , + * Eric Biggers + * + * Self-tests of fips140.ko cryptographic functionality. These are run at + * module load time to fulfill FIPS 140 and NIAP FPT_TST_EXT.1 requirements. + * + * The actual requirements for these self-tests are somewhat vague, but + * section 9 ("Self-Tests") of the FIPS 140-2 Implementation Guidance document + * (https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/fips140-2/fips1402ig.pdf) + * is somewhat helpful. Basically, all implementations of all FIPS approved + * algorithms (including modes of operation) must be tested. However: + * + * - If an implementation won't be used, it doesn't have to be tested. So + * when multiple implementations of the same algorithm are registered with + * the crypto API, we only have to test the default (highest-priority) one. + * + * - There are provisions for skipping tests that are already sufficiently + * covered by other tests. E.g., HMAC-SHA256 may cover SHA-256. + * + * - Only one test vector is required per algorithm, and it can be generated + * by any known-good implementation or taken from any official document. + * + * - For ciphers, both encryption and decryption must be tested. + * + * - Only one key size per algorithm needs to be tested. + * + * See fips140_selftests[] for the list of tests we've selected. Currently, all + * our test vectors except the DRBG ones were generated by the script + * tools/crypto/gen_fips140_testvecs.py, using the known-good implementations in + * the Python packages hashlib, pycryptodome, and cryptography. The DRBG test + * vectors were manually extracted from + * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip. + * + * Note that we don't reuse the upstream crypto API's self-tests + * (crypto/testmgr.{c,h}), for several reasons: + * + * - To meet FIPS requirements, the self-tests must be located within the FIPS + * module boundary (fips140.ko). But testmgr is integrated into the crypto + * API framework and can't be extracted into the module. + * + * - testmgr is much more heavyweight than required for FIPS and NIAP; it + * tests more algorithms and does more tests per algorithm, as it's meant to + * do proper testing and not just meet certification requirements. We need + * tests that can run with minimal overhead on every boot-up. + * + * - Despite being more heavyweight in general, testmgr doesn't test the + * SHA-256 and AES library APIs, despite that being needed here. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fips140-module.h" + +/* Test vector for a block cipher algorithm */ +struct blockcipher_testvec { + const u8 *key; + size_t key_size; + const u8 *plaintext; + const u8 *ciphertext; + size_t block_size; +}; + +/* Test vector for an AEAD algorithm */ +struct aead_testvec { + const u8 *key; + size_t key_size; + const u8 *iv; + size_t iv_size; + const u8 *assoc; + size_t assoc_size; + const u8 *plaintext; + size_t plaintext_size; + const u8 *ciphertext; + size_t ciphertext_size; +}; + +/* Test vector for a length-preserving encryption algorithm */ +struct skcipher_testvec { + const u8 *key; + size_t key_size; + const u8 *iv; + size_t iv_size; + const u8 *plaintext; + const u8 *ciphertext; + size_t message_size; +}; + +/* Test vector for a hash algorithm */ +struct hash_testvec { + const u8 *key; + size_t key_size; + const u8 *message; + size_t message_size; + const u8 *digest; + size_t digest_size; +}; + +/* Test vector for a DRBG algorithm */ +struct drbg_testvec { + const u8 *entropy; + size_t entropy_size; + const u8 *pers; + size_t pers_size; + const u8 *entpr_a; + const u8 *entpr_b; + size_t entpr_size; + const u8 *add_a; + const u8 *add_b; + size_t add_size; + const u8 *output; + size_t out_size; +}; + +/* + * A struct which specifies an algorithm name (using crypto API syntax), a test + * function for that algorithm, and a test vector used by that test function. + */ +struct fips_test { + const char *alg; + int __must_check (*func)(const struct fips_test *test); + union { + struct blockcipher_testvec blockcipher; + struct aead_testvec aead; + struct skcipher_testvec skcipher; + struct hash_testvec hash; + struct drbg_testvec drbg; + }; +}; + +/* Maximum IV size (in bytes) among any algorithm tested here */ +#define MAX_IV_SIZE 16 + +static int __init __must_check +fips_check_result(const struct fips_test *test, u8 *result, + const u8 *expected_result, size_t result_size, + const char *operation) +{ +#ifdef CONFIG_CRYPTO_FIPS140_MOD_ERROR_INJECTION + /* Inject a failure (via corrupting the result) if requested. */ + if (fips140_broken_alg && strcmp(test->alg, fips140_broken_alg) == 0) + result[0] ^= 0xff; +#endif + if (memcmp(result, expected_result, result_size) != 0) { + pr_err("wrong result from %s %s\n", test->alg, operation); + return -EBADMSG; + } + return 0; +} + +/* + * None of the algorithms should be ASYNC, as the FIPS module doesn't register + * any ASYNC algorithms. (The ASYNC flag is only declared by hardware + * algorithms, which would need their own FIPS certification.) + * + * Ideally we would verify alg->cra_module == THIS_MODULE here as well, but that + * doesn't work because the files are compiled as built-in code. + */ +static int __init __must_check +fips_validate_alg(const struct crypto_alg *alg) +{ + if (alg->cra_flags & CRYPTO_ALG_ASYNC) { + pr_err("unexpectedly got async implementation of %s (%s)\n", + alg->cra_name, alg->cra_driver_name); + return -EINVAL; + } + return 0; +} + +/* Test a block cipher using the crypto_cipher API. */ +static int __init __must_check +fips_test_blockcipher(const struct fips_test *test) +{ + const struct blockcipher_testvec *vec = &test->blockcipher; + struct crypto_cipher *tfm; + u8 block[MAX_CIPHER_BLOCKSIZE]; + int err; + + if (WARN_ON(vec->block_size > MAX_CIPHER_BLOCKSIZE)) + return -EINVAL; + + tfm = crypto_alloc_cipher(test->alg, 0, 0); + if (IS_ERR(tfm)) { + err = PTR_ERR(tfm); + pr_err("failed to allocate %s tfm: %d\n", test->alg, err); + return err; + } + err = fips_validate_alg(tfm->base.__crt_alg); + if (err) + goto out; + if (crypto_cipher_blocksize(tfm) != vec->block_size) { + pr_err("%s has wrong block size\n", test->alg); + err = -EINVAL; + goto out; + } + + err = crypto_cipher_setkey(tfm, vec->key, vec->key_size); + if (err) { + pr_err("failed to set %s key: %d\n", test->alg, err); + goto out; + } + + /* Encrypt the plaintext, then verify the resulting ciphertext. */ + memcpy(block, vec->plaintext, vec->block_size); + crypto_cipher_encrypt_one(tfm, block, block); + err = fips_check_result(test, block, vec->ciphertext, vec->block_size, + "encryption"); + if (err) + goto out; + + /* Decrypt the ciphertext, then verify the resulting plaintext. */ + crypto_cipher_decrypt_one(tfm, block, block); + err = fips_check_result(test, block, vec->plaintext, vec->block_size, + "decryption"); +out: + crypto_free_cipher(tfm); + return err; +} + +/* + * Test for plain AES (no mode of operation). We test this separately from the + * AES modes because the implementation of AES which is used by the "aes" + * crypto_cipher isn't necessarily the same as that used by the AES modes such + * as "ecb(aes)". Similarly, the aes_{encrypt,decrypt}() library functions may + * use a different implementation as well, so we test them separately too. + */ +static int __init __must_check +fips_test_aes(const struct fips_test *test) +{ + const struct blockcipher_testvec *vec = &test->blockcipher; + struct crypto_aes_ctx ctx; + u8 block[AES_BLOCK_SIZE]; + int err; + + if (WARN_ON(vec->block_size != AES_BLOCK_SIZE)) + return -EINVAL; + + err = fips_test_blockcipher(test); + if (err) + return err; + + err = aes_expandkey(&ctx, vec->key, vec->key_size); + if (err) { + pr_err("aes_expandkey() failed: %d\n", err); + return err; + } + aes_encrypt(&ctx, block, vec->plaintext); + err = fips_check_result(test, block, vec->ciphertext, AES_BLOCK_SIZE, + "encryption (library API)"); + if (err) + return err; + aes_decrypt(&ctx, block, block); + return fips_check_result(test, block, vec->plaintext, AES_BLOCK_SIZE, + "decryption (library API)"); +} + +/* Test a length-preserving symmetric cipher using the crypto_skcipher API. */ +static int __init __must_check +fips_test_skcipher(const struct fips_test *test) +{ + const struct skcipher_testvec *vec = &test->skcipher; + struct crypto_skcipher *tfm; + struct skcipher_request *req = NULL; + u8 *message = NULL; + struct scatterlist sg; + u8 iv[MAX_IV_SIZE]; + int err; + + if (WARN_ON(vec->iv_size > MAX_IV_SIZE)) + return -EINVAL; + + tfm = crypto_alloc_skcipher(test->alg, 0, 0); + if (IS_ERR(tfm)) { + err = PTR_ERR(tfm); + pr_err("failed to allocate %s tfm: %d\n", test->alg, err); + return err; + } + err = fips_validate_alg(&crypto_skcipher_alg(tfm)->base); + if (err) + goto out; + if (crypto_skcipher_ivsize(tfm) != vec->iv_size) { + pr_err("%s has wrong IV size\n", test->alg); + err = -EINVAL; + goto out; + } + + req = skcipher_request_alloc(tfm, GFP_KERNEL); + message = kmemdup(vec->plaintext, vec->message_size, GFP_KERNEL); + if (!req || !message) { + err = -ENOMEM; + goto out; + } + sg_init_one(&sg, message, vec->message_size); + + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); + skcipher_request_set_crypt(req, &sg, &sg, vec->message_size, iv); + + err = crypto_skcipher_setkey(tfm, vec->key, vec->key_size); + if (err) { + pr_err("failed to set %s key: %d\n", test->alg, err); + goto out; + } + + /* Encrypt the plaintext, then verify the resulting ciphertext. */ + memcpy(iv, vec->iv, vec->iv_size); + err = crypto_skcipher_encrypt(req); + if (err) { + pr_err("%s encryption failed: %d\n", test->alg, err); + goto out; + } + err = fips_check_result(test, message, vec->ciphertext, + vec->message_size, "encryption"); + if (err) + goto out; + + /* Decrypt the ciphertext, then verify the resulting plaintext. */ + memcpy(iv, vec->iv, vec->iv_size); + err = crypto_skcipher_decrypt(req); + if (err) { + pr_err("%s decryption failed: %d\n", test->alg, err); + goto out; + } + err = fips_check_result(test, message, vec->plaintext, + vec->message_size, "decryption"); +out: + kfree(message); + skcipher_request_free(req); + crypto_free_skcipher(tfm); + return err; +} + +/* Test an AEAD using the crypto_aead API. */ +static int __init __must_check +fips_test_aead(const struct fips_test *test) +{ + const struct aead_testvec *vec = &test->aead; + const int tag_size = vec->ciphertext_size - vec->plaintext_size; + struct crypto_aead *tfm; + struct aead_request *req = NULL; + u8 *assoc = NULL; + u8 *message = NULL; + struct scatterlist sg[2]; + int sg_idx = 0; + u8 iv[MAX_IV_SIZE]; + int err; + + if (WARN_ON(vec->iv_size > MAX_IV_SIZE)) + return -EINVAL; + if (WARN_ON(vec->ciphertext_size <= vec->plaintext_size)) + return -EINVAL; + + tfm = crypto_alloc_aead(test->alg, 0, 0); + if (IS_ERR(tfm)) { + err = PTR_ERR(tfm); + pr_err("failed to allocate %s tfm: %d\n", test->alg, err); + return err; + } + err = fips_validate_alg(&crypto_aead_alg(tfm)->base); + if (err) + goto out; + if (crypto_aead_ivsize(tfm) != vec->iv_size) { + pr_err("%s has wrong IV size\n", test->alg); + err = -EINVAL; + goto out; + } + + req = aead_request_alloc(tfm, GFP_KERNEL); + assoc = kmemdup(vec->assoc, vec->assoc_size, GFP_KERNEL); + message = kzalloc(vec->ciphertext_size, GFP_KERNEL); + if (!req || !assoc || !message) { + err = -ENOMEM; + goto out; + } + memcpy(message, vec->plaintext, vec->plaintext_size); + + sg_init_table(sg, ARRAY_SIZE(sg)); + if (vec->assoc_size) + sg_set_buf(&sg[sg_idx++], assoc, vec->assoc_size); + sg_set_buf(&sg[sg_idx++], message, vec->ciphertext_size); + + aead_request_set_ad(req, vec->assoc_size); + aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, NULL, NULL); + + err = crypto_aead_setkey(tfm, vec->key, vec->key_size); + if (err) { + pr_err("failed to set %s key: %d\n", test->alg, err); + goto out; + } + + err = crypto_aead_setauthsize(tfm, tag_size); + if (err) { + pr_err("failed to set %s authentication tag size: %d\n", + test->alg, err); + goto out; + } + + /* + * Encrypt the plaintext, then verify the resulting ciphertext (which + * includes the authentication tag). + */ + memcpy(iv, vec->iv, vec->iv_size); + aead_request_set_crypt(req, sg, sg, vec->plaintext_size, iv); + err = crypto_aead_encrypt(req); + if (err) { + pr_err("%s encryption failed: %d\n", test->alg, err); + goto out; + } + err = fips_check_result(test, message, vec->ciphertext, + vec->ciphertext_size, "encryption"); + if (err) + goto out; + + /* + * Decrypt the ciphertext (which includes the authentication tag), then + * verify the resulting plaintext. + */ + memcpy(iv, vec->iv, vec->iv_size); + aead_request_set_crypt(req, sg, sg, vec->ciphertext_size, iv); + err = crypto_aead_decrypt(req); + if (err) { + pr_err("%s decryption failed: %d\n", test->alg, err); + goto out; + } + err = fips_check_result(test, message, vec->plaintext, + vec->plaintext_size, "decryption"); +out: + kfree(message); + kfree(assoc); + aead_request_free(req); + crypto_free_aead(tfm); + return err; +} + +/* + * Test a hash algorithm using the crypto_shash API. + * + * Note that we don't need to test the crypto_ahash API too, since none of the + * hash algorithms in the FIPS module have the ASYNC flag, and thus there will + * be no hash algorithms that can be accessed only through crypto_ahash. + */ +static int __init __must_check +fips_test_hash(const struct fips_test *test) +{ + const struct hash_testvec *vec = &test->hash; + struct crypto_shash *tfm; + u8 digest[HASH_MAX_DIGESTSIZE]; + int err; + + if (WARN_ON(vec->digest_size > HASH_MAX_DIGESTSIZE)) + return -EINVAL; + + tfm = crypto_alloc_shash(test->alg, 0, 0); + if (IS_ERR(tfm)) { + err = PTR_ERR(tfm); + pr_err("failed to allocate %s tfm: %d\n", test->alg, err); + return err; + } + err = fips_validate_alg(&crypto_shash_alg(tfm)->base); + if (err) + goto out; + if (crypto_shash_digestsize(tfm) != vec->digest_size) { + pr_err("%s has wrong digest size\n", test->alg); + err = -EINVAL; + goto out; + } + + if (vec->key) { + err = crypto_shash_setkey(tfm, vec->key, vec->key_size); + if (err) { + pr_err("failed to set %s key: %d\n", test->alg, err); + goto out; + } + } + + err = crypto_shash_tfm_digest(tfm, vec->message, vec->message_size, + digest); + if (err) { + pr_err("%s digest computation failed: %d\n", test->alg, err); + goto out; + } + err = fips_check_result(test, digest, vec->digest, vec->digest_size, + "digest"); +out: + crypto_free_shash(tfm); + return err; +} + +/* + * Test the sha256() library function, as it may not be covered by the "sha256" + * crypto_shash, and thus may not be covered by the "hmac(sha256)" test we do. + */ +static int __init __must_check +fips_test_sha256_library(const struct fips_test *test) +{ + const struct hash_testvec *vec = &test->hash; + u8 digest[SHA256_DIGEST_SIZE]; + + if (WARN_ON(vec->digest_size != SHA256_DIGEST_SIZE)) + return -EINVAL; + + sha256(vec->message, vec->message_size, digest); + return fips_check_result(test, digest, vec->digest, vec->digest_size, + "digest (library API)"); +} + +/* Test a DRBG using the crypto_rng API. */ +static int __init __must_check +fips_test_drbg(const struct fips_test *test) +{ + const struct drbg_testvec *vec = &test->drbg; + struct crypto_rng *rng; + u8 *output = NULL; + struct drbg_test_data test_data; + struct drbg_string addtl, pers, testentropy; + int err; + + rng = crypto_alloc_rng(test->alg, 0, 0); + if (IS_ERR(rng)) { + err = PTR_ERR(rng); + pr_err("failed to allocate %s tfm: %d\n", test->alg, err); + return PTR_ERR(rng); + } + err = fips_validate_alg(&crypto_rng_alg(rng)->base); + if (err) + goto out; + + output = kzalloc(vec->out_size, GFP_KERNEL); + if (!output) { + err = -ENOMEM; + goto out; + } + + /* + * Initialize the DRBG with the entropy and personalization string given + * in the test vector. + */ + test_data.testentropy = &testentropy; + drbg_string_fill(&testentropy, vec->entropy, vec->entropy_size); + drbg_string_fill(&pers, vec->pers, vec->pers_size); + err = crypto_drbg_reset_test(rng, &pers, &test_data); + if (err) { + pr_err("failed to reset %s\n", test->alg); + goto out; + } + + /* + * Generate some random bytes using the additional data string provided + * in the test vector. Also use the additional entropy if provided + * (relevant for the prediction-resistant DRBG variants only). + */ + drbg_string_fill(&addtl, vec->add_a, vec->add_size); + if (vec->entpr_size) { + drbg_string_fill(&testentropy, vec->entpr_a, vec->entpr_size); + err = crypto_drbg_get_bytes_addtl_test(rng, output, + vec->out_size, &addtl, + &test_data); + } else { + err = crypto_drbg_get_bytes_addtl(rng, output, vec->out_size, + &addtl); + } + if (err) { + pr_err("failed to get bytes from %s (try 1): %d\n", + test->alg, err); + goto out; + } + + /* + * Do the same again, using a second additional data string, and (when + * applicable) a second additional entropy string. + */ + drbg_string_fill(&addtl, vec->add_b, vec->add_size); + if (test->drbg.entpr_size) { + drbg_string_fill(&testentropy, vec->entpr_b, vec->entpr_size); + err = crypto_drbg_get_bytes_addtl_test(rng, output, + vec->out_size, &addtl, + &test_data); + } else { + err = crypto_drbg_get_bytes_addtl(rng, output, vec->out_size, + &addtl); + } + if (err) { + pr_err("failed to get bytes from %s (try 2): %d\n", + test->alg, err); + goto out; + } + + /* Check that the DRBG generated the expected output. */ + err = fips_check_result(test, output, vec->output, vec->out_size, + "get_bytes"); +out: + kfree(output); + crypto_free_rng(rng); + return err; +} + +/* Include the test vectors generated by the Python script. */ +#include "fips140-generated-testvecs.h" + +/* List of all self-tests. Keep this in sync with fips140_algorithms[]. */ +static const struct fips_test fips140_selftests[] __initconst = { + /* + * Tests for AES and AES modes. + * + * The full list of AES algorithms we potentially need to test are AES + * by itself, AES-CBC, AES-CTR, AES-ECB, AES-GCM, and AES-XTS. We can + * follow the FIPS 140-2 Implementation Guidance (IG) document to try to + * reduce this list, but we run into the issue that the architecture- + * specific implementations of these algorithms in Linux often don't + * share the "same" underlying AES implementation. E.g., the ARMv8 CE + * optimized implementations issue ARMv8 CE instructions directly rather + * than going through a separate AES implementation. In this case, + * separate tests are needed according to section 9.2 of the IG. + */ + { + .alg = "aes", + .func = fips_test_aes, + .blockcipher = { + .key = fips_aes_key, + .key_size = sizeof(fips_aes_key), + .plaintext = fips_message, + .ciphertext = fips_aes_ecb_ciphertext, + .block_size = 16, + } + }, { + .alg = "cbc(aes)", + .func = fips_test_skcipher, + .skcipher = { + .key = fips_aes_key, + .key_size = sizeof(fips_aes_key), + .iv = fips_aes_iv, + .iv_size = sizeof(fips_aes_iv), + .plaintext = fips_message, + .ciphertext = fips_aes_cbc_ciphertext, + .message_size = sizeof(fips_message), + } + }, { + .alg = "ctr(aes)", + .func = fips_test_skcipher, + .skcipher = { + .key = fips_aes_key, + .key_size = sizeof(fips_aes_key), + .iv = fips_aes_iv, + .iv_size = sizeof(fips_aes_iv), + .plaintext = fips_message, + .ciphertext = fips_aes_ctr_ciphertext, + .message_size = sizeof(fips_message), + } + }, { + .alg = "ecb(aes)", + .func = fips_test_skcipher, + .skcipher = { + .key = fips_aes_key, + .key_size = sizeof(fips_aes_key), + .plaintext = fips_message, + .ciphertext = fips_aes_ecb_ciphertext, + .message_size = sizeof(fips_message) + } + }, { + .alg = "gcm(aes)", + .func = fips_test_aead, + .aead = { + .key = fips_aes_key, + .key_size = sizeof(fips_aes_key), + .iv = fips_aes_iv, + /* The GCM implementation assumes an IV size of 12. */ + .iv_size = 12, + .assoc = fips_aes_gcm_assoc, + .assoc_size = sizeof(fips_aes_gcm_assoc), + .plaintext = fips_message, + .plaintext_size = sizeof(fips_message), + .ciphertext = fips_aes_gcm_ciphertext, + .ciphertext_size = sizeof(fips_aes_gcm_ciphertext), + } + }, { + .alg = "xts(aes)", + .func = fips_test_skcipher, + .skcipher = { + .key = fips_aes_xts_key, + .key_size = sizeof(fips_aes_xts_key), + .iv = fips_aes_iv, + .iv_size = sizeof(fips_aes_iv), + .plaintext = fips_message, + .ciphertext = fips_aes_xts_ciphertext, + .message_size = sizeof(fips_message), + } + /* + * Tests for SHA-1, SHA-256, HMAC-SHA256, and SHA-512. + * + * The selection of these specific tests follows the guidance from + * section 9 of the FIPS 140-2 Implementation Guidance (IG) document to + * achieve a minimal list of tests, rather than testing all of + * SHA-{1,224,256,384,512} and HMAC-SHA{1,224,256,384,512}. As per the + * IG, testing SHA-224 is only required if SHA-256 isn't implemented, + * and testing SHA-384 is only required if SHA-512 isn't implemented. + * Also, HMAC only has to be tested with one underlying SHA, and the + * HMAC test also fulfills the test for its underlying SHA. That would + * result in a test list of e.g. SHA-1, HMAC-SHA256, and SHA-512. + * + * However we also need to take into account cases where implementations + * aren't shared in the "natural" way assumed by the IG. Currently the + * only known exception w.r.t. SHA-* and HMAC-* is the sha256() library + * function which may not be covered by the test of the "hmac(sha256)" + * crypto_shash. So, we test sha256() separately. + */ + }, { + .alg = "sha1", + .func = fips_test_hash, + .hash = { + .message = fips_message, + .message_size = sizeof(fips_message), + .digest = fips_sha1_digest, + .digest_size = sizeof(fips_sha1_digest) + } + }, { + .alg = "sha256", + .func = fips_test_sha256_library, + .hash = { + .message = fips_message, + .message_size = sizeof(fips_message), + .digest = fips_sha256_digest, + .digest_size = sizeof(fips_sha256_digest) + } + }, { + .alg = "hmac(sha256)", + .func = fips_test_hash, + .hash = { + .key = fips_hmac_key, + .key_size = sizeof(fips_hmac_key), + .message = fips_message, + .message_size = sizeof(fips_message), + .digest = fips_hmac_sha256_digest, + .digest_size = sizeof(fips_hmac_sha256_digest) + } + }, { + .alg = "sha512", + .func = fips_test_hash, + .hash = { + .message = fips_message, + .message_size = sizeof(fips_message), + .digest = fips_sha512_digest, + .digest_size = sizeof(fips_sha512_digest) + } + /* + * Tests for DRBG algorithms. + * + * Only the default variant (the one that users get when they request + * "stdrng") is required to be tested, as we don't consider the other + * variants to be used / usable in the FIPS security policy. This is + * similar to how e.g. we don't test both "xts(aes-generic)" and + * "xts-aes-ce" but rather just "xts(aes)". + * + * Currently the default one is "drbg_nopr_hmac_sha256"; however, just + * in case we also test the prediction-resistant enabled variant too. + */ + }, { + .alg = "drbg_nopr_hmac_sha256", + .func = fips_test_drbg, + .drbg = { + .entropy = + "\xf9\x7a\x3c\xfd\x91\xfa\xa0\x46\xb9\xe6\x1b\x94" + "\x93\xd4\x36\xc4\x93\x1f\x60\x4b\x22\xf1\x08\x15" + "\x21\xb3\x41\x91\x51\xe8\xff\x06\x11\xf3\xa7\xd4" + "\x35\x95\x35\x7d\x58\x12\x0b\xd1\xe2\xdd\x8a\xed", + .entropy_size = 48, + .output = + "\xc6\x87\x1c\xff\x08\x24\xfe\x55\xea\x76\x89\xa5" + "\x22\x29\x88\x67\x30\x45\x0e\x5d\x36\x2d\xa5\xbf" + "\x59\x0d\xcf\x9a\xcd\x67\xfe\xd4\xcb\x32\x10\x7d" + "\xf5\xd0\x39\x69\xa6\x6b\x1f\x64\x94\xfd\xf5\xd6" + "\x3d\x5b\x4d\x0d\x34\xea\x73\x99\xa0\x7d\x01\x16" + "\x12\x6d\x0d\x51\x8c\x7c\x55\xba\x46\xe1\x2f\x62" + "\xef\xc8\xfe\x28\xa5\x1c\x9d\x42\x8e\x6d\x37\x1d" + "\x73\x97\xab\x31\x9f\xc7\x3d\xed\x47\x22\xe5\xb4" + "\xf3\x00\x04\x03\x2a\x61\x28\xdf\x5e\x74\x97\xec" + "\xf8\x2c\xa7\xb0\xa5\x0e\x86\x7e\xf6\x72\x8a\x4f" + "\x50\x9a\x8c\x85\x90\x87\x03\x9c", + .out_size = 128, + .add_a = + "\x51\x72\x89\xaf\xe4\x44\xa0\xfe\x5e\xd1\xa4\x1d" + "\xbb\xb5\xeb\x17\x15\x00\x79\xbd\xd3\x1e\x29\xcf" + "\x2f\xf3\x00\x34\xd8\x26\x8e\x3b", + .add_b = + "\x88\x02\x8d\x29\xef\x80\xb4\xe6\xf0\xfe\x12\xf9" + "\x1d\x74\x49\xfe\x75\x06\x26\x82\xe8\x9c\x57\x14" + "\x40\xc0\xc9\xb5\x2c\x42\xa6\xe0", + .add_size = 32, + } + }, { + .alg = "drbg_pr_hmac_sha256", + .func = fips_test_drbg, + .drbg = { + .entropy = + "\xc7\xcc\xbc\x67\x7e\x21\x66\x1e\x27\x2b\x63\xdd" + "\x3a\x78\xdc\xdf\x66\x6d\x3f\x24\xae\xcf\x37\x01" + "\xa9\x0d\x89\x8a\xa7\xdc\x81\x58\xae\xb2\x10\x15" + "\x7e\x18\x44\x6d\x13\xea\xdf\x37\x85\xfe\x81\xfb", + .entropy_size = 48, + .entpr_a = + "\x7b\xa1\x91\x5b\x3c\x04\xc4\x1b\x1d\x19\x2f\x1a" + "\x18\x81\x60\x3c\x6c\x62\x91\xb7\xe9\xf5\xcb\x96" + "\xbb\x81\x6a\xcc\xb5\xae\x55\xb6", + .entpr_b = + "\x99\x2c\xc7\x78\x7e\x3b\x88\x12\xef\xbe\xd3\xd2" + "\x7d\x2a\xa5\x86\xda\x8d\x58\x73\x4a\x0a\xb2\x2e" + "\xbb\x4c\x7e\xe3\x9a\xb6\x81\xc1", + .entpr_size = 32, + .output = + "\x95\x6f\x95\xfc\x3b\xb7\xfe\x3e\xd0\x4e\x1a\x14" + "\x6c\x34\x7f\x7b\x1d\x0d\x63\x5e\x48\x9c\x69\xe6" + "\x46\x07\xd2\x87\xf3\x86\x52\x3d\x98\x27\x5e\xd7" + "\x54\xe7\x75\x50\x4f\xfb\x4d\xfd\xac\x2f\x4b\x77" + "\xcf\x9e\x8e\xcc\x16\xa2\x24\xcd\x53\xde\x3e\xc5" + "\x55\x5d\xd5\x26\x3f\x89\xdf\xca\x8b\x4e\x1e\xb6" + "\x88\x78\x63\x5c\xa2\x63\x98\x4e\x6f\x25\x59\xb1" + "\x5f\x2b\x23\xb0\x4b\xa5\x18\x5d\xc2\x15\x74\x40" + "\x59\x4c\xb4\x1e\xcf\x9a\x36\xfd\x43\xe2\x03\xb8" + "\x59\x91\x30\x89\x2a\xc8\x5a\x43\x23\x7c\x73\x72" + "\xda\x3f\xad\x2b\xba\x00\x6b\xd1", + .out_size = 128, + .add_a = + "\x18\xe8\x17\xff\xef\x39\xc7\x41\x5c\x73\x03\x03" + "\xf6\x3d\xe8\x5f\xc8\xab\xe4\xab\x0f\xad\xe8\xd6" + "\x86\x88\x55\x28\xc1\x69\xdd\x76", + .add_b = + "\xac\x07\xfc\xbe\x87\x0e\xd3\xea\x1f\x7e\xb8\xe7" + "\x9d\xec\xe8\xe7\xbc\xf3\x18\x25\x77\x35\x4a\xaa" + "\x00\x99\x2a\xdd\x0a\x00\x50\x82", + .add_size = 32, + .pers = + "\xbc\x55\xab\x3c\xf6\x52\xb0\x11\x3d\x7b\x90\xb8" + "\x24\xc9\x26\x4e\x5a\x1e\x77\x0d\x3d\x58\x4a\xda" + "\xd1\x81\xe9\xf8\xeb\x30\x8f\x6f", + .pers_size = 32, + } + } +}; + +bool __init fips140_run_selftests(void) +{ + int i; + + pr_info("running self-tests\n"); + for (i = 0; i < ARRAY_SIZE(fips140_selftests); i++) { + const struct fips_test *test = &fips140_selftests[i]; + int err; + + err = test->func(test); + if (err) { + pr_emerg("self-tests failed for algorithm %s: %d\n", + test->alg, err); + /* The caller is responsible for calling panic(). */ + return false; + } + } + pr_info("all self-tests passed\n"); + return true; +} diff --git a/drivers/OWNERS b/drivers/OWNERS deleted file mode 100644 index 22c7eece228f..000000000000 --- a/drivers/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/drivers/OWNERS diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 3b6d6be5e3b7..b28b56e6e4a2 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -738,7 +738,7 @@ static void binder_transaction_priority(struct task_struct *task, t->saved_priority.sched_policy = task->policy; t->saved_priority.prio = task->normal_prio; - trace_android_vh_binder_transaction_priority_skip(task, &skip); + trace_android_vh_binder_priority_skip(task, &skip); if (skip) return; @@ -2851,9 +2851,28 @@ static void binder_transaction(struct binder_proc *proc, if (target_node && target_node->txn_security_ctx) { u32 secid; size_t added_size; + int max_retries = 100; security_task_getsecid(proc->tsk, &secid); + retry_alloc: ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); + if (ret == -ENOMEM && max_retries-- > 0) { + struct page *dummy_page; + + /* + * security_secid_to_secctx() can fail because of a + * GFP_ATOMIC allocation in which case -ENOMEM is + * returned. This needs to be retried, but there is + * currently no way to tell userspace to retry so we + * do it here. We make sure there is still available + * memory first and then retry. + */ + dummy_page = alloc_page(GFP_KERNEL); + if (dummy_page) { + __free_page(dummy_page); + goto retry_alloc; + } + } if (ret) { return_error = BR_FAILED_REPLY; return_error_param = ret; @@ -5481,6 +5500,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m, struct binder_buffer *buffer = t->buffer; spin_lock(&t->lock); + trace_android_vh_binder_print_transaction_info(m, proc, prefix, t); to_proc = t->to_proc; seq_printf(m, "%s %d: %pK from %d:%d to %d:%d code %x flags %x pri %d:%d r%d", diff --git a/drivers/android/binder_internal.h b/drivers/android/binder_internal.h index 177ffc2918dc..2ddbec09d2f9 100644 --- a/drivers/android/binder_internal.h +++ b/drivers/android/binder_internal.h @@ -572,6 +572,7 @@ struct binder_transaction { */ spinlock_t lock; ANDROID_VENDOR_DATA(1); + ANDROID_OEM_DATA_ARRAY(1, 2); }; /** diff --git a/drivers/android/debug_symbols.c b/drivers/android/debug_symbols.c index 61e55575ed5f..6a4a6f8992f2 100644 --- a/drivers/android/debug_symbols.c +++ b/drivers/android/debug_symbols.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include struct ads_entry { char *name; @@ -59,6 +61,13 @@ static const struct ads_entry ads_entries[ADS_END] = { #ifdef CONFIG_SWAP ADS_ENTRY(ADS_NR_SWAP_PAGES, &nr_swap_pages), #endif +#ifdef CONFIG_MMU + ADS_ENTRY(ADS_MMAP_MIN_ADDR, &mmap_min_addr), +#endif + ADS_ENTRY(ADS_STACK_GUARD_GAP, &stack_guard_gap), +#ifdef CONFIG_SYSCTL + ADS_ENTRY(ADS_SYSCTL_LEGACY_VA_LAYOUT, &sysctl_legacy_va_layout), +#endif }; /* diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 9829d2b783f5..1302b9b0f5f2 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,16 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* * Export tracepoints that act as a bare tracehook (ie: have no trace event @@ -82,10 +93,14 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_prepare_prio_fork); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_finish_prio_fork); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_user_nice); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_setscheduler); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_sk_alloc); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_sk_free); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_nf_conn_alloc); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_nf_conn_free); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_arch_set_freq_scale); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_is_fpsimd_save); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_transaction_init); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_transaction_priority_skip); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_priority_skip); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_set_priority); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_restore_priority); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_wakeup_ilocked); @@ -105,6 +120,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_read_wait_finish); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_wait_start); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_write_wait_finish); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_show_task); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shmem_alloc_page); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_idle_enter); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_idle_exit); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mpam_set); @@ -193,9 +209,12 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cma_alloc_start); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cma_alloc_finish); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rmqueue); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_pagecache_get_page); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_fault_get_page); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_filemap_fault_cache_page); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_enable_thermal_genl_check); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_thermal_pm_notify_suspend); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_fill_prdt); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_ufs_reprogram_all_keys); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_prepare_command); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_update_sysfs); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_send_command); @@ -204,6 +223,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_send_uic_command); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_send_tm_command); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_check_int_errors); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_update_sdev); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ufs_clock_scaling); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_wake_up_sync); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_wake_flags); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_uclamp_eff_get); @@ -228,6 +248,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_insert); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_node_delete); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_node_replace); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_selinux_avc_lookup); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_blk_alloc_rqs); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_blk_rq_ctx_init); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_commit_creds); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_creds); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_override_creds); @@ -241,9 +263,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_module_permit_after_init); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_util_est_update); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_meminfo_proc_show); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_mm); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_unmapped_area_from_anti_fragment_pool); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_from_fragment_pool); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exclude_reserved_zone); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_unmapped_area_include_reserved_zone); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_include_reserved_zone); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_slowpath); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_print_slabinfo_header); @@ -269,6 +291,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_post_init_entity_util_avg); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpm_get_timer); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpm_adj_current_limit); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_logbuf); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_logbuf_pr_cont); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_scan_type); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_tune_swappiness); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_shrink_slab_bypass); @@ -306,19 +329,28 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mmc_gpio_cd_irqt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_save_vmalloc_stack); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_stack_hash); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_save_track_hash); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_vmpressure); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_task_comm); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpufreq_acct_update_power); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpm_log); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_media_device_setup_link); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_media_device_setup_link); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_clear_reserved_fmt_fields); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_fill_ext_fmtdesc); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_clear_mask_adjust); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_v4l2subdev_set_selection); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_v4l2subdev_set_selection); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_v4l2subdev_set_fmt); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_v4l2subdev_set_fmt); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_v4l2subdev_set_frame_interval); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_v4l2subdev_set_frame_interval); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_scmi_timeout_sync); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_find_new_ilb); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_force_compatible_pre); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_force_compatible_post); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_uid); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_user); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_add_request); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_update_request); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_remove_request); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_balance_anon_file_reclaim); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_enter); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpuidle_psci_exit); @@ -326,3 +358,25 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sha256); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_expandkey); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_encrypt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_decrypt); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_force_compatible_pre); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_force_compatible_post); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_print_transaction_info); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_setscheduler_uclamp); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rproc_recovery); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ptype_head); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_kfree_skb); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_mmap_file); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_file_open); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_check_bpf_syscall); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_usb_dev_suspend); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_usb_dev_resume); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ipv6_gen_linklocal_addr); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sound_usb_support_cpu_suspend); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_snd_compr_use_pause_in_drain); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_show_max_freq); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_tcp_sendmsg_locked); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_tcp_recvmsg); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_udp_sendmsg); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_udp_recvmsg); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_tcp_recvmsg_stat); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_pci_d3_sleep); diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index d3c863c0b1b2..2c7250eb1d67 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1234,8 +1234,8 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a error = dpm_run_callback(callback, dev, state, info); if (error) { async_error = error; - log_suspend_abort_reason("Callback failed on %s in %pS returned %d", - dev_name(dev), callback, error); + log_suspend_abort_reason("Device %s failed to %s noirq: error %d", + dev_name(dev), pm_verb(state.event), error); goto Complete; } @@ -1428,8 +1428,8 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as error = dpm_run_callback(callback, dev, state, info); if (error) { async_error = error; - log_suspend_abort_reason("Callback failed on %s in %pS returned %d", - dev_name(dev), callback, error); + log_suspend_abort_reason("Device %s failed to %s late: error %d", + dev_name(dev), pm_verb(state.event), error); goto Complete; } dpm_propagate_wakeup_to_parent(dev); @@ -1701,8 +1701,8 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) dpm_propagate_wakeup_to_parent(dev); dpm_clear_superiors_direct_complete(dev); } else { - log_suspend_abort_reason("Callback failed on %s in %pS returned %d", - dev_name(dev), callback, error); + log_suspend_abort_reason("Device %s failed to %s: error %d", + dev_name(dev), pm_verb(state.event), error); } device_unlock(dev); diff --git a/drivers/block/loop.c b/drivers/block/loop.c index a58084c2ed7c..a34fc3f42e3b 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -2113,7 +2113,8 @@ static int loop_add(struct loop_device **l, int i) lo->tag_set.queue_depth = 128; lo->tag_set.numa_node = NUMA_NO_NODE; lo->tag_set.cmd_size = sizeof(struct loop_cmd); - lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_STACKING; + lo->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_STACKING | + BLK_MQ_F_NO_SCHED_BY_DEFAULT; lo->tag_set.driver_data = lo; err = blk_mq_alloc_tag_set(&lo->tag_set); diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1e6b0eff68fb..89dbff9a8501 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -697,6 +697,7 @@ static ssize_t show_cpuinfo_max_freq(struct cpufreq_policy *policy, char *buf) unsigned int max_freq = policy->cpuinfo.max_freq; trace_android_vh_show_max_freq(policy, &max_freq); + trace_android_rvh_show_max_freq(policy, &max_freq); return sprintf(buf, "%u\n", max_freq); } diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 3bf28f4ebe74..ab77a363a9fb 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -212,6 +212,9 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, * broadcast must be assigned after the vendor hook. */ trace_android_vh_cpu_idle_enter(&index, dev); + if (index < 0) + return index; + target_state = &drv->states[index]; broadcast = !!(target_state->flags & CPUIDLE_FLAG_TIMER_STOP); @@ -428,7 +431,7 @@ void cpuidle_uninstall_idle_handler(void) { if (enabled_devices) { initialized = 0; - wake_up_all_idle_cpus(); + wake_up_all_online_idle_cpus(); } /* diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.c b/drivers/dma-buf/dma-buf-sysfs-stats.c index 943e395d1807..2389a363bd3a 100644 --- a/drivers/dma-buf/dma-buf-sysfs-stats.c +++ b/drivers/dma-buf/dma-buf-sysfs-stats.c @@ -52,13 +52,6 @@ static ssize_t exporter_name_show(struct dma_buf *dmabuf, return sysfs_emit(buf, "%s\n", dmabuf->exp_name); } -static ssize_t mmap_count_show(struct dma_buf *dmabuf, - struct dma_buf_stats_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%d\n", dmabuf->mmap_count); -} - static ssize_t size_show(struct dma_buf *dmabuf, struct dma_buf_stats_attribute *attr, char *buf) @@ -69,13 +62,10 @@ static ssize_t size_show(struct dma_buf *dmabuf, static struct dma_buf_stats_attribute exporter_name_attribute = __ATTR_RO(exporter_name); static struct dma_buf_stats_attribute size_attribute = __ATTR_RO(size); -static struct dma_buf_stats_attribute mmap_count_attribute = - __ATTR_RO(mmap_count); static struct attribute *dma_buf_stats_default_attrs[] = { &exporter_name_attribute.attr, &size_attribute.attr, - &mmap_count_attribute.attr, NULL, }; ATTRIBUTE_GROUPS(dma_buf_stats_default); @@ -94,120 +84,6 @@ static struct kobj_type dma_buf_ktype = { .default_groups = dma_buf_stats_default_groups, }; -#define to_dma_buf_attach_entry_from_kobj(x) container_of(x, struct dma_buf_attach_sysfs_entry, kobj) - -struct dma_buf_attach_stats_attribute { - struct attribute attr; - ssize_t (*show)(struct dma_buf_attach_sysfs_entry *sysfs_entry, - struct dma_buf_attach_stats_attribute *attr, char *buf); -}; -#define to_dma_buf_attach_stats_attr(x) container_of(x, struct dma_buf_attach_stats_attribute, attr) - -static ssize_t dma_buf_attach_stats_attribute_show(struct kobject *kobj, - struct attribute *attr, - char *buf) -{ - struct dma_buf_attach_stats_attribute *attribute; - struct dma_buf_attach_sysfs_entry *sysfs_entry; - - attribute = to_dma_buf_attach_stats_attr(attr); - sysfs_entry = to_dma_buf_attach_entry_from_kobj(kobj); - - if (!attribute->show) - return -EIO; - - return attribute->show(sysfs_entry, attribute, buf); -} - -static const struct sysfs_ops dma_buf_attach_stats_sysfs_ops = { - .show = dma_buf_attach_stats_attribute_show, -}; - -static ssize_t map_counter_show(struct dma_buf_attach_sysfs_entry *sysfs_entry, - struct dma_buf_attach_stats_attribute *attr, - char *buf) -{ - return sysfs_emit(buf, "%u\n", sysfs_entry->map_counter); -} - -static struct dma_buf_attach_stats_attribute map_counter_attribute = - __ATTR_RO(map_counter); - -static struct attribute *dma_buf_attach_stats_default_attrs[] = { - &map_counter_attribute.attr, - NULL, -}; -ATTRIBUTE_GROUPS(dma_buf_attach_stats_default); - -static void dma_buf_attach_sysfs_release(struct kobject *kobj) -{ - struct dma_buf_attach_sysfs_entry *sysfs_entry; - - sysfs_entry = to_dma_buf_attach_entry_from_kobj(kobj); - kfree(sysfs_entry); -} - -static struct kobj_type dma_buf_attach_ktype = { - .sysfs_ops = &dma_buf_attach_stats_sysfs_ops, - .release = dma_buf_attach_sysfs_release, - .default_groups = dma_buf_attach_stats_default_groups, -}; - -void dma_buf_attach_stats_teardown(struct dma_buf_attachment *attach) -{ - struct dma_buf_attach_sysfs_entry *sysfs_entry; - - sysfs_entry = attach->sysfs_entry; - if (!sysfs_entry) - return; - - sysfs_delete_link(&sysfs_entry->kobj, &attach->dev->kobj, "device"); - - kobject_del(&sysfs_entry->kobj); - kobject_put(&sysfs_entry->kobj); -} - -int dma_buf_attach_stats_setup(struct dma_buf_attachment *attach, - unsigned int uid) -{ - struct dma_buf_attach_sysfs_entry *sysfs_entry; - int ret; - struct dma_buf *dmabuf; - - if (!attach) - return -EINVAL; - - dmabuf = attach->dmabuf; - - sysfs_entry = kzalloc(sizeof(struct dma_buf_attach_sysfs_entry), - GFP_KERNEL); - if (!sysfs_entry) - return -ENOMEM; - - sysfs_entry->kobj.kset = dmabuf->sysfs_entry->attach_stats_kset; - - attach->sysfs_entry = sysfs_entry; - - ret = kobject_init_and_add(&sysfs_entry->kobj, &dma_buf_attach_ktype, - NULL, "%u", uid); - if (ret) - goto kobj_err; - - ret = sysfs_create_link(&sysfs_entry->kobj, &attach->dev->kobj, - "device"); - if (ret) - goto link_err; - - return 0; - -link_err: - kobject_del(&sysfs_entry->kobj); -kobj_err: - kobject_put(&sysfs_entry->kobj); - attach->sysfs_entry = NULL; - - return ret; -} void dma_buf_stats_teardown(struct dma_buf *dmabuf) { struct dma_buf_sysfs_entry *sysfs_entry; @@ -216,7 +92,6 @@ void dma_buf_stats_teardown(struct dma_buf *dmabuf) if (!sysfs_entry) return; - kset_unregister(sysfs_entry->attach_stats_kset); kobject_del(&sysfs_entry->kobj); kobject_put(&sysfs_entry->kobj); } @@ -264,7 +139,6 @@ int dma_buf_stats_setup(struct dma_buf *dmabuf) { struct dma_buf_sysfs_entry *sysfs_entry; int ret; - struct kset *attach_stats_kset; if (!dmabuf || !dmabuf->file) return -EINVAL; @@ -289,21 +163,8 @@ int dma_buf_stats_setup(struct dma_buf *dmabuf) if (ret) goto err_sysfs_dmabuf; - /* create the directory for attachment stats */ - attach_stats_kset = kset_create_and_add("attachments", - &dmabuf_sysfs_no_uevent_ops, - &sysfs_entry->kobj); - if (!attach_stats_kset) { - ret = -ENOMEM; - goto err_sysfs_attach; - } - - sysfs_entry->attach_stats_kset = attach_stats_kset; - return 0; -err_sysfs_attach: - kobject_del(&sysfs_entry->kobj); err_sysfs_dmabuf: kobject_put(&sysfs_entry->kobj); dmabuf->sysfs_entry = NULL; diff --git a/drivers/dma-buf/dma-buf-sysfs-stats.h b/drivers/dma-buf/dma-buf-sysfs-stats.h index 5f4703249117..a49c6e2650cc 100644 --- a/drivers/dma-buf/dma-buf-sysfs-stats.h +++ b/drivers/dma-buf/dma-buf-sysfs-stats.h @@ -14,23 +14,8 @@ int dma_buf_init_sysfs_statistics(void); void dma_buf_uninit_sysfs_statistics(void); int dma_buf_stats_setup(struct dma_buf *dmabuf); -int dma_buf_attach_stats_setup(struct dma_buf_attachment *attach, - unsigned int uid); -static inline void dma_buf_update_attachment_map_count(struct dma_buf_attachment *attach, - int delta) -{ - struct dma_buf_attach_sysfs_entry *entry = attach->sysfs_entry; - entry->map_counter += delta; -} void dma_buf_stats_teardown(struct dma_buf *dmabuf); -void dma_buf_attach_stats_teardown(struct dma_buf_attachment *attach); -static inline unsigned int dma_buf_update_attach_uid(struct dma_buf *dmabuf) -{ - struct dma_buf_sysfs_entry *entry = dmabuf->sysfs_entry; - - return entry->attachment_uid++; -} #else static inline int dma_buf_init_sysfs_statistics(void) @@ -44,19 +29,7 @@ static inline int dma_buf_stats_setup(struct dma_buf *dmabuf) { return 0; } -static inline int dma_buf_attach_stats_setup(struct dma_buf_attachment *attach, - unsigned int uid) -{ - return 0; -} static inline void dma_buf_stats_teardown(struct dma_buf *dmabuf) {} -static inline void dma_buf_attach_stats_teardown(struct dma_buf_attachment *attach) {} -static inline void dma_buf_update_attachment_map_count(struct dma_buf_attachment *attach, - int delta) {} -static inline unsigned int dma_buf_update_attach_uid(struct dma_buf *dmabuf) -{ - return 0; -} #endif #endif // _DMA_BUF_SYSFS_STATS_H diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 0ab865543d1f..d9948d58b3f4 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -98,12 +98,12 @@ static void dma_buf_release(struct dentry *dentry) */ BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active); + dma_buf_stats_teardown(dmabuf); dmabuf->ops->release(dmabuf); if (dmabuf->resv == (struct dma_resv *)&dmabuf[1]) dma_resv_fini(dmabuf->resv); - dma_buf_stats_teardown(dmabuf); module_put(dmabuf->owner); kfree(dmabuf->name); kfree(dmabuf); @@ -149,54 +149,6 @@ static struct file_system_type dma_buf_fs_type = { .kill_sb = kill_anon_super, }; -#ifdef CONFIG_DMABUF_SYSFS_STATS -static void dma_buf_vma_open(struct vm_area_struct *vma) -{ - struct dma_buf *dmabuf = vma->vm_file->private_data; - - dmabuf->mmap_count++; - /* call the heap provided vma open() op */ - if (dmabuf->exp_vm_ops->open) - dmabuf->exp_vm_ops->open(vma); -} - -static void dma_buf_vma_close(struct vm_area_struct *vma) -{ - struct dma_buf *dmabuf = vma->vm_file->private_data; - - if (dmabuf->mmap_count) - dmabuf->mmap_count--; - /* call the heap provided vma close() op */ - if (dmabuf->exp_vm_ops->close) - dmabuf->exp_vm_ops->close(vma); -} - -static int dma_buf_do_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -{ - /* call this first because the exporter might override vma->vm_ops */ - int ret = dmabuf->ops->mmap(dmabuf, vma); - - if (ret) - return ret; - - /* save the exporter provided vm_ops */ - dmabuf->exp_vm_ops = vma->vm_ops; - dmabuf->vm_ops = *(dmabuf->exp_vm_ops); - /* override open() and close() to provide buffer mmap count */ - dmabuf->vm_ops.open = dma_buf_vma_open; - dmabuf->vm_ops.close = dma_buf_vma_close; - vma->vm_ops = &dmabuf->vm_ops; - dmabuf->mmap_count++; - - return ret; -} -#else /* CONFIG_DMABUF_SYSFS_STATS */ -static int dma_buf_do_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -{ - return dmabuf->ops->mmap(dmabuf, vma); -} -#endif /* CONFIG_DMABUF_SYSFS_STATS */ - static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) { struct dma_buf *dmabuf; @@ -215,7 +167,7 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) dmabuf->size >> PAGE_SHIFT) return -EINVAL; - return dma_buf_do_mmap(dmabuf, vma); + return dmabuf->ops->mmap(dmabuf, vma); } static loff_t dma_buf_llseek(struct file *file, loff_t offset, int whence) @@ -778,7 +730,6 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, { struct dma_buf_attachment *attach; int ret; - unsigned int attach_uid; if (WARN_ON(!dmabuf || !dev)) return ERR_PTR(-EINVAL); @@ -804,13 +755,8 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, } dma_resv_lock(dmabuf->resv, NULL); list_add(&attach->node, &dmabuf->attachments); - attach_uid = dma_buf_update_attach_uid(dmabuf); dma_resv_unlock(dmabuf->resv); - ret = dma_buf_attach_stats_setup(attach, attach_uid); - if (ret) - goto err_sysfs; - /* When either the importer or the exporter can't handle dynamic * mappings we cache the mapping here to avoid issues with the * reservation object lock. @@ -837,7 +783,6 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, dma_resv_unlock(attach->dmabuf->resv); attach->sgt = sgt; attach->dir = DMA_BIDIRECTIONAL; - dma_buf_update_attachment_map_count(attach, 1 /* delta */); } return attach; @@ -854,7 +799,6 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, if (dma_buf_is_dynamic(attach->dmabuf)) dma_resv_unlock(attach->dmabuf->resv); -err_sysfs: dma_buf_detach(dmabuf, attach); return ERR_PTR(ret); } @@ -893,7 +837,6 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) dma_resv_lock(attach->dmabuf->resv, NULL); dmabuf->ops->unmap_dma_buf(attach, attach->sgt, attach->dir); - dma_buf_update_attachment_map_count(attach, -1 /* delta */); if (dma_buf_is_dynamic(attach->dmabuf)) { dma_buf_unpin(attach); @@ -907,7 +850,6 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) if (dmabuf->ops->detach) dmabuf->ops->detach(dmabuf, attach); - dma_buf_attach_stats_teardown(attach); kfree(attach); } EXPORT_SYMBOL_GPL(dma_buf_detach); @@ -1013,9 +955,6 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, attach->dir = direction; } - if (!IS_ERR(sg_table)) - dma_buf_update_attachment_map_count(attach, 1 /* delta */); - return sg_table; } EXPORT_SYMBOL_GPL(dma_buf_map_attachment); @@ -1053,8 +992,6 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, if (dma_buf_is_dynamic(attach->dmabuf) && !IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY)) dma_buf_unpin(attach); - - dma_buf_update_attachment_map_count(attach, -1 /* delta */); } EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment); diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 4931578df815..fd564aa70ee9 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -99,9 +99,10 @@ static struct sg_table *cma_heap_map_dma_buf(struct dma_buf_attachment *attachme { struct dma_heap_attachment *a = attachment->priv; struct sg_table *table = &a->table; + int attrs = attachment->dma_map_attrs; int ret; - ret = dma_map_sgtable(attachment->dev, table, direction, 0); + ret = dma_map_sgtable(attachment->dev, table, direction, attrs); if (ret) return ERR_PTR(-ENOMEM); a->mapped = true; @@ -113,9 +114,10 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, enum dma_data_direction direction) { struct dma_heap_attachment *a = attachment->priv; + int attrs = attachment->dma_map_attrs; a->mapped = false; - dma_unmap_sgtable(attachment->dev, table, direction, 0); + dma_unmap_sgtable(attachment->dev, table, direction, attrs); } static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, diff --git a/drivers/dma-buf/heaps/deferred-free-helper.c b/drivers/dma-buf/heaps/deferred-free-helper.c index e19c8b68dfeb..1330d279f48a 100644 --- a/drivers/dma-buf/heaps/deferred-free-helper.c +++ b/drivers/dma-buf/heaps/deferred-free-helper.c @@ -62,7 +62,7 @@ static size_t free_one_item(enum df_reason reason) return nr_pages; } -static unsigned long get_freelist_nr_pages(void) +unsigned long get_freelist_nr_pages(void) { unsigned long nr_pages; unsigned long flags; @@ -72,6 +72,7 @@ static unsigned long get_freelist_nr_pages(void) spin_unlock_irqrestore(&free_list_lock, flags); return nr_pages; } +EXPORT_SYMBOL_GPL(get_freelist_nr_pages); static unsigned long freelist_shrink_count(struct shrinker *shrinker, struct shrink_control *sc) diff --git a/drivers/dma-buf/heaps/deferred-free-helper.h b/drivers/dma-buf/heaps/deferred-free-helper.h index 11940328ce3f..415440314599 100644 --- a/drivers/dma-buf/heaps/deferred-free-helper.h +++ b/drivers/dma-buf/heaps/deferred-free-helper.h @@ -52,4 +52,6 @@ void deferred_free(struct deferred_freelist_item *item, void (*free)(struct deferred_freelist_item *i, enum df_reason reason), size_t nr_pages); + +unsigned long get_freelist_nr_pages(void); #endif diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 15796bc4c033..5f71a73a00a4 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -140,11 +140,11 @@ static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attac { struct dma_heap_attachment *a = attachment->priv; struct sg_table *table = a->table; - int attr = 0; + int attr = attachment->dma_map_attrs; int ret; if (a->uncached) - attr = DMA_ATTR_SKIP_CPU_SYNC; + attr |= DMA_ATTR_SKIP_CPU_SYNC; ret = dma_map_sgtable(attachment->dev, table, direction, attr); if (ret) @@ -159,10 +159,10 @@ static void system_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, enum dma_data_direction direction) { struct dma_heap_attachment *a = attachment->priv; - int attr = 0; + int attr = attachment->dma_map_attrs; if (a->uncached) - attr = DMA_ATTR_SKIP_CPU_SYNC; + attr |= DMA_ATTR_SKIP_CPU_SYNC; a->mapped = false; dma_unmap_sgtable(attachment->dev, table, direction, attr); } diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 02cee8468639..c957a168ce61 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1385,6 +1385,21 @@ void scmi_unrequest_protocol_device(const struct scmi_device_id *id_table) mutex_unlock(&scmi_requested_devices_mtx); } +static int scmi_cleanup_txrx_channels(struct scmi_info *info) +{ + int ret; + struct idr *idr = &info->tx_idr; + + ret = idr_for_each(idr, info->desc->ops->chan_free, idr); + idr_destroy(&info->tx_idr); + + idr = &info->rx_idr; + ret = idr_for_each(idr, info->desc->ops->chan_free, idr); + idr_destroy(&info->rx_idr); + + return ret; +} + static int scmi_probe(struct platform_device *pdev) { int ret; @@ -1426,7 +1441,7 @@ static int scmi_probe(struct platform_device *pdev) ret = scmi_xfer_info_init(info); if (ret) - return ret; + goto clear_txrx_setup; if (scmi_notification_init(handle)) dev_err(dev, "SCMI Notifications NOT available.\n"); @@ -1439,7 +1454,7 @@ static int scmi_probe(struct platform_device *pdev) ret = scmi_acquire_protocol(handle, SCMI_PROTOCOL_BASE); if (ret) { dev_err(dev, "unable to communicate with SCMI\n"); - return ret; + goto notification_exit; } mutex_lock(&scmi_list_mutex); @@ -1478,6 +1493,12 @@ static int scmi_probe(struct platform_device *pdev) } return 0; + +notification_exit: + scmi_notification_exit(&info->handle); +clear_txrx_setup: + scmi_cleanup_txrx_channels(info); + return ret; } void scmi_free_channel(struct scmi_chan_info *cinfo, struct idr *idr, int id) @@ -1489,7 +1510,6 @@ static int scmi_remove(struct platform_device *pdev) { int ret = 0, id; struct scmi_info *info = platform_get_drvdata(pdev); - struct idr *idr = &info->tx_idr; struct device_node *child; mutex_lock(&scmi_list_mutex); @@ -1513,14 +1533,7 @@ static int scmi_remove(struct platform_device *pdev) idr_destroy(&info->active_protocols); /* Safe to free channels since no more users */ - ret = idr_for_each(idr, info->desc->ops->chan_free, idr); - idr_destroy(&info->tx_idr); - - idr = &info->rx_idr; - ret = idr_for_each(idr, info->desc->ops->chan_free, idr); - idr_destroy(&info->rx_idr); - - return ret; + return scmi_cleanup_txrx_channels(info); } static ssize_t protocol_version_show(struct device *dev, diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index c4c9f41c0622..1504eb09f8e5 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -23,7 +23,7 @@ #include "coresight-priv.h" static DEFINE_MUTEX(coresight_mutex); -DEFINE_PER_CPU(struct coresight_device *, csdev_sink); +static DEFINE_PER_CPU(struct coresight_device *, csdev_sink); /** * struct coresight_node - elements of a path, from source to sink diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 90827077d2f9..6fee02bf7b71 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -115,7 +115,7 @@ void etm4x_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) } } -u64 ete_sysreg_read(u32 offset, bool _relaxed, bool _64bit) +static u64 ete_sysreg_read(u32 offset, bool _relaxed, bool _64bit) { u64 res = 0; @@ -132,7 +132,7 @@ u64 ete_sysreg_read(u32 offset, bool _relaxed, bool _64bit) return res; } -void ete_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) +static void ete_sysreg_write(u64 val, u32 offset, bool _relaxed, bool _64bit) { if (!_relaxed) __iowmb(); /* Imitate the !relaxed I/O helpers */ diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index a7484abda325..176868496879 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -5,6 +5,8 @@ * device (ETE) thus generating required trace data. Trace can be enabled * via the perf framework. * + * The AUX buffer handling is inspired from Arm SPE PMU driver. + * * Copyright (C) 2020 ARM Ltd. * * Author: Anshuman Khandual @@ -515,7 +517,7 @@ static void *arm_trbe_alloc_buffer(struct coresight_device *csdev, if (!buf->trbe_base) { kfree(pglist); kfree(buf); - return ERR_PTR(buf->trbe_base); + return ERR_PTR(-ENOMEM); } buf->trbe_limit = buf->trbe_base + nr_pages * PAGE_SIZE; buf->trbe_write = buf->trbe_base; @@ -614,9 +616,10 @@ static unsigned long arm_trbe_update_buffer(struct coresight_device *csdev, /* * Otherwise, the buffer is full and the write pointer * has reached base. Adjust this back to the Limit pointer - * for correct size. + * for correct size. Also, mark the buffer truncated. */ write = get_trbe_limit_pointer(); + perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED); } offset = write - base; @@ -703,7 +706,12 @@ static void trbe_handle_overflow(struct perf_output_handle *handle) if (buf->snapshot) handle->head += size; - perf_aux_output_flag(handle, PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW); + /* + * Mark the buffer as truncated, as we have stopped the trace + * collection upon the WRAP event, without stopping the source. + */ + perf_aux_output_flag(handle, PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW | + PERF_AUX_FLAG_TRUNCATED); perf_aux_output_end(handle, size); event_data = perf_aux_output_begin(handle, event); if (!event_data) { @@ -863,7 +871,7 @@ static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cp dev = &cpudata->drvdata->pdev->dev; desc.name = devm_kasprintf(dev, GFP_KERNEL, "trbe%d", cpu); - if (IS_ERR(desc.name)) + if (!desc.name) goto cpu_clear; desc.type = CORESIGHT_DEV_TYPE_SINK; @@ -1038,7 +1046,7 @@ static int arm_trbe_probe_irq(struct platform_device *pdev, if (irq_get_percpu_devid_partition(drvdata->irq, &drvdata->supported_cpus)) return -EINVAL; - drvdata->handle = alloc_percpu(typeof(*drvdata->handle)); + drvdata->handle = alloc_percpu(struct perf_output_handle *); if (!drvdata->handle) return -ENOMEM; diff --git a/drivers/hwtracing/coresight/coresight-trbe.h b/drivers/hwtracing/coresight/coresight-trbe.h index 499b846ccfee..abf3e36082f0 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.h +++ b/drivers/hwtracing/coresight/coresight-trbe.h @@ -128,8 +128,7 @@ static inline void set_trbe_write_pointer(unsigned long addr) static inline unsigned long get_trbe_limit_pointer(void) { u64 trblimitr = read_sysreg_s(SYS_TRBLIMITR_EL1); - unsigned long limit = (trblimitr >> TRBLIMITR_LIMIT_SHIFT) & TRBLIMITR_LIMIT_MASK; - unsigned long addr = limit << TRBLIMITR_LIMIT_SHIFT; + unsigned long addr = trblimitr & (TRBLIMITR_LIMIT_MASK << TRBLIMITR_LIMIT_SHIFT); WARN_ON(!IS_ALIGNED(addr, PAGE_SIZE)); return addr; diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 0a51e7d7bfea..7bbccb680c2b 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -434,9 +434,9 @@ static int dma_info_to_prot(enum dma_data_direction dir, bool coherent, if (attrs & DMA_ATTR_PRIVILEGED) prot |= IOMMU_PRIV; if (attrs & DMA_ATTR_SYS_CACHE_ONLY) - prot |= IOMMU_SYS_CACHE_ONLY; + prot |= IOMMU_SYS_CACHE; if (attrs & DMA_ATTR_SYS_CACHE_ONLY_NWA) - prot |= IOMMU_SYS_CACHE_ONLY_NWA; + prot |= IOMMU_SYS_CACHE_NWA; switch (dir) { case DMA_BIDIRECTIONAL: @@ -487,7 +487,7 @@ static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain, iova = alloc_iova_fast(iovad, iova_len, dma_limit >> shift, true); - trace_android_vh_iommu_alloc_iova(dev, iova, size); + trace_android_vh_iommu_alloc_iova(dev, (dma_addr_t)iova << shift, size); return (dma_addr_t)iova << shift; } diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 0d7bb004e587..ec31966b4f6f 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -112,18 +112,20 @@ #define ARM_LPAE_VTCR_PS_SHIFT 16 #define ARM_LPAE_VTCR_PS_MASK 0x7 -#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3) -#define ARM_LPAE_MAIR_ATTR_MASK 0xff -#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04ULL -#define ARM_LPAE_MAIR_ATTR_NC 0x44ULL -#define ARM_LPAE_MAIR_ATTR_INC_OWBRANWA 0xe4ULL -#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA 0xf4ULL -#define ARM_LPAE_MAIR_ATTR_WBRWA 0xffULL -#define ARM_LPAE_MAIR_ATTR_IDX_NC 0 -#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1 -#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2 -#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE 3 -#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA 4 +#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3) +#define ARM_LPAE_MAIR_ATTR_MASK 0xff +#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04ULL +#define ARM_LPAE_MAIR_ATTR_NC 0x44ULL +#define ARM_LPAE_MAIR_ATTR_INC_OWBRANWA 0xe4ULL +#define ARM_LPAE_MAIR_ATTR_IWBRWA_OWBRANWA 0xefULL +#define ARM_LPAE_MAIR_ATTR_INC_OWBRWA 0xf4ULL +#define ARM_LPAE_MAIR_ATTR_WBRWA 0xffULL +#define ARM_LPAE_MAIR_ATTR_IDX_NC 0 +#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1 +#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2 +#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE 3 +#define ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA 4 +#define ARM_LPAE_MAIR_ATTR_IDX_ICACHE_OCACHE_NWA 5 #define ARM_MALI_LPAE_TTBR_ADRMODE_TABLE (3u << 0) #define ARM_MALI_LPAE_TTBR_READ_INNER BIT(2) @@ -435,13 +437,17 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data, if (prot & IOMMU_MMIO) pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV << ARM_LPAE_PTE_ATTRINDX_SHIFT); + else if ((prot & IOMMU_CACHE) && (prot & IOMMU_SYS_CACHE_NWA)) + pte |= (ARM_LPAE_MAIR_ATTR_IDX_ICACHE_OCACHE_NWA + << ARM_LPAE_PTE_ATTRINDX_SHIFT); + /* IOMMU_CACHE + IOMMU_SYS_CACHE equivalent to IOMMU_CACHE */ else if (prot & IOMMU_CACHE) pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE << ARM_LPAE_PTE_ATTRINDX_SHIFT); - else if (prot & IOMMU_SYS_CACHE_ONLY) + else if (prot & IOMMU_SYS_CACHE) pte |= (ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE << ARM_LPAE_PTE_ATTRINDX_SHIFT); - else if (prot & IOMMU_SYS_CACHE_ONLY_NWA) + else if (prot & IOMMU_SYS_CACHE_NWA) pte |= (ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA << ARM_LPAE_PTE_ATTRINDX_SHIFT); } @@ -904,7 +910,9 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie) (ARM_LPAE_MAIR_ATTR_INC_OWBRWA << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE)) | (ARM_LPAE_MAIR_ATTR_INC_OWBRANWA - << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA)); + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_INC_OCACHE_NWA)) | + (ARM_LPAE_MAIR_ATTR_IWBRWA_OWBRANWA + << ARM_LPAE_MAIR_ATTR_SHIFT(ARM_LPAE_MAIR_ATTR_IDX_ICACHE_OCACHE_NWA)); cfg->arm_lpae_s1_cfg.mair = reg; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 078935a25afd..0fbc02fa6459 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -50,20 +50,6 @@ struct redist_region { bool single_redist; }; -struct gic_chip_data { - struct fwnode_handle *fwnode; - void __iomem *dist_base; - struct redist_region *redist_regions; - struct rdists rdists; - struct irq_domain *domain; - u64 redist_stride; - u32 nr_redist_regions; - u64 flags; - bool has_rss; - unsigned int ppi_nr; - struct partition_desc **ppi_descs; -}; - static struct gic_chip_data gic_data __read_mostly; static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); @@ -1269,7 +1255,7 @@ static inline void gic_cpu_pm_init(void) { } #ifdef CONFIG_PM void gic_resume(void) { - trace_android_vh_gic_resume(gic_data.domain, gic_data.dist_base); + trace_android_vh_gic_resume(&gic_data); } EXPORT_SYMBOL_GPL(gic_resume); diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 97baa541c826..0fb6e4e853a0 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -225,6 +225,7 @@ static long media_device_setup_link(struct media_device *mdev, void *arg) /* Setup the link on both entities */ trace_android_vh_media_device_setup_link(link, linkd, &ret); + trace_android_rvh_media_device_setup_link(link, linkd, &ret); if (ret) return ret; diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index a7d508e74d6b..ac6ce031c7b7 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -22,6 +22,9 @@ #include #include #include +#ifndef __GENKSYMS__ +#include +#endif #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API) static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd) @@ -511,10 +514,18 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_SUBDEV_S_FMT: { struct v4l2_subdev_format *format = arg; + int ret = 0; if (format->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev) return -EPERM; + trace_android_vh_v4l2subdev_set_fmt(sd, subdev_fh->pad, + format, &ret); + trace_android_rvh_v4l2subdev_set_fmt(sd, subdev_fh->pad, + format, &ret); + if (ret) + return ret; + memset(format->reserved, 0, sizeof(format->reserved)); memset(format->format.reserved, 0, sizeof(format->format.reserved)); return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh->pad, format); @@ -585,10 +596,16 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_SUBDEV_S_FRAME_INTERVAL: { struct v4l2_subdev_frame_interval *fi = arg; + int ret = 0; if (ro_subdev) return -EPERM; + trace_android_vh_v4l2subdev_set_frame_interval(sd, fi, &ret); + trace_android_rvh_v4l2subdev_set_frame_interval(sd, fi, &ret); + if (ret) + return ret; + memset(fi->reserved, 0, sizeof(fi->reserved)); return v4l2_subdev_call(sd, video, s_frame_interval, arg); } @@ -611,10 +628,18 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_SUBDEV_S_SELECTION: { struct v4l2_subdev_selection *sel = arg; + int ret = 0; if (sel->which != V4L2_SUBDEV_FORMAT_TRY && ro_subdev) return -EPERM; + trace_android_vh_v4l2subdev_set_selection(sd, subdev_fh->pad, + sel, &ret); + trace_android_rvh_v4l2subdev_set_selection(sd, subdev_fh->pad, + sel, &ret); + if (ret) + return ret; + memset(sel->reserved, 0, sizeof(sel->reserved)); return v4l2_subdev_call( sd, pad, set_selection, subdev_fh->pad, sel); diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index ca465794ea9c..df5cebb372a5 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -108,6 +108,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) syscon_config.max_register = resource_size(&res) - reg_io_width; regmap = regmap_init_mmio(NULL, base, &syscon_config); + kfree(syscon_config.name); if (IS_ERR(regmap)) { pr_err("regmap init failed\n"); ret = PTR_ERR(regmap); @@ -144,7 +145,6 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk) regmap_exit(regmap); err_regmap: iounmap(base); - kfree(syscon_config.name); err_map: kfree(syscon); return ERR_PTR(ret); diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index 42469fd31434..f989e80df327 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h @@ -32,6 +32,8 @@ struct mmc_bus_ops { int (*hw_reset)(struct mmc_host *); int (*sw_reset)(struct mmc_host *); bool (*cache_enabled)(struct mmc_host *); + + ANDROID_VENDOR_DATA_ARRAY(1, 2); }; void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 0770c036e2ff..63f51491fffe 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -605,6 +606,8 @@ struct sdhci_host { u64 data_timeout; + ANDROID_KABI_RESERVE(1); + unsigned long private[] ____cacheline_aligned; }; @@ -652,6 +655,8 @@ struct sdhci_ops { void (*request_done)(struct sdhci_host *host, struct mmc_request *mrq); void (*dump_vendor_regs)(struct sdhci_host *host); + + ANDROID_KABI_RESERVE(1); }; #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 854c6624e685..016d058f6967 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1890,7 +1890,7 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb) static const struct driver_info cdc_ncm_info = { .description = "CDC NCM", .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET - | FLAG_LINK_INTR, + | FLAG_LINK_INTR | FLAG_ETHER, .bind = cdc_ncm_bind, .unbind = cdc_ncm_unbind, .manage_power = usbnet_manage_power, diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index c966069845f4..31e21d8f2972 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -561,6 +561,7 @@ struct mac80211_hwsim_data { u32 ciphers[ARRAY_SIZE(hwsim_ciphers)]; struct mac_address addresses[2]; + struct ieee80211_chanctx_conf *chanctx; int channels, idx; bool use_chanctx; bool destroy_on_close; @@ -1191,7 +1192,8 @@ static inline u16 trans_tx_rate_flags_ieee2hwsim(struct ieee80211_tx_rate *rate) static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, struct sk_buff *my_skb, - int dst_portid) + int dst_portid, + struct ieee80211_channel *channel) { struct sk_buff *skb; struct mac80211_hwsim_data *data = hw->priv; @@ -1246,7 +1248,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, if (nla_put_u32(skb, HWSIM_ATTR_FLAGS, hwsim_flags)) goto nla_put_failure; - if (nla_put_u32(skb, HWSIM_ATTR_FREQ, data->channel->center_freq)) + if (nla_put_u32(skb, HWSIM_ATTR_FREQ, channel->center_freq)) goto nla_put_failure; /* We get the tx control (rate and retries) info*/ @@ -1593,7 +1595,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, _portid = READ_ONCE(data->wmediumd); if (_portid || hwsim_virtio_enabled) - return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); + return mac80211_hwsim_tx_frame_nl(hw, skb, _portid, channel); /* NO wmediumd detected, perfect medium simulation */ data->tx_pkts++; @@ -1704,7 +1706,7 @@ static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, mac80211_hwsim_monitor_rx(hw, skb, chan); if (_pid || hwsim_virtio_enabled) - return mac80211_hwsim_tx_frame_nl(hw, skb, _pid); + return mac80211_hwsim_tx_frame_nl(hw, skb, _pid, chan); mac80211_hwsim_tx_frame_no_nl(hw, skb, chan); dev_kfree_skb(skb); @@ -2443,6 +2445,11 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw, static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { + struct mac80211_hwsim_data *hwsim = hw->priv; + + mutex_lock(&hwsim->mutex); + hwsim->chanctx = ctx; + mutex_unlock(&hwsim->mutex); hwsim_set_chanctx_magic(ctx); wiphy_dbg(hw->wiphy, "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", @@ -2454,6 +2461,11 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw, static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx) { + struct mac80211_hwsim_data *hwsim = hw->priv; + + mutex_lock(&hwsim->mutex); + hwsim->chanctx = NULL; + mutex_unlock(&hwsim->mutex); wiphy_dbg(hw->wiphy, "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", ctx->def.chan->center_freq, ctx->def.width, @@ -2466,6 +2478,11 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw, struct ieee80211_chanctx_conf *ctx, u32 changed) { + struct mac80211_hwsim_data *hwsim = hw->priv; + + mutex_lock(&hwsim->mutex); + hwsim->chanctx = ctx; + mutex_unlock(&hwsim->mutex); hwsim_check_chanctx_magic(ctx); wiphy_dbg(hw->wiphy, "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", @@ -3060,6 +3077,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, hw->wiphy->max_remain_on_channel_duration = 1000; data->if_combination.radar_detect_widths = 0; data->if_combination.num_different_channels = data->channels; + data->chanctx = NULL; } else { data->if_combination.num_different_channels = 1; data->if_combination.radar_detect_widths = @@ -3567,6 +3585,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, int frame_data_len; void *frame_data; struct sk_buff *skb = NULL; + struct ieee80211_channel *channel = NULL; if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || !info->attrs[HWSIM_ATTR_FRAME] || @@ -3593,6 +3612,17 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, if (!data2) goto out; + if (data2->use_chanctx) { + if (data2->tmp_chan) + channel = data2->tmp_chan; + else if (data2->chanctx) + channel = data2->chanctx->def.chan; + } else { + channel = data2->channel; + } + if (!channel) + goto out; + if (!hwsim_virtio_enabled) { if (hwsim_net_get_netgroup(genl_info_net(info)) != data2->netgroup) @@ -3604,7 +3634,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, /* check if radio is configured properly */ - if (data2->idle || !data2->started) + if ((data2->idle && !data2->tmp_chan) || !data2->started) goto out; /* A frame is received from user space */ @@ -3617,18 +3647,16 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, mutex_lock(&data2->mutex); rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]); - if (rx_status.freq != data2->channel->center_freq && - (!data2->tmp_chan || - rx_status.freq != data2->tmp_chan->center_freq)) { + if (rx_status.freq != channel->center_freq) { mutex_unlock(&data2->mutex); goto out; } mutex_unlock(&data2->mutex); } else { - rx_status.freq = data2->channel->center_freq; + rx_status.freq = channel->center_freq; } - rx_status.band = data2->channel->band; + rx_status.band = channel->band; rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); diff --git a/drivers/of/base.c b/drivers/of/base.c index 161a23631472..5947d9218289 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1817,6 +1817,7 @@ int of_add_property(struct device_node *np, struct property *prop) return rc; } +EXPORT_SYMBOL_GPL(of_add_property); int __of_remove_property(struct device_node *np, struct property *prop) { diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d5d9ea864fe6..e5c3fb43a791 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -31,6 +31,9 @@ #include #include #include +#ifndef __GENKSYMS__ +#include +#endif #include "pci.h" DEFINE_MUTEX(pci_slot_mutex); @@ -64,12 +67,16 @@ struct pci_pme_device { static void pci_dev_d3_sleep(struct pci_dev *dev) { unsigned int delay = dev->d3hot_delay; + int err = -EOPNOTSUPP; if (delay < pci_pm_d3hot_delay) delay = pci_pm_d3hot_delay; - if (delay) - msleep(delay); + if (delay) { + trace_android_rvh_pci_d3_sleep(dev, delay, &err); + if (err == -EOPNOTSUPP) + msleep(delay); + } } #ifdef CONFIG_PCI_DOMAINS diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 9107ec4ca0d7..5ec0502c04c4 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "remoteproc_internal.h" @@ -1725,6 +1726,7 @@ int rproc_trigger_recovery(struct rproc *rproc) release_firmware(firmware_p); unlock_mutex: + trace_android_vh_rproc_recovery(rproc); mutex_unlock(&rproc->lock); return ret; } diff --git a/drivers/remoteproc/remoteproc_coredump.c b/drivers/remoteproc/remoteproc_coredump.c index aee657cc08c6..aa45b68c224b 100644 --- a/drivers/remoteproc/remoteproc_coredump.c +++ b/drivers/remoteproc/remoteproc_coredump.c @@ -32,6 +32,7 @@ void rproc_coredump_cleanup(struct rproc *rproc) kfree(entry); } } +EXPORT_SYMBOL(rproc_coredump_cleanup); /** * rproc_coredump_add_segment() - add segment of device memory to coredump @@ -327,6 +328,7 @@ void rproc_coredump(struct rproc *rproc) */ wait_for_completion(&dump_state.dump_done); } +EXPORT_SYMBOL(rproc_coredump); /** * rproc_coredump_using_sections() - perform coredump using section headers diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h index 9ea37aa687d2..b8bd681c6547 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -49,10 +49,6 @@ extern struct class rproc_class; int rproc_init_sysfs(void); void rproc_exit_sysfs(void); -/* from remoteproc_coredump.c */ -void rproc_coredump_cleanup(struct rproc *rproc); -void rproc_coredump(struct rproc *rproc); - #ifdef CONFIG_REMOTEPROC_CDEV void rproc_init_cdev(void); void rproc_exit_cdev(void); diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig index c339517b7a09..87900016448f 100644 --- a/drivers/scsi/ufs/Kconfig +++ b/drivers/scsi/ufs/Kconfig @@ -115,6 +115,7 @@ config SCSI_UFS_MEDIATEK tristate "Mediatek specific hooks to UFS controller platform driver" depends on SCSI_UFSHCD_PLATFORM && ARCH_MEDIATEK select PHY_MTK_UFS + select RESET_TI_SYSCON help This selects the Mediatek specific additions to UFSHCD platform driver. UFS host on Mediatek needs some vendor specific configuration before @@ -182,3 +183,12 @@ config SCSI_UFS_CRYPTO Enabling this makes it possible for the kernel to use the crypto capabilities of the UFS device (if present) to perform crypto operations on data being transferred to/from the device. + +config SCSI_UFS_HPB + bool "Support UFS Host Performance Booster" + depends on SCSI_UFSHCD + help + The UFS HPB feature improves random read performance. It caches + L2P (logical to physical) map of UFS to host DRAM. The driver uses HPB + read command by piggybacking physical page number for bypassing FTL (flash + translation layer)'s L2P address translation. diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 06f3a3fe4a44..cce9b3916f5b 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile @@ -8,6 +8,7 @@ ufshcd-core-y += ufshcd.o ufs-sysfs.o ufshcd-core-$(CONFIG_DEBUG_FS) += ufs-debugfs.o ufshcd-core-$(CONFIG_SCSI_UFS_BSG) += ufs_bsg.o ufshcd-core-$(CONFIG_SCSI_UFS_CRYPTO) += ufshcd-crypto.o +ufshcd-core-$(CONFIG_SCSI_UFS_HPB) += ufshpb.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c index 082c88628499..ca0ebb2c9b96 100644 --- a/drivers/scsi/ufs/ufs-mediatek.c +++ b/drivers/scsi/ufs/ufs-mediatek.c @@ -595,11 +595,23 @@ static void ufs_mtk_get_controller_version(struct ufs_hba *hba) ret = ufshcd_dme_get(hba, UIC_ARG_MIB(PA_LOCALVERINFO), &ver); if (!ret) { - if (ver >= UFS_UNIPRO_VER_1_8) + if (ver >= UFS_UNIPRO_VER_1_8) { host->hw_ver.major = 3; + /* + * Fix HCI version for some platforms with + * incorrect version + */ + if (hba->ufs_version < ufshci_version(3, 0)) + hba->ufs_version = ufshci_version(3, 0); + } } } +static u32 ufs_mtk_get_ufs_hci_version(struct ufs_hba *hba) +{ + return hba->ufs_version; +} + /** * ufs_mtk_init - find other essential mmio bases * @hba: host controller instance @@ -853,6 +865,9 @@ static int ufs_mtk_device_reset(struct ufs_hba *hba) { struct arm_smccc_res res; + /* disable hba before device reset */ + ufshcd_hba_stop(hba); + ufs_mtk_device_reset_ctrl(0, res); /* @@ -1055,6 +1070,7 @@ static void ufs_mtk_event_notify(struct ufs_hba *hba, static const struct ufs_hba_variant_ops ufs_hba_mtk_vops = { .name = "mediatek.ufshci", .init = ufs_mtk_init, + .get_ufs_hci_version = ufs_mtk_get_ufs_hci_version, .setup_clocks = ufs_mtk_setup_clocks, .hce_enable_notify = ufs_mtk_hce_enable_notify, .link_startup_notify = ufs_mtk_link_startup_notify, @@ -1078,12 +1094,42 @@ static int ufs_mtk_probe(struct platform_device *pdev) { int err; struct device *dev = &pdev->dev; + struct device_node *reset_node; + struct platform_device *reset_pdev; + struct device_link *link; + reset_node = of_find_compatible_node(NULL, NULL, + "ti,syscon-reset"); + if (!reset_node) { + dev_notice(dev, "find ti,syscon-reset fail\n"); + goto skip_reset; + } + reset_pdev = of_find_device_by_node(reset_node); + if (!reset_pdev) { + dev_notice(dev, "find reset_pdev fail\n"); + goto skip_reset; + } + link = device_link_add(dev, &reset_pdev->dev, + DL_FLAG_AUTOPROBE_CONSUMER); + if (!link) { + dev_notice(dev, "add reset device_link fail\n"); + goto skip_reset; + } + /* supplier is not probed */ + if (link->status == DL_STATE_DORMANT) { + err = -EPROBE_DEFER; + goto out; + } + +skip_reset: /* perform generic probe */ err = ufshcd_pltfrm_init(pdev, &ufs_hba_mtk_vops); + +out: if (err) dev_info(dev, "probe failed %d\n", err); + of_node_put(reset_node); return err; } diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c index 1f52f6817524..9fe3b93440f6 100644 --- a/drivers/scsi/ufs/ufs-qcom.c +++ b/drivers/scsi/ufs/ufs-qcom.c @@ -838,9 +838,9 @@ static u32 ufs_qcom_get_ufs_hci_version(struct ufs_hba *hba) struct ufs_qcom_host *host = ufshcd_get_variant(hba); if (host->hw_ver.major == 0x1) - return UFSHCI_VERSION_11; + return ufshci_version(1, 1); else - return UFSHCI_VERSION_20; + return ufshci_version(2, 0); } /** diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c index 7fe6825817f6..4c02591058c6 100644 --- a/drivers/scsi/ufs/ufs-sysfs.c +++ b/drivers/scsi/ufs/ufs-sysfs.c @@ -207,6 +207,242 @@ static const struct attribute_group ufs_sysfs_default_group = { .attrs = ufs_sysfs_ufshcd_attrs, }; +static ssize_t monitor_enable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%d\n", hba->monitor.enabled); +} + +static ssize_t monitor_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + unsigned long value, flags; + + if (kstrtoul(buf, 0, &value)) + return -EINVAL; + + value = !!value; + spin_lock_irqsave(hba->host->host_lock, flags); + if (value == hba->monitor.enabled) + goto out_unlock; + + if (!value) { + memset(&hba->monitor, 0, sizeof(hba->monitor)); + } else { + hba->monitor.enabled = true; + hba->monitor.enabled_ts = ktime_get(); + } + +out_unlock: + spin_unlock_irqrestore(hba->host->host_lock, flags); + return count; +} + +static ssize_t monitor_chunk_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%lu\n", hba->monitor.chunk_size); +} + +static ssize_t monitor_chunk_size_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + unsigned long value, flags; + + if (kstrtoul(buf, 0, &value)) + return -EINVAL; + + spin_lock_irqsave(hba->host->host_lock, flags); + /* Only allow chunk size change when monitor is disabled */ + if (!hba->monitor.enabled) + hba->monitor.chunk_size = value; + spin_unlock_irqrestore(hba->host->host_lock, flags); + return count; +} + +static ssize_t read_total_sectors_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%lu\n", hba->monitor.nr_sec_rw[READ]); +} + +static ssize_t read_total_busy_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%llu\n", + ktime_to_us(hba->monitor.total_busy[READ])); +} + +static ssize_t read_nr_requests_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%lu\n", hba->monitor.nr_req[READ]); +} + +static ssize_t read_req_latency_avg_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + struct ufs_hba_monitor *m = &hba->monitor; + + return sysfs_emit(buf, "%llu\n", div_u64(ktime_to_us(m->lat_sum[READ]), + m->nr_req[READ])); +} + +static ssize_t read_req_latency_max_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%llu\n", + ktime_to_us(hba->monitor.lat_max[READ])); +} + +static ssize_t read_req_latency_min_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%llu\n", + ktime_to_us(hba->monitor.lat_min[READ])); +} + +static ssize_t read_req_latency_sum_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%llu\n", + ktime_to_us(hba->monitor.lat_sum[READ])); +} + +static ssize_t write_total_sectors_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%lu\n", hba->monitor.nr_sec_rw[WRITE]); +} + +static ssize_t write_total_busy_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%llu\n", + ktime_to_us(hba->monitor.total_busy[WRITE])); +} + +static ssize_t write_nr_requests_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%lu\n", hba->monitor.nr_req[WRITE]); +} + +static ssize_t write_req_latency_avg_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + struct ufs_hba_monitor *m = &hba->monitor; + + return sysfs_emit(buf, "%llu\n", div_u64(ktime_to_us(m->lat_sum[WRITE]), + m->nr_req[WRITE])); +} + +static ssize_t write_req_latency_max_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%llu\n", + ktime_to_us(hba->monitor.lat_max[WRITE])); +} + +static ssize_t write_req_latency_min_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%llu\n", + ktime_to_us(hba->monitor.lat_min[WRITE])); +} + +static ssize_t write_req_latency_sum_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%llu\n", + ktime_to_us(hba->monitor.lat_sum[WRITE])); +} + +static DEVICE_ATTR_RW(monitor_enable); +static DEVICE_ATTR_RW(monitor_chunk_size); +static DEVICE_ATTR_RO(read_total_sectors); +static DEVICE_ATTR_RO(read_total_busy); +static DEVICE_ATTR_RO(read_nr_requests); +static DEVICE_ATTR_RO(read_req_latency_avg); +static DEVICE_ATTR_RO(read_req_latency_max); +static DEVICE_ATTR_RO(read_req_latency_min); +static DEVICE_ATTR_RO(read_req_latency_sum); +static DEVICE_ATTR_RO(write_total_sectors); +static DEVICE_ATTR_RO(write_total_busy); +static DEVICE_ATTR_RO(write_nr_requests); +static DEVICE_ATTR_RO(write_req_latency_avg); +static DEVICE_ATTR_RO(write_req_latency_max); +static DEVICE_ATTR_RO(write_req_latency_min); +static DEVICE_ATTR_RO(write_req_latency_sum); + +static struct attribute *ufs_sysfs_monitor_attrs[] = { + &dev_attr_monitor_enable.attr, + &dev_attr_monitor_chunk_size.attr, + &dev_attr_read_total_sectors.attr, + &dev_attr_read_total_busy.attr, + &dev_attr_read_nr_requests.attr, + &dev_attr_read_req_latency_avg.attr, + &dev_attr_read_req_latency_max.attr, + &dev_attr_read_req_latency_min.attr, + &dev_attr_read_req_latency_sum.attr, + &dev_attr_write_total_sectors.attr, + &dev_attr_write_total_busy.attr, + &dev_attr_write_nr_requests.attr, + &dev_attr_write_req_latency_avg.attr, + &dev_attr_write_req_latency_max.attr, + &dev_attr_write_req_latency_min.attr, + &dev_attr_write_req_latency_sum.attr, + NULL +}; + +static const struct attribute_group ufs_sysfs_monitor_group = { + .name = "monitor", + .attrs = ufs_sysfs_monitor_attrs, +}; + static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba, enum desc_idn desc_id, u8 desc_index, @@ -286,6 +522,8 @@ UFS_DEVICE_DESC_PARAM(device_version, _DEV_VER, 2); UFS_DEVICE_DESC_PARAM(number_of_secure_wpa, _NUM_SEC_WPA, 1); UFS_DEVICE_DESC_PARAM(psa_max_data_size, _PSA_MAX_DATA, 4); UFS_DEVICE_DESC_PARAM(psa_state_timeout, _PSA_TMT, 1); +UFS_DEVICE_DESC_PARAM(hpb_version, _HPB_VER, 2); +UFS_DEVICE_DESC_PARAM(hpb_control, _HPB_CONTROL, 1); UFS_DEVICE_DESC_PARAM(ext_feature_sup, _EXT_UFS_FEATURE_SUP, 4); UFS_DEVICE_DESC_PARAM(wb_presv_us_en, _WB_PRESRV_USRSPC_EN, 1); UFS_DEVICE_DESC_PARAM(wb_type, _WB_TYPE, 1); @@ -318,6 +556,8 @@ static struct attribute *ufs_sysfs_device_descriptor[] = { &dev_attr_number_of_secure_wpa.attr, &dev_attr_psa_max_data_size.attr, &dev_attr_psa_state_timeout.attr, + &dev_attr_hpb_version.attr, + &dev_attr_hpb_control.attr, &dev_attr_ext_feature_sup.attr, &dev_attr_wb_presv_us_en.attr, &dev_attr_wb_type.attr, @@ -391,6 +631,10 @@ UFS_GEOMETRY_DESC_PARAM(enh4_memory_max_alloc_units, _ENM4_MAX_NUM_UNITS, 4); UFS_GEOMETRY_DESC_PARAM(enh4_memory_capacity_adjustment_factor, _ENM4_CAP_ADJ_FCTR, 2); +UFS_GEOMETRY_DESC_PARAM(hpb_region_size, _HPB_REGION_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(hpb_number_lu, _HPB_NUMBER_LU, 1); +UFS_GEOMETRY_DESC_PARAM(hpb_subregion_size, _HPB_SUBREGION_SIZE, 1); +UFS_GEOMETRY_DESC_PARAM(hpb_max_active_regions, _HPB_MAX_ACTIVE_REGS, 2); UFS_GEOMETRY_DESC_PARAM(wb_max_alloc_units, _WB_MAX_ALLOC_UNITS, 4); UFS_GEOMETRY_DESC_PARAM(wb_max_wb_luns, _WB_MAX_WB_LUNS, 1); UFS_GEOMETRY_DESC_PARAM(wb_buff_cap_adj, _WB_BUFF_CAP_ADJ, 1); @@ -428,6 +672,10 @@ static struct attribute *ufs_sysfs_geometry_descriptor[] = { &dev_attr_enh3_memory_capacity_adjustment_factor.attr, &dev_attr_enh4_memory_max_alloc_units.attr, &dev_attr_enh4_memory_capacity_adjustment_factor.attr, + &dev_attr_hpb_region_size.attr, + &dev_attr_hpb_number_lu.attr, + &dev_attr_hpb_subregion_size.attr, + &dev_attr_hpb_max_active_regions.attr, &dev_attr_wb_max_alloc_units.attr, &dev_attr_wb_max_wb_luns.attr, &dev_attr_wb_buff_cap_adj.attr, @@ -669,6 +917,7 @@ UFS_FLAG(disable_fw_update, _PERMANENTLY_DISABLE_FW_UPDATE); UFS_FLAG(wb_enable, _WB_EN); UFS_FLAG(wb_flush_en, _WB_BUFF_FLUSH_EN); UFS_FLAG(wb_flush_during_h8, _WB_BUFF_FLUSH_DURING_HIBERN8); +UFS_FLAG(hpb_enable, _HPB_EN); static struct attribute *ufs_sysfs_device_flags[] = { &dev_attr_device_init.attr, @@ -682,6 +931,7 @@ static struct attribute *ufs_sysfs_device_flags[] = { &dev_attr_wb_enable.attr, &dev_attr_wb_flush_en.attr, &dev_attr_wb_flush_during_h8.attr, + &dev_attr_hpb_enable.attr, NULL, }; @@ -717,6 +967,7 @@ static ssize_t _name##_show(struct device *dev, \ static DEVICE_ATTR_RO(_name) UFS_ATTRIBUTE(boot_lun_enabled, _BOOT_LU_EN); +UFS_ATTRIBUTE(max_data_size_hpb_single_cmd, _MAX_HPB_SINGLE_CMD); UFS_ATTRIBUTE(current_power_mode, _POWER_MODE); UFS_ATTRIBUTE(active_icc_level, _ACTIVE_ICC_LVL); UFS_ATTRIBUTE(ooo_data_enabled, _OOO_DATA_EN); @@ -740,6 +991,7 @@ UFS_ATTRIBUTE(wb_cur_buf, _CURR_WB_BUFF_SIZE); static struct attribute *ufs_sysfs_attributes[] = { &dev_attr_boot_lun_enabled.attr, + &dev_attr_max_data_size_hpb_single_cmd.attr, &dev_attr_current_power_mode.attr, &dev_attr_active_icc_level.attr, &dev_attr_ooo_data_enabled.attr, @@ -769,6 +1021,7 @@ static const struct attribute_group ufs_sysfs_attributes_group = { static const struct attribute_group *ufs_sysfs_groups[] = { &ufs_sysfs_default_group, + &ufs_sysfs_monitor_group, &ufs_sysfs_device_descriptor_group, &ufs_sysfs_interconnect_descriptor_group, &ufs_sysfs_geometry_descriptor_group, @@ -811,6 +1064,9 @@ UFS_UNIT_DESC_PARAM(provisioning_type, _PROVISIONING_TYPE, 1); UFS_UNIT_DESC_PARAM(physical_memory_resourse_count, _PHY_MEM_RSRC_CNT, 8); UFS_UNIT_DESC_PARAM(context_capabilities, _CTX_CAPABILITIES, 2); UFS_UNIT_DESC_PARAM(large_unit_granularity, _LARGE_UNIT_SIZE_M1, 1); +UFS_UNIT_DESC_PARAM(hpb_lu_max_active_regions, _HPB_LU_MAX_ACTIVE_RGNS, 2); +UFS_UNIT_DESC_PARAM(hpb_pinned_region_start_offset, _HPB_PIN_RGN_START_OFF, 2); +UFS_UNIT_DESC_PARAM(hpb_number_pinned_regions, _HPB_NUM_PIN_RGNS, 2); UFS_UNIT_DESC_PARAM(wb_buf_alloc_units, _WB_BUF_ALLOC_UNITS, 4); @@ -828,6 +1084,9 @@ static struct attribute *ufs_sysfs_unit_descriptor[] = { &dev_attr_physical_memory_resourse_count.attr, &dev_attr_context_capabilities.attr, &dev_attr_large_unit_granularity.attr, + &dev_attr_hpb_lu_max_active_regions.attr, + &dev_attr_hpb_pinned_region_start_offset.attr, + &dev_attr_hpb_number_pinned_regions.attr, &dev_attr_wb_buf_alloc_units.attr, NULL, }; diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 7f1d4c73b674..1ee80cda3d01 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h @@ -13,6 +13,7 @@ #include #include +#include #include #define GENERAL_UPIU_REQUEST_SIZE (sizeof(struct utp_upiu_req)) @@ -122,12 +123,14 @@ enum flag_idn { QUERY_FLAG_IDN_WB_EN = 0x0E, QUERY_FLAG_IDN_WB_BUFF_FLUSH_EN = 0x0F, QUERY_FLAG_IDN_WB_BUFF_FLUSH_DURING_HIBERN8 = 0x10, + QUERY_FLAG_IDN_HPB_RESET = 0x11, + QUERY_FLAG_IDN_HPB_EN = 0x12, }; /* Attribute idn for Query requests */ enum attr_idn { QUERY_ATTR_IDN_BOOT_LU_EN = 0x00, - QUERY_ATTR_IDN_RESERVED = 0x01, + QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD = 0x01, QUERY_ATTR_IDN_POWER_MODE = 0x02, QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, QUERY_ATTR_IDN_OOO_DATA_EN = 0x04, @@ -195,6 +198,9 @@ enum unit_desc_param { UNIT_DESC_PARAM_PHY_MEM_RSRC_CNT = 0x18, UNIT_DESC_PARAM_CTX_CAPABILITIES = 0x20, UNIT_DESC_PARAM_LARGE_UNIT_SIZE_M1 = 0x22, + UNIT_DESC_PARAM_HPB_LU_MAX_ACTIVE_RGNS = 0x23, + UNIT_DESC_PARAM_HPB_PIN_RGN_START_OFF = 0x25, + UNIT_DESC_PARAM_HPB_NUM_PIN_RGNS = 0x27, UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS = 0x29, }; @@ -235,6 +241,8 @@ enum device_desc_param { DEVICE_DESC_PARAM_PSA_MAX_DATA = 0x25, DEVICE_DESC_PARAM_PSA_TMT = 0x29, DEVICE_DESC_PARAM_PRDCT_REV = 0x2A, + DEVICE_DESC_PARAM_HPB_VER = 0x40, + DEVICE_DESC_PARAM_HPB_CONTROL = 0x42, DEVICE_DESC_PARAM_EXT_UFS_FEATURE_SUP = 0x4F, DEVICE_DESC_PARAM_WB_PRESRV_USRSPC_EN = 0x53, DEVICE_DESC_PARAM_WB_TYPE = 0x54, @@ -283,6 +291,10 @@ enum geometry_desc_param { GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS = 0x3E, GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR = 0x42, GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE = 0x44, + GEOMETRY_DESC_PARAM_HPB_REGION_SIZE = 0x48, + GEOMETRY_DESC_PARAM_HPB_NUMBER_LU = 0x49, + GEOMETRY_DESC_PARAM_HPB_SUBREGION_SIZE = 0x4A, + GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS = 0x4B, GEOMETRY_DESC_PARAM_WB_MAX_ALLOC_UNITS = 0x4F, GEOMETRY_DESC_PARAM_WB_MAX_WB_LUNS = 0x53, GEOMETRY_DESC_PARAM_WB_BUFF_CAP_ADJ = 0x54, @@ -327,8 +339,10 @@ enum { /* Possible values for dExtendedUFSFeaturesSupport */ enum { + UFS_DEV_HPB_SUPPORT = BIT(7), UFS_DEV_WRITE_BOOSTER_SUP = BIT(8), }; +#define UFS_DEV_HPB_SUPPORT_VERSION 0x310 #define POWER_DESC_MAX_SIZE 0x62 #define POWER_DESC_MAX_ACTV_ICC_LVLS 16 @@ -460,6 +474,41 @@ struct utp_cmd_rsp { u8 sense_data[UFS_SENSE_SIZE]; }; +struct ufshpb_active_field { + __be16 active_rgn; + __be16 active_srgn; +}; +#define HPB_ACT_FIELD_SIZE 4 + +/** + * struct utp_hpb_rsp - Response UPIU structure + * @residual_transfer_count: Residual transfer count DW-3 + * @reserved1: Reserved double words DW-4 to DW-7 + * @sense_data_len: Sense data length DW-8 U16 + * @desc_type: Descriptor type of sense data + * @additional_len: Additional length of sense data + * @hpb_op: HPB operation type + * @lun: LUN of response UPIU + * @active_rgn_cnt: Active region count + * @inactive_rgn_cnt: Inactive region count + * @hpb_active_field: Recommended to read HPB region and subregion + * @hpb_inactive_field: To be inactivated HPB region and subregion + */ +struct utp_hpb_rsp { + __be32 residual_transfer_count; + __be32 reserved1[4]; + __be16 sense_data_len; + u8 desc_type; + u8 additional_len; + u8 hpb_op; + u8 lun; + u8 active_rgn_cnt; + u8 inactive_rgn_cnt; + struct ufshpb_active_field hpb_active_field[2]; + __be16 hpb_inactive_field[2]; +}; +#define UTP_HPB_RSP_SIZE 40 + /** * struct utp_upiu_rsp - general upiu response structure * @header: UPIU header structure DW-0 to DW-2 @@ -470,6 +519,7 @@ struct utp_upiu_rsp { struct utp_upiu_header header; union { struct utp_cmd_rsp sr; + struct utp_hpb_rsp hr; struct utp_upiu_query qr; }; }; @@ -543,6 +593,9 @@ struct ufs_dev_info { u32 d_wb_alloc_units; bool b_rpm_dev_flush_capable; u8 b_presrv_uspc_en; + /* UFS HPB related flag */ + bool hpb_enabled; + ANDROID_KABI_RESERVE(1); }; /** diff --git a/drivers/scsi/ufs/ufshcd-crypto.c b/drivers/scsi/ufs/ufshcd-crypto.c index 734dd09ffb88..7604c0744746 100644 --- a/drivers/scsi/ufs/ufshcd-crypto.c +++ b/drivers/scsi/ufs/ufshcd-crypto.c @@ -6,6 +6,9 @@ #include "ufshcd.h" #include "ufshcd-crypto.h" +#undef CREATE_TRACE_POINTS +#include + /* Blk-crypto modes supported by UFS crypto */ static const struct ufs_crypto_alg_entry { enum ufs_crypto_alg ufs_alg; @@ -120,8 +123,13 @@ bool ufshcd_crypto_enable(struct ufs_hba *hba) return false; /* Reset might clear all keys, so reprogram all the keys. */ - if (hba->ksm.num_slots) - blk_ksm_reprogram_all_keys(&hba->ksm); + if (hba->ksm.num_slots) { + int err = -EOPNOTSUPP; + + trace_android_rvh_ufs_reprogram_all_keys(hba, &err); + if (err == -EOPNOTSUPP) + blk_ksm_reprogram_all_keys(&hba->ksm); + } if (hba->quirks & UFSHCD_QUIRK_BROKEN_CRYPTO_ENABLE) return false; diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index d983a7db461b..b17dedc68732 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c @@ -23,6 +23,7 @@ #include "ufs-debugfs.h" #include "ufs_bsg.h" #include "ufshcd-crypto.h" +#include "ufshpb.h" #include #include @@ -36,7 +37,7 @@ UTP_TASK_REQ_COMPL |\ UFSHCD_ERROR_MASK) /* UIC command timeout, unit: ms */ -#define UIC_CMD_TIMEOUT 500 +#define UIC_CMD_TIMEOUT 5000 /* NOP OUT retries waiting for NOP IN response */ #define NOP_OUT_RETRIES 10 @@ -637,23 +638,12 @@ int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask, */ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba) { - u32 intr_mask = 0; + if (hba->ufs_version == ufshci_version(1, 0)) + return INTERRUPT_MASK_ALL_VER_10; + if (hba->ufs_version <= ufshci_version(2, 0)) + return INTERRUPT_MASK_ALL_VER_11; - switch (hba->ufs_version) { - case UFSHCI_VERSION_10: - intr_mask = INTERRUPT_MASK_ALL_VER_10; - break; - case UFSHCI_VERSION_11: - case UFSHCI_VERSION_20: - intr_mask = INTERRUPT_MASK_ALL_VER_11; - break; - case UFSHCI_VERSION_21: - default: - intr_mask = INTERRUPT_MASK_ALL_VER_21; - break; - } - - return intr_mask; + return INTERRUPT_MASK_ALL_VER_21; } /** @@ -664,10 +654,22 @@ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba) */ static inline u32 ufshcd_get_ufs_version(struct ufs_hba *hba) { - if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION) - return ufshcd_vops_get_ufs_hci_version(hba); + u32 ufshci_ver; - return ufshcd_readl(hba, REG_UFS_VERSION); + if (hba->quirks & UFSHCD_QUIRK_BROKEN_UFS_HCI_VERSION) + ufshci_ver = ufshcd_vops_get_ufs_hci_version(hba); + else + ufshci_ver = ufshcd_readl(hba, REG_UFS_VERSION); + + /* + * UFSHCI v1.x uses a different version scheme, in order + * to allow the use of comparisons with the ufshci_version + * function, we convert it to the same scheme as ufs 2.0+. + */ + if (ufshci_ver & 0x00010000) + return ufshci_version(1, ufshci_ver & 0x00000100); + + return ufshci_ver; } /** @@ -729,7 +731,7 @@ static inline void ufshcd_utmrl_clear(struct ufs_hba *hba, u32 pos) */ static inline void ufshcd_outstanding_req_clear(struct ufs_hba *hba, int tag) { - __clear_bit(tag, &hba->outstanding_reqs); + clear_bit(tag, &hba->outstanding_reqs); } /** @@ -899,8 +901,7 @@ static inline bool ufshcd_is_hba_active(struct ufs_hba *hba) u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba) { /* HCI version 1.0 and 1.1 supports UniPro 1.41 */ - if ((hba->ufs_version == UFSHCI_VERSION_10) || - (hba->ufs_version == UFSHCI_VERSION_11)) + if (hba->ufs_version <= ufshci_version(1, 1)) return UFS_UNIPRO_VER_1_41; else return UFS_UNIPRO_VER_1_6; @@ -1287,6 +1288,8 @@ static int ufshcd_devfreq_target(struct device *dev, struct list_head *clk_list = &hba->clk_list_head; struct ufs_clk_info *clki; unsigned long irq_flags; + bool force_out = false; + bool force_scaling = false; if (!ufshcd_is_clkscaling_supported(hba)) return -EINVAL; @@ -1312,8 +1315,11 @@ static int ufshcd_devfreq_target(struct device *dev, scale_up = (*freq == clki->max_freq) ? true : false; if (!scale_up) *freq = clki->min_freq; + + trace_android_vh_ufs_clock_scaling(hba, &force_out, &force_scaling, &scale_up); + /* Update the frequency */ - if (!ufshcd_is_devfreq_scaling_required(hba, scale_up)) { + if (force_out || (!force_scaling && !ufshcd_is_devfreq_scaling_required(hba, scale_up))) { spin_unlock_irqrestore(hba->host->host_lock, irq_flags); ret = 0; goto out; /* no state change required */ @@ -1956,15 +1962,19 @@ static void ufshcd_clk_scaling_start_busy(struct ufs_hba *hba) { bool queue_resume_work = false; ktime_t curr_t = ktime_get(); + unsigned long flags; if (!ufshcd_is_clkscaling_supported(hba)) return; + spin_lock_irqsave(hba->host->host_lock, flags); if (!hba->clk_scaling.active_reqs++) queue_resume_work = true; - if (!hba->clk_scaling.is_enabled || hba->pm_op_in_progress) + if (!hba->clk_scaling.is_enabled || hba->pm_op_in_progress) { + spin_unlock_irqrestore(hba->host->host_lock, flags); return; + } if (queue_resume_work) queue_work(hba->clk_scaling.workq, @@ -1980,22 +1990,91 @@ static void ufshcd_clk_scaling_start_busy(struct ufs_hba *hba) hba->clk_scaling.busy_start_t = curr_t; hba->clk_scaling.is_busy_started = true; } + spin_unlock_irqrestore(hba->host->host_lock, flags); } static void ufshcd_clk_scaling_update_busy(struct ufs_hba *hba) { struct ufs_clk_scaling *scaling = &hba->clk_scaling; + unsigned long flags; if (!ufshcd_is_clkscaling_supported(hba)) return; + spin_lock_irqsave(hba->host->host_lock, flags); + hba->clk_scaling.active_reqs--; if (!hba->outstanding_reqs && scaling->is_busy_started) { scaling->tot_busy_t += ktime_to_us(ktime_sub(ktime_get(), scaling->busy_start_t)); scaling->busy_start_t = 0; scaling->is_busy_started = false; } + spin_unlock_irqrestore(hba->host->host_lock, flags); } + +static inline int ufshcd_monitor_opcode2dir(u8 opcode) +{ + if (opcode == READ_6 || opcode == READ_10 || opcode == READ_16) + return READ; + else if (opcode == WRITE_6 || opcode == WRITE_10 || opcode == WRITE_16) + return WRITE; + else + return -EINVAL; +} + +static inline bool ufshcd_should_inform_monitor(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp) +{ + struct ufs_hba_monitor *m = &hba->monitor; + + return (m->enabled && lrbp && lrbp->cmd && + (!m->chunk_size || m->chunk_size == lrbp->cmd->sdb.length) && + ktime_before(hba->monitor.enabled_ts, lrbp->issue_time_stamp)); +} + +static void ufshcd_start_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + int dir = ufshcd_monitor_opcode2dir(*lrbp->cmd->cmnd); + unsigned long flags; + + spin_lock_irqsave(hba->host->host_lock, flags); + if (dir >= 0 && hba->monitor.nr_queued[dir]++ == 0) + hba->monitor.busy_start_ts[dir] = ktime_get(); + spin_unlock_irqrestore(hba->host->host_lock, flags); +} + +static void ufshcd_update_monitor(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + int dir = ufshcd_monitor_opcode2dir(*lrbp->cmd->cmnd); + unsigned long flags; + + spin_lock_irqsave(hba->host->host_lock, flags); + if (dir >= 0 && hba->monitor.nr_queued[dir] > 0) { + struct request *req = lrbp->cmd->request; + struct ufs_hba_monitor *m = &hba->monitor; + ktime_t now, inc, lat; + + now = lrbp->compl_time_stamp; + inc = ktime_sub(now, m->busy_start_ts[dir]); + m->total_busy[dir] = ktime_add(m->total_busy[dir], inc); + m->nr_sec_rw[dir] += blk_rq_sectors(req); + + /* Update latencies */ + m->nr_req[dir]++; + lat = ktime_sub(now, lrbp->issue_time_stamp); + m->lat_sum[dir] += lat; + if (m->lat_max[dir] < lat || !m->lat_max[dir]) + m->lat_max[dir] = lat; + if (m->lat_min[dir] > lat || !m->lat_min[dir]) + m->lat_min[dir] = lat; + + m->nr_queued[dir]--; + /* Push forward the busy start of monitor */ + m->busy_start_ts[dir] = now; + } + spin_unlock_irqrestore(hba->host->host_lock, flags); +} + /** * ufshcd_send_command - Send SCSI or device management commands * @hba: per adapter instance @@ -2012,8 +2091,21 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) trace_android_vh_ufs_send_command(hba, lrbp); ufshcd_add_command_trace(hba, task_tag, "send"); ufshcd_clk_scaling_start_busy(hba); - __set_bit(task_tag, &hba->outstanding_reqs); - ufshcd_writel(hba, 1 << task_tag, REG_UTP_TRANSFER_REQ_DOOR_BELL); + if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) + ufshcd_start_monitor(hba, lrbp); + if (ufshcd_has_utrlcnr(hba)) { + set_bit(task_tag, &hba->outstanding_reqs); + ufshcd_writel(hba, 1 << task_tag, + REG_UTP_TRANSFER_REQ_DOOR_BELL); + } else { + unsigned long flags; + + spin_lock_irqsave(hba->host->host_lock, flags); + set_bit(task_tag, &hba->outstanding_reqs); + ufshcd_writel(hba, 1 << task_tag, + REG_UTP_TRANSFER_REQ_DOOR_BELL); + spin_unlock_irqrestore(hba->host->host_lock, flags); + } /* Make sure that doorbell is committed immediately */ wmb(); } @@ -2231,6 +2323,9 @@ int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) int ret; unsigned long flags; + if (hba->quirks & UFSHCD_QUIRK_BROKEN_UIC_CMD) + return 0; + ufshcd_hold(hba, false); mutex_lock(&hba->uic_cmd_mutex); ufshcd_add_delay_before_dme_cmd(hba); @@ -2307,7 +2402,7 @@ static void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs) { u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); - if (hba->ufs_version == UFSHCI_VERSION_10) { + if (hba->ufs_version == ufshci_version(1, 0)) { u32 rw; rw = set & INTERRUPT_MASK_RW_VER_10; set = rw | ((set ^ intrs) & intrs); @@ -2327,7 +2422,7 @@ static void ufshcd_disable_intr(struct ufs_hba *hba, u32 intrs) { u32 set = ufshcd_readl(hba, REG_INTERRUPT_ENABLE); - if (hba->ufs_version == UFSHCI_VERSION_10) { + if (hba->ufs_version == ufshci_version(1, 0)) { u32 rw; rw = (set & INTERRUPT_MASK_RW_VER_10) & ~(intrs & INTERRUPT_MASK_RW_VER_10); @@ -2490,8 +2585,7 @@ static int ufshcd_compose_devman_upiu(struct ufs_hba *hba, u8 upiu_flags; int ret = 0; - if ((hba->ufs_version == UFSHCI_VERSION_10) || - (hba->ufs_version == UFSHCI_VERSION_11)) + if (hba->ufs_version <= ufshci_version(1, 1)) lrbp->command_type = UTP_CMD_TYPE_DEV_MANAGE; else lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; @@ -2518,8 +2612,7 @@ static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) u8 upiu_flags; int ret = 0; - if ((hba->ufs_version == UFSHCI_VERSION_10) || - (hba->ufs_version == UFSHCI_VERSION_11)) + if (hba->ufs_version <= ufshci_version(1, 1)) lrbp->command_type = UTP_CMD_TYPE_SCSI; else lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; @@ -2579,7 +2672,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) { struct ufshcd_lrb *lrbp; struct ufs_hba *hba; - unsigned long flags; int tag; int err = 0; @@ -2596,6 +2688,43 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) if (!down_read_trylock(&hba->clk_scaling_lock)) return SCSI_MLQUEUE_HOST_BUSY; + switch (hba->ufshcd_state) { + case UFSHCD_STATE_OPERATIONAL: + case UFSHCD_STATE_EH_SCHEDULED_NON_FATAL: + break; + case UFSHCD_STATE_EH_SCHEDULED_FATAL: + /* + * pm_runtime_get_sync() is used at error handling preparation + * stage. If a scsi cmd, e.g. the SSU cmd, is sent from hba's + * PM ops, it can never be finished if we let SCSI layer keep + * retrying it, which gets err handler stuck forever. Neither + * can we let the scsi cmd pass through, because UFS is in bad + * state, the scsi cmd may eventually time out, which will get + * err handler blocked for too long. So, just fail the scsi cmd + * sent from PM ops, err handler can recover PM error anyways. + */ + if (hba->pm_op_in_progress) { + hba->force_reset = true; + set_host_byte(cmd, DID_BAD_TARGET); + cmd->scsi_done(cmd); + goto out; + } + fallthrough; + case UFSHCD_STATE_RESET: + err = SCSI_MLQUEUE_HOST_BUSY; + goto out; + case UFSHCD_STATE_ERROR: + set_host_byte(cmd, DID_ERROR); + cmd->scsi_done(cmd); + goto out; + default: + dev_WARN_ONCE(hba->dev, 1, "%s: invalid state %d\n", + __func__, hba->ufshcd_state); + set_host_byte(cmd, DID_BAD_TARGET); + cmd->scsi_done(cmd); + goto out; + } + hba->req_abort_count = 0; err = ufshcd_hold(hba, true); @@ -2607,15 +2736,6 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) (hba->clk_gating.state != CLKS_ON)); lrbp = &hba->lrb[tag]; - if (unlikely(lrbp->in_use)) { - if (hba->pm_op_in_progress) - set_host_byte(cmd, DID_BAD_TARGET); - else - err = SCSI_MLQUEUE_HOST_BUSY; - ufshcd_release(hba); - goto out; - } - WARN_ON(lrbp->cmd); lrbp->cmd = cmd; lrbp->sense_bufflen = UFS_SENSE_SIZE; @@ -2635,6 +2755,13 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) lrbp->req_abort_skip = false; + err = ufshpb_prep(hba, lrbp); + if (err == -EAGAIN) { + lrbp->cmd = NULL; + ufshcd_release(hba); + goto out; + } + ufshcd_comp_scsi_upiu(hba, lrbp); err = ufshcd_map_sg(hba, lrbp); @@ -2646,51 +2773,7 @@ static int ufshcd_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) /* Make sure descriptors are ready before ringing the doorbell */ wmb(); - spin_lock_irqsave(hba->host->host_lock, flags); - switch (hba->ufshcd_state) { - case UFSHCD_STATE_OPERATIONAL: - case UFSHCD_STATE_EH_SCHEDULED_NON_FATAL: - break; - case UFSHCD_STATE_EH_SCHEDULED_FATAL: - /* - * pm_runtime_get_sync() is used at error handling preparation - * stage. If a scsi cmd, e.g. the SSU cmd, is sent from hba's - * PM ops, it can never be finished if we let SCSI layer keep - * retrying it, which gets err handler stuck forever. Neither - * can we let the scsi cmd pass through, because UFS is in bad - * state, the scsi cmd may eventually time out, which will get - * err handler blocked for too long. So, just fail the scsi cmd - * sent from PM ops, err handler can recover PM error anyways. - */ - if (hba->pm_op_in_progress) { - hba->force_reset = true; - set_host_byte(cmd, DID_BAD_TARGET); - goto out_compl_cmd; - } - fallthrough; - case UFSHCD_STATE_RESET: - err = SCSI_MLQUEUE_HOST_BUSY; - goto out_compl_cmd; - case UFSHCD_STATE_ERROR: - set_host_byte(cmd, DID_ERROR); - goto out_compl_cmd; - default: - dev_WARN_ONCE(hba->dev, 1, "%s: invalid state %d\n", - __func__, hba->ufshcd_state); - set_host_byte(cmd, DID_BAD_TARGET); - goto out_compl_cmd; - } ufshcd_send_command(hba, tag); - spin_unlock_irqrestore(hba->host->host_lock, flags); - goto out; - -out_compl_cmd: - scsi_dma_unmap(lrbp->cmd); - lrbp->cmd = NULL; - spin_unlock_irqrestore(hba->host->host_lock, flags); - ufshcd_release(hba); - if (!err) - cmd->scsi_done(cmd); out: up_read(&hba->clk_scaling_lock); return err; @@ -2845,7 +2928,6 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, int err; int tag; struct completion wait; - unsigned long flags; down_read(&hba->clk_scaling_lock); @@ -2867,32 +2949,23 @@ static int ufshcd_exec_dev_cmd(struct ufs_hba *hba, init_completion(&wait); lrbp = &hba->lrb[tag]; - if (unlikely(lrbp->in_use)) { - err = -EBUSY; - goto out; - } - WARN_ON(lrbp->cmd); err = ufshcd_compose_dev_cmd(hba, lrbp, cmd_type, tag); if (unlikely(err)) - goto out_put_tag; + goto out; hba->dev_cmd.complete = &wait; ufshcd_add_query_upiu_trace(hba, tag, "query_send"); /* Make sure descriptors are ready before ringing the doorbell */ wmb(); - spin_lock_irqsave(hba->host->host_lock, flags); + ufshcd_send_command(hba, tag); - spin_unlock_irqrestore(hba->host->host_lock, flags); - err = ufshcd_wait_for_dev_cmd(hba, lrbp, timeout); - -out: ufshcd_add_query_upiu_trace(hba, tag, err ? "query_complete_err" : "query_complete"); -out_put_tag: +out: blk_put_request(req); out_unlock: up_read(&hba->clk_scaling_lock); @@ -3036,14 +3109,14 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, BUG_ON(!hba); - ufshcd_hold(hba, false); if (!attr_val) { dev_err(hba->dev, "%s: attribute value required for opcode 0x%x\n", __func__, opcode); - err = -EINVAL; - goto out; + return -EINVAL; } + ufshcd_hold(hba, false); + mutex_lock(&hba->dev_cmd.lock); ufshcd_init_query(hba, &request, &response, opcode, idn, index, selector); @@ -3075,7 +3148,6 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, out_unlock: mutex_unlock(&hba->dev_cmd.lock); -out: ufshcd_release(hba); return err; } @@ -3129,21 +3201,20 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba, BUG_ON(!hba); - ufshcd_hold(hba, false); if (!desc_buf) { dev_err(hba->dev, "%s: descriptor buffer required for opcode 0x%x\n", __func__, opcode); - err = -EINVAL; - goto out; + return -EINVAL; } if (*buf_len < QUERY_DESC_MIN_SIZE || *buf_len > QUERY_DESC_MAX_SIZE) { dev_err(hba->dev, "%s: descriptor buffer size (%d) is out of range\n", __func__, *buf_len); - err = -EINVAL; - goto out; + return -EINVAL; } + ufshcd_hold(hba, false); + mutex_lock(&hba->dev_cmd.lock); ufshcd_init_query(hba, &request, &response, opcode, idn, index, selector); @@ -3178,7 +3249,6 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba, out_unlock: hba->dev_cmd.query.descriptor = NULL; mutex_unlock(&hba->dev_cmd.lock); -out: ufshcd_release(hba); return err; } @@ -3323,9 +3393,11 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, if (is_kmalloc) { /* Make sure we don't copy more data than available */ - if (param_offset + param_size > buff_len) - param_size = buff_len - param_offset; - memcpy(param_read_buf, &desc_buf[param_offset], param_size); + if (param_offset >= buff_len) + ret = -EINVAL; + else + memcpy(param_read_buf, &desc_buf[param_offset], + min_t(u32, param_size, buff_len - param_offset)); } out: if (is_kmalloc) @@ -4403,7 +4475,7 @@ EXPORT_SYMBOL_GPL(ufshcd_make_hba_operational); * ufshcd_hba_stop - Send controller to reset state * @hba: per adapter instance */ -static inline void ufshcd_hba_stop(struct ufs_hba *hba) +void ufshcd_hba_stop(struct ufs_hba *hba) { unsigned long flags; int err; @@ -4422,6 +4494,7 @@ static inline void ufshcd_hba_stop(struct ufs_hba *hba) if (err) dev_err(hba->dev, "%s: Controller disable failed\n", __func__); } +EXPORT_SYMBOL_GPL(ufshcd_hba_stop); /** * ufshcd_hba_execute_hce - initialize the controller @@ -4836,6 +4909,26 @@ static int ufshcd_change_queue_depth(struct scsi_device *sdev, int depth) return scsi_change_queue_depth(sdev, depth); } +static void ufshcd_hpb_destroy(struct ufs_hba *hba, struct scsi_device *sdev) +{ + /* skip well-known LU */ + if ((sdev->lun >= UFS_UPIU_MAX_UNIT_NUM_ID) || + !(hba->dev_info.hpb_enabled) || !ufshpb_is_allowed(hba)) + return; + + ufshpb_destroy_lu(hba, sdev); +} + +static void ufshcd_hpb_configure(struct ufs_hba *hba, struct scsi_device *sdev) +{ + /* skip well-known LU */ + if ((sdev->lun >= UFS_UPIU_MAX_UNIT_NUM_ID) || + !(hba->dev_info.hpb_enabled) || !ufshpb_is_allowed(hba)) + return; + + ufshpb_init_hpb_lu(hba, sdev); +} + /** * ufshcd_slave_configure - adjust SCSI device configurations * @sdev: pointer to SCSI device @@ -4845,6 +4938,8 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) struct ufs_hba *hba = shost_priv(sdev->host); struct request_queue *q = sdev->request_queue; + ufshcd_hpb_configure(hba, sdev); + blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); if (hba->quirks & UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE) blk_queue_update_dma_alignment(q, PAGE_SIZE - 1); @@ -4868,6 +4963,9 @@ static void ufshcd_slave_destroy(struct scsi_device *sdev) struct ufs_hba *hba; hba = shost_priv(sdev->host); + + ufshcd_hpb_destroy(hba, sdev); + /* Drop the reference as it won't be needed anymore */ if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) { unsigned long flags; @@ -4978,6 +5076,9 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) */ pm_runtime_get_noresume(hba->dev); } + + if (scsi_status == SAM_STAT_GOOD) + ufshpb_rsp_upiu(hba, lrbp); break; case UPIU_TRANSACTION_REJECT_UPIU: /* TODO: handle Reject UPIU Response */ @@ -5024,6 +5125,24 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) return result; } +static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, + u32 intr_mask) +{ + if (!ufshcd_is_auto_hibern8_supported(hba) || + !ufshcd_is_auto_hibern8_enabled(hba)) + return false; + + if (!(intr_mask & UFSHCD_UIC_HIBERN8_MASK)) + return false; + + if (hba->active_uic_cmd && + (hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_ENTER || + hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_EXIT)) + return false; + + return true; +} + /** * ufshcd_uic_cmd_compl - handle completion of uic command * @hba: per adapter instance @@ -5037,6 +5156,10 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) { irqreturn_t retval = IRQ_NONE; + spin_lock(hba->host->host_lock); + if (ufshcd_is_auto_hibern8_error(hba, intr_status)) + hba->errors |= (UFSHCD_UIC_HIBERN8_MASK & intr_status); + if ((intr_status & UIC_COMMAND_COMPL) && hba->active_uic_cmd) { hba->active_uic_cmd->argument2 |= ufshcd_get_uic_cmd_result(hba); @@ -5057,6 +5180,7 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) if (retval == IRQ_HANDLED) ufshcd_add_uic_command_trace(hba, hba->active_uic_cmd, "complete"); + spin_unlock(hba->host->host_lock); return retval; } @@ -5075,11 +5199,14 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, bool update_scaling = false; for_each_set_bit(index, &completed_reqs, hba->nutrs) { + if (!test_and_clear_bit(index, &hba->outstanding_reqs)) + continue; lrbp = &hba->lrb[index]; - lrbp->in_use = false; lrbp->compl_time_stamp = ktime_get(); cmd = lrbp->cmd; if (cmd) { + if (unlikely(ufshcd_should_inform_monitor(hba, lrbp))) + ufshcd_update_monitor(hba, lrbp); trace_android_vh_ufs_compl_command(hba, lrbp); ufshcd_add_command_trace(hba, index, "complete"); result = ufshcd_transfer_rsp_status(hba, lrbp); @@ -5090,7 +5217,7 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, lrbp->cmd = NULL; /* Do not touch lrbp after scsi done */ cmd->scsi_done(cmd); - __ufshcd_release(hba); + ufshcd_release(hba); update_scaling = true; } else if (lrbp->command_type == UTP_CMD_TYPE_DEV_MANAGE || lrbp->command_type == UTP_CMD_TYPE_UFS_STORAGE) { @@ -5102,28 +5229,23 @@ static void __ufshcd_transfer_req_compl(struct ufs_hba *hba, update_scaling = true; } } - if (ufshcd_is_clkscaling_supported(hba) && update_scaling) - hba->clk_scaling.active_reqs--; + if (update_scaling) + ufshcd_clk_scaling_update_busy(hba); } - - /* clear corresponding bits of completed commands */ - hba->outstanding_reqs ^= completed_reqs; - - ufshcd_clk_scaling_update_busy(hba); } /** - * ufshcd_transfer_req_compl - handle SCSI and query command completion + * ufshcd_trc_handler - handle transfer requests completion * @hba: per adapter instance + * @use_utrlcnr: get completed requests from UTRLCNR * * Returns * IRQ_HANDLED - If interrupt is valid * IRQ_NONE - If invalid interrupt */ -static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) +static irqreturn_t ufshcd_trc_handler(struct ufs_hba *hba, bool use_utrlcnr) { - unsigned long completed_reqs; - u32 tr_doorbell; + unsigned long completed_reqs = 0; /* Resetting interrupt aggregation counters first and reading the * DOOR_BELL afterward allows us to handle all the completed requests. @@ -5136,8 +5258,24 @@ static irqreturn_t ufshcd_transfer_req_compl(struct ufs_hba *hba) !(hba->quirks & UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR)) ufshcd_reset_intr_aggr(hba); - tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); - completed_reqs = tr_doorbell ^ hba->outstanding_reqs; + if (use_utrlcnr) { + u32 utrlcnr; + + utrlcnr = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_LIST_COMPL); + if (utrlcnr) { + ufshcd_writel(hba, utrlcnr, + REG_UTP_TRANSFER_REQ_LIST_COMPL); + completed_reqs = utrlcnr; + } + } else { + unsigned long flags; + u32 tr_doorbell; + + spin_lock_irqsave(hba->host->host_lock, flags); + tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); + completed_reqs = tr_doorbell ^ hba->outstanding_reqs; + spin_unlock_irqrestore(hba->host->host_lock, flags); + } if (completed_reqs) { __ufshcd_transfer_req_compl(hba, completed_reqs); @@ -5646,7 +5784,7 @@ static void ufshcd_exception_event_handler(struct work_struct *work) /* Complete requests that have door-bell cleared */ static void ufshcd_complete_requests(struct ufs_hba *hba) { - ufshcd_transfer_req_compl(hba); + ufshcd_trc_handler(hba, false); ufshcd_tmc_handler(hba); } @@ -5895,13 +6033,11 @@ static void ufshcd_err_handler(struct work_struct *work) ufshcd_set_eh_in_progress(hba); spin_unlock_irqrestore(hba->host->host_lock, flags); ufshcd_err_handling_prepare(hba); + /* Complete requests that have door-bell cleared by h/w */ + ufshcd_complete_requests(hba); spin_lock_irqsave(hba->host->host_lock, flags); if (hba->ufshcd_state != UFSHCD_STATE_ERROR) hba->ufshcd_state = UFSHCD_STATE_RESET; - - /* Complete requests that have door-bell cleared by h/w */ - ufshcd_complete_requests(hba); - /* * A full reset and restore might have happened after preparation * is finished, double check whether we should stop. @@ -5984,12 +6120,11 @@ static void ufshcd_err_handler(struct work_struct *work) } lock_skip_pending_xfer_clear: - spin_lock_irqsave(hba->host->host_lock, flags); - /* Complete the requests that are cleared by s/w */ ufshcd_complete_requests(hba); - hba->silence_err_logs = false; + spin_lock_irqsave(hba->host->host_lock, flags); + hba->silence_err_logs = false; if (err_xfer || err_tm) { needs_reset = true; goto do_reset; @@ -6022,19 +6157,6 @@ static void ufshcd_err_handler(struct work_struct *work) do_reset: /* Fatal errors need reset */ if (needs_reset) { - unsigned long max_doorbells = (1UL << hba->nutrs) - 1; - - /* - * ufshcd_reset_and_restore() does the link reinitialization - * which will need atleast one empty doorbell slot to send the - * device management commands (NOP and query commands). - * If there is no slot empty at this moment then free up last - * slot forcefully. - */ - if (hba->outstanding_reqs == max_doorbells) - __ufshcd_transfer_req_compl(hba, - (1UL << (hba->nutrs - 1))); - hba->force_reset = false; spin_unlock_irqrestore(hba->host->host_lock, flags); err = ufshcd_reset_and_restore(hba); @@ -6152,37 +6274,23 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba) return retval; } -static bool ufshcd_is_auto_hibern8_error(struct ufs_hba *hba, - u32 intr_mask) -{ - if (!ufshcd_is_auto_hibern8_supported(hba) || - !ufshcd_is_auto_hibern8_enabled(hba)) - return false; - - if (!(intr_mask & UFSHCD_UIC_HIBERN8_MASK)) - return false; - - if (hba->active_uic_cmd && - (hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_ENTER || - hba->active_uic_cmd->command == UIC_CMD_DME_HIBER_EXIT)) - return false; - - return true; -} - /** * ufshcd_check_errors - Check for errors that need s/w attention * @hba: per-adapter instance + * @intr_status: interrupt status generated by the controller * * Returns * IRQ_HANDLED - If interrupt is valid * IRQ_NONE - If invalid interrupt */ -static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) +static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) { bool queue_eh_work = false; irqreturn_t retval = IRQ_NONE; + spin_lock(hba->host->host_lock); + hba->errors |= UFSHCD_ERROR_MASK & intr_status; + if (hba->errors & INT_FATAL_ERRORS) { ufshcd_update_evt_hist(hba, UFS_EVT_FATAL_ERR, hba->errors); @@ -6239,6 +6347,9 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba) * itself without s/w intervention or errors that will be * handled by the SCSI core layer. */ + hba->errors = 0; + hba->uic_error = 0; + spin_unlock(hba->host->host_lock); return retval; } @@ -6273,13 +6384,17 @@ static bool ufshcd_compl_tm(struct request *req, void *priv, bool reserved) */ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) { + unsigned long flags; struct request_queue *q = hba->tmf_queue; struct ctm_info ci = { .hba = hba, - .pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL), }; + spin_lock_irqsave(hba->host->host_lock, flags); + ci.pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); blk_mq_tagset_busy_iter(q->tag_set, ufshcd_compl_tm, &ci); + spin_unlock_irqrestore(hba->host->host_lock, flags); + return ci.ncpl ? IRQ_HANDLED : IRQ_NONE; } @@ -6296,22 +6411,17 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status) { irqreturn_t retval = IRQ_NONE; - hba->errors = UFSHCD_ERROR_MASK & intr_status; - - if (ufshcd_is_auto_hibern8_error(hba, intr_status)) - hba->errors |= (UFSHCD_UIC_HIBERN8_MASK & intr_status); - - if (hba->errors) - retval |= ufshcd_check_errors(hba); - if (intr_status & UFSHCD_UIC_MASK) retval |= ufshcd_uic_cmd_compl(hba, intr_status); + if (intr_status & UFSHCD_ERROR_MASK || hba->errors) + retval |= ufshcd_check_errors(hba, intr_status); + if (intr_status & UTP_TASK_REQ_COMPL) retval |= ufshcd_tmc_handler(hba); if (intr_status & UTP_TRANSFER_REQ_COMPL) - retval |= ufshcd_transfer_req_compl(hba); + retval |= ufshcd_trc_handler(hba, ufshcd_has_utrlcnr(hba)); return retval; } @@ -6332,7 +6442,6 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) struct ufs_hba *hba = __hba; int retries = hba->nutrs; - spin_lock(hba->host->host_lock); intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS); hba->ufs_stats.last_intr_status = intr_status; hba->ufs_stats.last_intr_ts = ktime_get(); @@ -6364,7 +6473,6 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba) ufshcd_dump_regs(hba, 0, UFSHCI_REG_SPACE_SIZE, "host_regs: "); } - spin_unlock(hba->host->host_lock); return retval; } @@ -6541,7 +6649,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, int err = 0; int tag; struct completion wait; - unsigned long flags; u8 upiu_flags; down_read(&hba->clk_scaling_lock); @@ -6556,11 +6663,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, init_completion(&wait); lrbp = &hba->lrb[tag]; - if (unlikely(lrbp->in_use)) { - err = -EBUSY; - goto out; - } - WARN_ON(lrbp->cmd); lrbp->cmd = NULL; lrbp->sense_bufflen = 0; @@ -6571,15 +6673,10 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, ufshcd_prepare_lrbp_crypto(NULL, lrbp); hba->dev_cmd.type = cmd_type; - switch (hba->ufs_version) { - case UFSHCI_VERSION_10: - case UFSHCI_VERSION_11: + if (hba->ufs_version <= ufshci_version(1, 1)) lrbp->command_type = UTP_CMD_TYPE_DEV_MANAGE; - break; - default: + else lrbp->command_type = UTP_CMD_TYPE_UFS_STORAGE; - break; - } /* update the task tag in the request upiu */ req_upiu->header.dword_0 |= cpu_to_be32(tag); @@ -6603,10 +6700,8 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, /* Make sure descriptors are ready before ringing the doorbell */ wmb(); - spin_lock_irqsave(hba->host->host_lock, flags); - ufshcd_send_command(hba, tag); - spin_unlock_irqrestore(hba->host->host_lock, flags); + ufshcd_send_command(hba, tag); /* * ignore the returning value here - ufshcd_check_query_response is * bound to fail since dev_cmd.query and dev_cmd.type were left empty. @@ -6633,7 +6728,6 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba, } } -out: blk_put_request(req); out_unlock: up_read(&hba->clk_scaling_lock); @@ -6725,7 +6819,6 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) u32 pos; int err; u8 resp = 0xF, lun; - unsigned long flags; host = cmd->device->host; hba = shost_priv(host); @@ -6744,11 +6837,9 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd) err = ufshcd_clear_cmd(hba, pos); if (err) break; + __ufshcd_transfer_req_compl(hba, pos); } } - spin_lock_irqsave(host->host_lock, flags); - ufshcd_transfer_req_compl(hba); - spin_unlock_irqrestore(host->host_lock, flags); out: hba->req_abort_count = 0; @@ -6775,7 +6866,8 @@ static void ufshcd_set_req_abort_skip(struct ufs_hba *hba, unsigned long bitmap) /** * ufshcd_try_to_abort_task - abort a specific task - * @cmd: SCSI command pointer + * @hba: Pointer to adapter instance + * @tag: Task tag/index to be aborted * * Abort the pending command in device by sending UFS_ABORT_TASK task management * command, and in host controller by clearing the door-bell register. There can @@ -6865,7 +6957,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) struct ufs_hba *hba; unsigned long flags; unsigned int tag; - int err = 0; + int err = FAILED, res; struct ufshcd_lrb *lrbp; u32 reg; @@ -6882,12 +6974,12 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) ufshcd_hold(hba, false); reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); - /* If command is already aborted/completed, return SUCCESS */ + /* If command is already aborted/completed, return FAILED. */ if (!(test_bit(tag, &hba->outstanding_reqs))) { dev_err(hba->dev, "%s: cmd at tag %d already completed, outstanding=0x%lx, doorbell=0x%x\n", __func__, tag, hba->outstanding_reqs, reg); - goto out; + goto release; } /* Print Transfer Request of aborted task */ @@ -6916,7 +7008,8 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) dev_err(hba->dev, "%s: cmd was completed, but without a notifying intr, tag = %d", __func__, tag); - goto cleanup; + __ufshcd_transfer_req_compl(hba, 1UL << tag); + goto release; } /* @@ -6924,47 +7017,37 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) * will fail, due to spec violation, scsi err handling next step * will be to send LU reset which, again, is a spec violation. * To avoid these unnecessary/illegal steps, first we clean up - * the lrb taken by this cmd and mark the lrb as in_use, then - * queue the eh_work and bail. + * the lrb taken by this cmd and re-set it in outstanding_reqs, + * then queue the eh_work and bail. */ if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) { ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun); - spin_lock_irqsave(host->host_lock, flags); - if (lrbp->cmd) { - __ufshcd_transfer_req_compl(hba, (1UL << tag)); - __set_bit(tag, &hba->outstanding_reqs); - lrbp->in_use = true; - hba->force_reset = true; - ufshcd_schedule_eh_work(hba); - } + spin_lock_irqsave(host->host_lock, flags); + hba->force_reset = true; + ufshcd_schedule_eh_work(hba); spin_unlock_irqrestore(host->host_lock, flags); - goto out; + goto release; } /* Skip task abort in case previous aborts failed and report failure */ - if (lrbp->req_abort_skip) - err = -EIO; - else - err = ufshcd_try_to_abort_task(hba, tag); - - if (!err) { -cleanup: - spin_lock_irqsave(host->host_lock, flags); - __ufshcd_transfer_req_compl(hba, (1UL << tag)); - spin_unlock_irqrestore(host->host_lock, flags); -out: - err = SUCCESS; - } else { - dev_err(hba->dev, "%s: failed with err %d\n", __func__, err); + if (lrbp->req_abort_skip) { + dev_err(hba->dev, "%s: skipping abort\n", __func__); ufshcd_set_req_abort_skip(hba, hba->outstanding_reqs); - err = FAILED; + goto release; } - /* - * This ufshcd_release() corresponds to the original scsi cmd that got - * aborted here (as we won't get any IRQ for it). - */ + res = ufshcd_try_to_abort_task(hba, tag); + if (res) { + dev_err(hba->dev, "%s: failed with err %d\n", __func__, res); + ufshcd_set_req_abort_skip(hba, hba->outstanding_reqs); + goto release; + } + + err = SUCCESS; + +release: + /* Matches the ufshcd_hold() call at the start of this function. */ ufshcd_release(hba); return err; } @@ -6982,19 +7065,16 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) static int ufshcd_host_reset_and_restore(struct ufs_hba *hba) { int err; - unsigned long flags; + ufshpb_reset_host(hba); /* * Stop the host controller and complete the requests * cleared by h/w */ ufshcd_hba_stop(hba); - - spin_lock_irqsave(hba->host->host_lock, flags); hba->silence_err_logs = true; ufshcd_complete_requests(hba); hba->silence_err_logs = false; - spin_unlock_irqrestore(hba->host->host_lock, flags); /* scale up clocks to max frequency before full reinitialization */ ufshcd_set_clk_freq(hba, true); @@ -7380,6 +7460,7 @@ static int ufs_get_device_desc(struct ufs_hba *hba) { int err; u8 model_index; + u8 b_ufs_feature_sup; u8 *desc_buf; struct ufs_dev_info *dev_info = &hba->dev_info; @@ -7407,9 +7488,26 @@ static int ufs_get_device_desc(struct ufs_hba *hba) /* getting Specification Version in big endian format */ dev_info->wspecversion = desc_buf[DEVICE_DESC_PARAM_SPEC_VER] << 8 | desc_buf[DEVICE_DESC_PARAM_SPEC_VER + 1]; + b_ufs_feature_sup = desc_buf[DEVICE_DESC_PARAM_UFS_FEAT]; model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; + if (dev_info->wspecversion >= UFS_DEV_HPB_SUPPORT_VERSION && + (b_ufs_feature_sup & UFS_DEV_HPB_SUPPORT)) { + bool hpb_en = false; + + ufshpb_get_dev_info(hba, desc_buf); + + if (!ufshpb_is_legacy(hba)) + err = ufshcd_query_flag_retry(hba, + UPIU_QUERY_OPCODE_READ_FLAG, + QUERY_FLAG_IDN_HPB_EN, 0, + &hpb_en); + + if (ufshpb_is_legacy(hba) || (!err && hpb_en)) + dev_info->hpb_enabled = true; + } + err = ufshcd_read_string_desc(hba, model_index, &dev_info->model, SD_ASCII_STD); if (err < 0) { @@ -7638,6 +7736,10 @@ static int ufshcd_device_geo_params_init(struct ufs_hba *hba) else if (desc_buf[GEOMETRY_DESC_PARAM_MAX_NUM_LUN] == 0) hba->dev_info.max_lu_supported = 8; + if (hba->desc_size[QUERY_DESC_IDN_GEOMETRY] >= + GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS) + ufshpb_get_geo_info(hba, desc_buf); + out: kfree(desc_buf); return err; @@ -7780,6 +7882,7 @@ static int ufshcd_add_lus(struct ufs_hba *hba) } ufs_bsg_probe(hba); + ufshpb_init(hba); scsi_scan_host(hba->host); pm_runtime_put_sync(hba->dev); @@ -7863,6 +7966,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) if (ret) goto out; + if (hba->quirks & UFSHCD_QUIRK_SKIP_INTERFACE_CONFIGURATION) + goto out; + /* Debug counters initialization */ ufshcd_clear_dbg_ufs_stats(hba); @@ -7925,6 +8031,7 @@ static int ufshcd_probe_hba(struct ufs_hba *hba, bool async) /* Enable Auto-Hibernate if configured */ ufshcd_auto_hibern8_enable(hba); + ufshpb_reset(hba); out: spin_lock_irqsave(hba->host->host_lock, flags); if (ret) @@ -7972,6 +8079,10 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) static const struct attribute_group *ufshcd_driver_groups[] = { &ufs_sysfs_unit_descriptor_group, &ufs_sysfs_lun_attributes_group, +#ifdef CONFIG_SCSI_UFS_HPB + &ufs_sysfs_hpb_stat_group, + &ufs_sysfs_hpb_param_group, +#endif NULL, }; @@ -8691,6 +8802,8 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) req_link_state = UIC_LINK_OFF_STATE; } + ufshpb_suspend(hba); + /* * If we can't transition into any of the low power modes * just gate the clocks. @@ -8809,6 +8922,7 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) hba->dev_info.b_rpm_dev_flush_capable = false; ufshcd_clear_ua_wluns(hba); ufshcd_release(hba); + ufshpb_resume(hba); out: if (hba->dev_info.b_rpm_dev_flush_capable) { schedule_delayed_work(&hba->rpm_dev_flush_recheck_work, @@ -8908,6 +9022,8 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) /* Enable Auto-Hibernate if configured */ ufshcd_auto_hibern8_enable(hba); + ufshpb_resume(hba); + if (hba->dev_info.b_rpm_dev_flush_capable) { hba->dev_info.b_rpm_dev_flush_capable = false; cancel_delayed_work(&hba->rpm_dev_flush_recheck_work); @@ -9138,6 +9254,7 @@ EXPORT_SYMBOL(ufshcd_shutdown); void ufshcd_remove(struct ufs_hba *hba) { ufs_bsg_remove(hba); + ufshpb_remove(hba); ufs_sysfs_remove_nodes(hba->dev); blk_cleanup_queue(hba->tmf_queue); blk_mq_free_tag_set(&hba->tmf_tag_set); @@ -9196,7 +9313,7 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle) } host = scsi_host_alloc(&ufshcd_driver_template, - sizeof(struct ufs_hba)); + sizeof(struct ufs_hba_with_hpb)); if (!host) { dev_err(dev, "scsi_host_alloc failed\n"); err = -ENOMEM; @@ -9265,10 +9382,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Get UFS version supported by the controller */ hba->ufs_version = ufshcd_get_ufs_version(hba); - if ((hba->ufs_version != UFSHCI_VERSION_10) && - (hba->ufs_version != UFSHCI_VERSION_11) && - (hba->ufs_version != UFSHCI_VERSION_20) && - (hba->ufs_version != UFSHCI_VERSION_21)) + if (hba->ufs_version < ufshci_version(1, 0)) dev_err(hba->dev, "invalid UFS version 0x%x\n", hba->ufs_version); @@ -9427,6 +9541,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) async_schedule(ufshcd_async_scan, hba); ufs_sysfs_add_nodes(hba); + device_enable_async_suspend(dev); return 0; free_tmf_queue: diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index c1ab533fcc74..c75c5cd7b973 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h @@ -43,6 +43,7 @@ #include #include #include +#include #include "ufs.h" #include "ufs_quirks.h" @@ -188,7 +189,6 @@ struct ufs_pm_lvl_states { * @crypto_key_slot: the key slot to use for inline crypto (-1 if none) * @data_unit_num: the data unit number for the first block for inline crypto * @req_abort_skip: skip request abort task flag - * @in_use: indicates that this lrb is still in use */ struct ufshcd_lrb { struct utp_transfer_req_desc *utr_descriptor_ptr; @@ -218,7 +218,8 @@ struct ufshcd_lrb { #endif bool req_abort_skip; - bool in_use; + + ANDROID_KABI_RESERVE(1); }; /** @@ -355,6 +356,11 @@ struct ufs_hba_variant_ops { const union ufs_crypto_cfg_entry *cfg, int slot); void (*event_notify)(struct ufs_hba *hba, enum ufs_event_type evt, void *data); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; /* clock gating state */ @@ -394,6 +400,8 @@ struct ufs_clk_gating { bool is_initialized; int active_reqs; struct workqueue_struct *clk_gating_workq; + + ANDROID_KABI_RESERVE(1); }; struct ufs_saved_pwr_info { @@ -440,6 +448,8 @@ struct ufs_clk_scaling { bool is_initialized; bool is_busy_started; bool is_suspended; + + ANDROID_KABI_RESERVE(1); }; #define UFS_EVENT_HIST_LENGTH 8 @@ -567,6 +577,18 @@ enum ufshcd_quirks { */ UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 14, + /* + * This quirk needs to be enabled if the host controller does not + * support UIC command + */ + UFSHCD_QUIRK_BROKEN_UIC_CMD = 1 << 15, + + /* + * This quirk needs to be enabled if the host controller cannot + * support interface configuration. + */ + UFSHCD_QUIRK_SKIP_INTERFACE_CONFIGURATION = 1 << 16, + /* * This quirk needs to be enabled if the host controller supports inline * encryption, but it needs to initialize the crypto capabilities in a @@ -655,6 +677,50 @@ struct ufs_hba_variant_params { u32 wb_flush_threshold; }; +#ifdef CONFIG_SCSI_UFS_HPB +/** + * struct ufshpb_dev_info - UFSHPB device related info + * @num_lu: the number of user logical unit to check whether all lu finished + * initialization + * @rgn_size: device reported HPB region size + * @srgn_size: device reported HPB sub-region size + * @slave_conf_cnt: counter to check all lu finished initialization + * @hpb_disabled: flag to check if HPB is disabled + * @max_hpb_single_cmd: device reported bMAX_DATA_SIZE_FOR_SINGLE_CMD value + * @is_legacy: flag to check HPB 1.0 + * @control_mode: either host or device + */ +struct ufshpb_dev_info { + int num_lu; + int rgn_size; + int srgn_size; + atomic_t slave_conf_cnt; + bool hpb_disabled; + u8 max_hpb_single_cmd; + bool is_legacy; + u8 control_mode; +}; +#endif + +struct ufs_hba_monitor { + unsigned long chunk_size; + + unsigned long nr_sec_rw[2]; + ktime_t total_busy[2]; + + unsigned long nr_req[2]; + /* latencies*/ + ktime_t lat_sum[2]; + ktime_t lat_max[2]; + ktime_t lat_min[2]; + + u32 nr_queued[2]; + ktime_t busy_start_ts[2]; + + ktime_t enabled_ts; + bool enabled; +}; + /** * struct ufs_hba - per adapter private structure * @mmio_base: UFSHCI base register address @@ -846,6 +912,13 @@ struct ufs_hba { bool wb_enabled; struct delayed_work rpm_dev_flush_recheck_work; +#if 0 + /* This has been moved into struct ufs_hba_with_hpb. */ + struct ufshpb_dev_info ufshpb_dev; +#endif + + struct ufs_hba_monitor monitor; + #ifdef CONFIG_SCSI_UFS_CRYPTO union ufs_crypto_capabilities crypto_capabilities; union ufs_crypto_cap_entry *crypto_cap_array; @@ -855,6 +928,22 @@ struct ufs_hba { #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_root; #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); +}; + +/* + * Compared to the upstream equivalent, @hpb_dev has been moved from struct + * ufs_hba into struct ufs_hba_with_hpb to satisfy the Android ABI checks. + */ +struct ufs_hba_with_hpb { + struct ufs_hba hba; +#ifdef CONFIG_SCSI_UFS_HPB + struct ufshpb_dev_info hpb_dev; +#endif }; /* Returns true if clocks can be gated. Otherwise false */ @@ -956,6 +1045,7 @@ int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask, unsigned long timeout_ms); void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba, struct clk *refclk); void ufshcd_update_evt_hist(struct ufs_hba *hba, u32 id, u32 val); +void ufshcd_hba_stop(struct ufs_hba *hba); static inline void check_upiu_size(void) { @@ -1146,6 +1236,11 @@ static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba) return ufshcd_readl(hba, REG_UFS_VERSION); } +static inline bool ufshcd_has_utrlcnr(struct ufs_hba *hba) +{ + return (hba->ufs_version >= ufshci_version(3, 0)); +} + static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba, bool up, enum ufs_notify_change_status status) { @@ -1210,8 +1305,13 @@ static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba, static inline void ufshcd_vops_setup_xfer_req(struct ufs_hba *hba, int tag, bool is_scsi_cmd) { - if (hba->vops && hba->vops->setup_xfer_req) - return hba->vops->setup_xfer_req(hba, tag, is_scsi_cmd); + if (hba->vops && hba->vops->setup_xfer_req) { + unsigned long flags; + + spin_lock_irqsave(hba->host->host_lock, flags); + hba->vops->setup_xfer_req(hba, tag, is_scsi_cmd); + spin_unlock_irqrestore(hba->host->host_lock, flags); + } } static inline void ufshcd_vops_setup_task_mgmt(struct ufs_hba *hba, diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index f41f74bef204..757727dbab81 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h @@ -39,6 +39,7 @@ enum { REG_UTP_TRANSFER_REQ_DOOR_BELL = 0x58, REG_UTP_TRANSFER_REQ_LIST_CLEAR = 0x5C, REG_UTP_TRANSFER_REQ_LIST_RUN_STOP = 0x60, + REG_UTP_TRANSFER_REQ_LIST_COMPL = 0x64, REG_UTP_TASK_REQ_LIST_BASE_L = 0x70, REG_UTP_TASK_REQ_LIST_BASE_H = 0x74, REG_UTP_TASK_REQ_DOOR_BELL = 0x78, @@ -74,13 +75,17 @@ enum { #define MINOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 0) #define MAJOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 16) -/* Controller UFSHCI version */ -enum { - UFSHCI_VERSION_10 = 0x00010000, /* 1.0 */ - UFSHCI_VERSION_11 = 0x00010100, /* 1.1 */ - UFSHCI_VERSION_20 = 0x00000200, /* 2.0 */ - UFSHCI_VERSION_21 = 0x00000210, /* 2.1 */ -}; +/* + * Controller UFSHCI version + * - 2.x and newer use the following scheme: + * major << 8 + minor << 4 + * - 1.x has been converted to match this in + * ufshcd_get_ufs_version() + */ +static inline u32 ufshci_version(u32 major, u32 minor) +{ + return (major << 8) + (minor << 4); +} /* * HCDDID - Host Controller Identification Descriptor diff --git a/drivers/scsi/ufs/ufshpb.c b/drivers/scsi/ufs/ufshpb.c new file mode 100644 index 000000000000..9755317c3301 --- /dev/null +++ b/drivers/scsi/ufs/ufshpb.c @@ -0,0 +1,2914 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Universal Flash Storage Host Performance Booster + * + * Copyright (C) 2017-2021 Samsung Electronics Co., Ltd. + * + * Authors: + * Yongmyung Lee + * Jinyoung Choi + */ + +#include +#include + +#include "ufshcd.h" +#include "ufshpb.h" +#include "../sd.h" + +#define ACTIVATION_THRESHOLD 8 /* 8 IOs */ +#define READ_TO_MS 1000 +#define READ_TO_EXPIRIES 100 +#define POLLING_INTERVAL_MS 200 +#define THROTTLE_MAP_REQ_DEFAULT 1 + +/* memory management */ +static struct kmem_cache *ufshpb_mctx_cache; +static mempool_t *ufshpb_mctx_pool; +static mempool_t *ufshpb_page_pool; +/* A cache size of 2MB can cache ppn in the 1GB range. */ +static unsigned int ufshpb_host_map_kbytes = 2048; +static int tot_active_srgn_pages; + +static struct workqueue_struct *ufshpb_wq; + +static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx, + int srgn_idx); + +static inline struct ufshpb_dev_info *ufs_hba_to_hpb(struct ufs_hba *hba) +{ + return &container_of(hba, struct ufs_hba_with_hpb, hba)->hpb_dev; +} + +bool ufshpb_is_allowed(struct ufs_hba *hba) +{ + return !(ufs_hba_to_hpb(hba)->hpb_disabled); +} + +/* HPB version 1.0 is called as legacy version. */ +bool ufshpb_is_legacy(struct ufs_hba *hba) +{ + return ufs_hba_to_hpb(hba)->is_legacy; +} + +static struct ufshpb_lu *ufshpb_get_hpb_data(struct scsi_device *sdev) +{ + return sdev->hostdata; +} + +static int ufshpb_get_state(struct ufshpb_lu *hpb) +{ + return atomic_read(&hpb->hpb_state); +} + +static void ufshpb_set_state(struct ufshpb_lu *hpb, int state) +{ + atomic_set(&hpb->hpb_state, state); +} + +static int ufshpb_is_valid_srgn(struct ufshpb_region *rgn, + struct ufshpb_subregion *srgn) +{ + return rgn->rgn_state != HPB_RGN_INACTIVE && + srgn->srgn_state == HPB_SRGN_VALID; +} + +static bool ufshpb_is_read_cmd(struct scsi_cmnd *cmd) +{ + return req_op(cmd->request) == REQ_OP_READ; +} + +static bool ufshpb_is_write_or_discard(struct scsi_cmnd *cmd) +{ + return op_is_write(req_op(cmd->request)) || + op_is_discard(req_op(cmd->request)); +} + +static bool ufshpb_is_supported_chunk(struct ufshpb_lu *hpb, int transfer_len) +{ + return transfer_len <= hpb->pre_req_max_tr_len; +} + +/* + * In this driver, WRITE_BUFFER CMD support 36KB (len=9) ~ 1MB (len=256) as + * default. It is possible to change range of transfer_len through sysfs. + */ +static inline bool ufshpb_is_required_wb(struct ufshpb_lu *hpb, int len) +{ + return len > hpb->pre_req_min_tr_len && + len <= hpb->pre_req_max_tr_len; +} + +static bool ufshpb_is_general_lun(int lun) +{ + return lun < UFS_UPIU_MAX_UNIT_NUM_ID; +} + +static bool ufshpb_is_pinned_region(struct ufshpb_lu *hpb, int rgn_idx) +{ + if (hpb->lu_pinned_end != PINNED_NOT_SET && + rgn_idx >= hpb->lu_pinned_start && + rgn_idx <= hpb->lu_pinned_end) + return true; + + return false; +} + +static void ufshpb_kick_map_work(struct ufshpb_lu *hpb) +{ + bool ret = false; + unsigned long flags; + + if (ufshpb_get_state(hpb) != HPB_PRESENT) + return; + + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + if (!list_empty(&hpb->lh_inact_rgn) || !list_empty(&hpb->lh_act_srgn)) + ret = true; + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + + if (ret) + queue_work(ufshpb_wq, &hpb->map_work); +} + +static bool ufshpb_is_hpb_rsp_valid(struct ufs_hba *hba, + struct ufshcd_lrb *lrbp, + struct utp_hpb_rsp *rsp_field) +{ + /* Check HPB_UPDATE_ALERT */ + if (!(lrbp->ucd_rsp_ptr->header.dword_2 & + UPIU_HEADER_DWORD(0, 2, 0, 0))) + return false; + + if (be16_to_cpu(rsp_field->sense_data_len) != DEV_SENSE_SEG_LEN || + rsp_field->desc_type != DEV_DES_TYPE || + rsp_field->additional_len != DEV_ADDITIONAL_LEN || + rsp_field->active_rgn_cnt > MAX_ACTIVE_NUM || + rsp_field->inactive_rgn_cnt > MAX_INACTIVE_NUM || + rsp_field->hpb_op == HPB_RSP_NONE || + (rsp_field->hpb_op == HPB_RSP_REQ_REGION_UPDATE && + !rsp_field->active_rgn_cnt && !rsp_field->inactive_rgn_cnt)) + return false; + + if (!ufshpb_is_general_lun(rsp_field->lun)) { + dev_warn(hba->dev, "ufshpb: lun(%d) not supported\n", + lrbp->lun); + return false; + } + + return true; +} + +static void ufshpb_iterate_rgn(struct ufshpb_lu *hpb, int rgn_idx, int srgn_idx, + int srgn_offset, int cnt, bool set_dirty) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn, *prev_srgn = NULL; + int set_bit_len; + int bitmap_len; + unsigned long flags; + +next_srgn: + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + if (likely(!srgn->is_last)) + bitmap_len = hpb->entries_per_srgn; + else + bitmap_len = hpb->last_srgn_entries; + + if ((srgn_offset + cnt) > bitmap_len) + set_bit_len = bitmap_len - srgn_offset; + else + set_bit_len = cnt; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + if (set_dirty && rgn->rgn_state != HPB_RGN_INACTIVE && + srgn->srgn_state == HPB_SRGN_VALID) + bitmap_set(srgn->mctx->ppn_dirty, srgn_offset, set_bit_len); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + if (hpb->is_hcm && prev_srgn != srgn) { + bool activate = false; + + spin_lock(&rgn->rgn_lock); + if (set_dirty) { + rgn->reads -= srgn->reads; + srgn->reads = 0; + set_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); + } else { + srgn->reads++; + rgn->reads++; + if (srgn->reads == hpb->params.activation_thld) + activate = true; + } + spin_unlock(&rgn->rgn_lock); + + if (activate || + test_and_clear_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags)) { + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + ufshpb_update_active_info(hpb, rgn_idx, srgn_idx); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, + "activate region %d-%d\n", rgn_idx, srgn_idx); + } + + prev_srgn = srgn; + } + + srgn_offset = 0; + if (++srgn_idx == hpb->srgns_per_rgn) { + srgn_idx = 0; + rgn_idx++; + } + + cnt -= set_bit_len; + if (cnt > 0) + goto next_srgn; +} + +static bool ufshpb_test_ppn_dirty(struct ufshpb_lu *hpb, int rgn_idx, + int srgn_idx, int srgn_offset, int cnt) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + int bitmap_len; + int bit_len; + +next_srgn: + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + if (likely(!srgn->is_last)) + bitmap_len = hpb->entries_per_srgn; + else + bitmap_len = hpb->last_srgn_entries; + + if (!ufshpb_is_valid_srgn(rgn, srgn)) + return true; + + /* + * If the region state is active, mctx must be allocated. + * In this case, check whether the region is evicted or + * mctx allcation fail. + */ + if (unlikely(!srgn->mctx)) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "no mctx in region %d subregion %d.\n", + srgn->rgn_idx, srgn->srgn_idx); + return true; + } + + if ((srgn_offset + cnt) > bitmap_len) + bit_len = bitmap_len - srgn_offset; + else + bit_len = cnt; + + if (find_next_bit(srgn->mctx->ppn_dirty, bit_len + srgn_offset, + srgn_offset) < bit_len + srgn_offset) + return true; + + srgn_offset = 0; + if (++srgn_idx == hpb->srgns_per_rgn) { + srgn_idx = 0; + rgn_idx++; + } + + cnt -= bit_len; + if (cnt > 0) + goto next_srgn; + + return false; +} + +static inline bool is_rgn_dirty(struct ufshpb_region *rgn) +{ + return test_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); +} + +static int ufshpb_fill_ppn_from_page(struct ufshpb_lu *hpb, + struct ufshpb_map_ctx *mctx, int pos, + int len, __be64 *ppn_buf) +{ + struct page *page; + int index, offset; + int copied; + + index = pos / (PAGE_SIZE / HPB_ENTRY_SIZE); + offset = pos % (PAGE_SIZE / HPB_ENTRY_SIZE); + + if ((offset + len) <= (PAGE_SIZE / HPB_ENTRY_SIZE)) + copied = len; + else + copied = (PAGE_SIZE / HPB_ENTRY_SIZE) - offset; + + page = mctx->m_page[index]; + if (unlikely(!page)) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "error. cannot find page in mctx\n"); + return -ENOMEM; + } + + memcpy(ppn_buf, page_address(page) + (offset * HPB_ENTRY_SIZE), + copied * HPB_ENTRY_SIZE); + + return copied; +} + +static void +ufshpb_get_pos_from_lpn(struct ufshpb_lu *hpb, unsigned long lpn, int *rgn_idx, + int *srgn_idx, int *offset) +{ + int rgn_offset; + + *rgn_idx = lpn >> hpb->entries_per_rgn_shift; + rgn_offset = lpn & hpb->entries_per_rgn_mask; + *srgn_idx = rgn_offset >> hpb->entries_per_srgn_shift; + *offset = rgn_offset & hpb->entries_per_srgn_mask; +} + +static void +ufshpb_set_hpb_read_to_upiu(struct ufshpb_lu *hpb, struct ufshcd_lrb *lrbp, + u32 lpn, __be64 ppn, u8 transfer_len, int read_id) +{ + unsigned char *cdb = lrbp->cmd->cmnd; + + cdb[0] = UFSHPB_READ; + + /* ppn value is stored as big-endian in the host memory */ + memcpy(&cdb[6], &ppn, sizeof(__be64)); + cdb[14] = transfer_len; + cdb[15] = read_id; + + lrbp->cmd->cmd_len = UFS_CDB_SIZE; +} + +static inline void ufshpb_set_write_buf_cmd(unsigned char *cdb, + unsigned long lpn, unsigned int len, + int read_id) +{ + cdb[0] = UFSHPB_WRITE_BUFFER; + cdb[1] = UFSHPB_WRITE_BUFFER_PREFETCH_ID; + + put_unaligned_be32(lpn, &cdb[2]); + cdb[6] = read_id; + put_unaligned_be16(len * HPB_ENTRY_SIZE, &cdb[7]); + + cdb[9] = 0x00; /* Control = 0x00 */ +} + +static struct ufshpb_req *ufshpb_get_pre_req(struct ufshpb_lu *hpb) +{ + struct ufshpb_req *pre_req; + + if (hpb->num_inflight_pre_req >= hpb->throttle_pre_req) { + dev_info(&hpb->sdev_ufs_lu->sdev_dev, + "pre_req throttle. inflight %d throttle %d", + hpb->num_inflight_pre_req, hpb->throttle_pre_req); + return NULL; + } + + pre_req = list_first_entry_or_null(&hpb->lh_pre_req_free, + struct ufshpb_req, list_req); + if (!pre_req) { + dev_info(&hpb->sdev_ufs_lu->sdev_dev, "There is no pre_req"); + return NULL; + } + + list_del_init(&pre_req->list_req); + hpb->num_inflight_pre_req++; + + return pre_req; +} + +static inline void ufshpb_put_pre_req(struct ufshpb_lu *hpb, + struct ufshpb_req *pre_req) +{ + pre_req->req = NULL; + bio_reset(pre_req->bio); + list_add_tail(&pre_req->list_req, &hpb->lh_pre_req_free); + hpb->num_inflight_pre_req--; +} + +static void ufshpb_pre_req_compl_fn(struct request *req, blk_status_t error) +{ + struct ufshpb_req *pre_req = (struct ufshpb_req *)req->end_io_data; + struct ufshpb_lu *hpb = pre_req->hpb; + unsigned long flags; + + if (error) { + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req); + struct scsi_sense_hdr sshdr; + + dev_err(&hpb->sdev_ufs_lu->sdev_dev, "block status %d", error); + scsi_command_normalize_sense(cmd, &sshdr); + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "code %x sense_key %x asc %x ascq %x", + sshdr.response_code, + sshdr.sense_key, sshdr.asc, sshdr.ascq); + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "byte4 %x byte5 %x byte6 %x additional_len %x", + sshdr.byte4, sshdr.byte5, + sshdr.byte6, sshdr.additional_length); + } + + blk_mq_free_request(req); + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + ufshpb_put_pre_req(pre_req->hpb, pre_req); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); +} + +static int ufshpb_prep_entry(struct ufshpb_req *pre_req, struct page *page) +{ + struct ufshpb_lu *hpb = pre_req->hpb; + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + __be64 *addr; + int offset = 0; + int copied; + unsigned long lpn = pre_req->wb.lpn; + int rgn_idx, srgn_idx, srgn_offset; + unsigned long flags; + + addr = page_address(page); + ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, &srgn_offset); + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + +next_offset: + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + if (!ufshpb_is_valid_srgn(rgn, srgn)) + goto mctx_error; + + if (!srgn->mctx) + goto mctx_error; + + copied = ufshpb_fill_ppn_from_page(hpb, srgn->mctx, srgn_offset, + pre_req->wb.len - offset, + &addr[offset]); + + if (copied < 0) + goto mctx_error; + + offset += copied; + srgn_offset += copied; + + if (srgn_offset == hpb->entries_per_srgn) { + srgn_offset = 0; + + if (++srgn_idx == hpb->srgns_per_rgn) { + srgn_idx = 0; + rgn_idx++; + } + } + + if (offset < pre_req->wb.len) + goto next_offset; + + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return 0; +mctx_error: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return -ENOMEM; +} + +static int ufshpb_pre_req_add_bio_page(struct ufshpb_lu *hpb, + struct request_queue *q, + struct ufshpb_req *pre_req) +{ + struct page *page = pre_req->wb.m_page; + struct bio *bio = pre_req->bio; + int entries_bytes, ret; + + if (!page) + return -ENOMEM; + + if (ufshpb_prep_entry(pre_req, page)) + return -ENOMEM; + + entries_bytes = pre_req->wb.len * sizeof(__be64); + + ret = bio_add_pc_page(q, bio, page, entries_bytes, 0); + if (ret != entries_bytes) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "bio_add_pc_page fail: %d", ret); + return -ENOMEM; + } + return 0; +} + +static inline int ufshpb_get_read_id(struct ufshpb_lu *hpb) +{ + if (++hpb->cur_read_id >= MAX_HPB_READ_ID) + hpb->cur_read_id = 1; + return hpb->cur_read_id; +} + +static int ufshpb_execute_pre_req(struct ufshpb_lu *hpb, struct scsi_cmnd *cmd, + struct ufshpb_req *pre_req, int read_id) +{ + struct scsi_device *sdev = cmd->device; + struct request_queue *q = sdev->request_queue; + struct request *req; + struct scsi_request *rq; + struct bio *bio = pre_req->bio; + + pre_req->hpb = hpb; + pre_req->wb.lpn = sectors_to_logical(cmd->device, + blk_rq_pos(cmd->request)); + pre_req->wb.len = sectors_to_logical(cmd->device, + blk_rq_sectors(cmd->request)); + if (ufshpb_pre_req_add_bio_page(hpb, q, pre_req)) + return -ENOMEM; + + req = pre_req->req; + + /* 1. request setup */ + blk_rq_append_bio(req, &bio); + req->rq_disk = NULL; + req->end_io_data = (void *)pre_req; + req->end_io = ufshpb_pre_req_compl_fn; + + /* 2. scsi_request setup */ + rq = scsi_req(req); + rq->retries = 1; + + ufshpb_set_write_buf_cmd(rq->cmd, pre_req->wb.lpn, pre_req->wb.len, + read_id); + rq->cmd_len = scsi_command_size(rq->cmd); + + if (blk_insert_cloned_request(q, req) != BLK_STS_OK) + return -EAGAIN; + + hpb->stats.pre_req_cnt++; + + return 0; +} + +static int ufshpb_issue_pre_req(struct ufshpb_lu *hpb, struct scsi_cmnd *cmd, + int *read_id) +{ + struct ufshpb_req *pre_req; + struct request *req = NULL; + unsigned long flags; + int _read_id; + int ret = 0; + + req = blk_get_request(cmd->device->request_queue, + REQ_OP_SCSI_OUT | REQ_SYNC, BLK_MQ_REQ_NOWAIT); + if (IS_ERR(req)) + return -EAGAIN; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + pre_req = ufshpb_get_pre_req(hpb); + if (!pre_req) { + ret = -EAGAIN; + goto unlock_out; + } + _read_id = ufshpb_get_read_id(hpb); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + pre_req->req = req; + + ret = ufshpb_execute_pre_req(hpb, cmd, pre_req, _read_id); + if (ret) + goto free_pre_req; + + *read_id = _read_id; + + return ret; +free_pre_req: + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + ufshpb_put_pre_req(hpb, pre_req); +unlock_out: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + blk_put_request(req); + return ret; +} + +/* + * This function will set up HPB read command using host-side L2P map data. + */ +int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + struct ufshpb_lu *hpb; + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + struct scsi_cmnd *cmd = lrbp->cmd; + u32 lpn; + __be64 ppn; + unsigned long flags; + int transfer_len, rgn_idx, srgn_idx, srgn_offset; + int read_id = 0; + int err = 0; + + hpb = ufshpb_get_hpb_data(cmd->device); + if (!hpb) + return -ENODEV; + + if (ufshpb_get_state(hpb) == HPB_INIT) + return -ENODEV; + + if (ufshpb_get_state(hpb) != HPB_PRESENT) { + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "%s: ufshpb state is not PRESENT", __func__); + return -ENODEV; + } + + if (blk_rq_is_scsi(cmd->request) || + (!ufshpb_is_write_or_discard(cmd) && + !ufshpb_is_read_cmd(cmd))) + return 0; + + transfer_len = sectors_to_logical(cmd->device, + blk_rq_sectors(cmd->request)); + if (unlikely(!transfer_len)) + return 0; + + lpn = sectors_to_logical(cmd->device, blk_rq_pos(cmd->request)); + ufshpb_get_pos_from_lpn(hpb, lpn, &rgn_idx, &srgn_idx, &srgn_offset); + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + /* If command type is WRITE or DISCARD, set bitmap as drity */ + if (ufshpb_is_write_or_discard(cmd)) { + ufshpb_iterate_rgn(hpb, rgn_idx, srgn_idx, srgn_offset, + transfer_len, true); + return 0; + } + + if (!ufshpb_is_supported_chunk(hpb, transfer_len)) + return 0; + + WARN_ON_ONCE(transfer_len > HPB_MULTI_CHUNK_HIGH); + + if (hpb->is_hcm) { + /* + * in host control mode, reads are the main source for + * activation trials. + */ + ufshpb_iterate_rgn(hpb, rgn_idx, srgn_idx, srgn_offset, + transfer_len, false); + + /* keep those counters normalized */ + if (rgn->reads > hpb->entries_per_srgn) + schedule_work(&hpb->ufshpb_normalization_work); + } + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + if (ufshpb_test_ppn_dirty(hpb, rgn_idx, srgn_idx, srgn_offset, + transfer_len)) { + hpb->stats.miss_cnt++; + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return 0; + } + + err = ufshpb_fill_ppn_from_page(hpb, srgn->mctx, srgn_offset, 1, &ppn); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + if (unlikely(err < 0)) { + /* + * In this case, the region state is active, + * but the ppn table is not allocated. + * Make sure that ppn table must be allocated on + * active state. + */ + dev_err(hba->dev, "get ppn failed. err %d\n", err); + return err; + } + + if (!ufshpb_is_legacy(hba) && + ufshpb_is_required_wb(hpb, transfer_len)) { + err = ufshpb_issue_pre_req(hpb, cmd, &read_id); + if (err) { + unsigned long timeout; + + timeout = cmd->jiffies_at_alloc + msecs_to_jiffies( + hpb->params.requeue_timeout_ms); + + if (time_before(jiffies, timeout)) + return -EAGAIN; + + hpb->stats.miss_cnt++; + return 0; + } + } + + ufshpb_set_hpb_read_to_upiu(hpb, lrbp, lpn, ppn, transfer_len, read_id); + + hpb->stats.hit_cnt++; + return 0; +} + +static struct ufshpb_req *ufshpb_get_req(struct ufshpb_lu *hpb, + int rgn_idx, enum req_opf dir, + bool atomic) +{ + struct ufshpb_req *rq; + struct request *req; + int retries = HPB_MAP_REQ_RETRIES; + + rq = kmem_cache_alloc(hpb->map_req_cache, GFP_KERNEL); + if (!rq) + return NULL; + +retry: + req = blk_get_request(hpb->sdev_ufs_lu->request_queue, dir, + BLK_MQ_REQ_NOWAIT); + + if (!atomic && (PTR_ERR(req) == -EWOULDBLOCK) && (--retries > 0)) { + usleep_range(3000, 3100); + goto retry; + } + + if (IS_ERR(req)) + goto free_rq; + + rq->hpb = hpb; + rq->req = req; + rq->rb.rgn_idx = rgn_idx; + + return rq; + +free_rq: + kmem_cache_free(hpb->map_req_cache, rq); + return NULL; +} + +static void ufshpb_put_req(struct ufshpb_lu *hpb, struct ufshpb_req *rq) +{ + blk_put_request(rq->req); + kmem_cache_free(hpb->map_req_cache, rq); +} + +static struct ufshpb_req *ufshpb_get_map_req(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + struct ufshpb_req *map_req; + struct bio *bio; + + if (hpb->is_hcm && + hpb->num_inflight_map_req >= hpb->params.inflight_map_req) { + dev_info(&hpb->sdev_ufs_lu->sdev_dev, + "map_req throttle. inflight %d throttle %d", + hpb->num_inflight_map_req, + hpb->params.inflight_map_req); + return NULL; + } + + map_req = ufshpb_get_req(hpb, srgn->rgn_idx, REQ_OP_SCSI_IN, false); + if (!map_req) + return NULL; + + bio = bio_alloc(GFP_KERNEL, hpb->pages_per_srgn); + if (!bio) { + ufshpb_put_req(hpb, map_req); + return NULL; + } + + map_req->bio = bio; + + map_req->rb.srgn_idx = srgn->srgn_idx; + map_req->rb.mctx = srgn->mctx; + hpb->num_inflight_map_req++; + + return map_req; +} + +static void ufshpb_put_map_req(struct ufshpb_lu *hpb, + struct ufshpb_req *map_req) +{ + bio_put(map_req->bio); + ufshpb_put_req(hpb, map_req); + hpb->num_inflight_map_req--; +} + +static int ufshpb_clear_dirty_bitmap(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + struct ufshpb_region *rgn; + u32 num_entries = hpb->entries_per_srgn; + + if (!srgn->mctx) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "no mctx in region %d subregion %d.\n", + srgn->rgn_idx, srgn->srgn_idx); + return -1; + } + + if (unlikely(srgn->is_last)) + num_entries = hpb->last_srgn_entries; + + bitmap_zero(srgn->mctx->ppn_dirty, num_entries); + + rgn = hpb->rgn_tbl + srgn->rgn_idx; + clear_bit(RGN_FLAG_DIRTY, &rgn->rgn_flags); + + return 0; +} + +static void ufshpb_update_active_info(struct ufshpb_lu *hpb, int rgn_idx, + int srgn_idx) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + + rgn = hpb->rgn_tbl + rgn_idx; + srgn = rgn->srgn_tbl + srgn_idx; + + list_del_init(&rgn->list_inact_rgn); + + if (list_empty(&srgn->list_act_srgn)) + list_add_tail(&srgn->list_act_srgn, &hpb->lh_act_srgn); + + hpb->stats.rb_active_cnt++; +} + +static void ufshpb_update_inactive_info(struct ufshpb_lu *hpb, int rgn_idx) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + int srgn_idx; + + rgn = hpb->rgn_tbl + rgn_idx; + + for_each_sub_region(rgn, srgn_idx, srgn) + list_del_init(&srgn->list_act_srgn); + + if (list_empty(&rgn->list_inact_rgn)) + list_add_tail(&rgn->list_inact_rgn, &hpb->lh_inact_rgn); + + hpb->stats.rb_inactive_cnt++; +} + +static void ufshpb_activate_subregion(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + struct ufshpb_region *rgn; + + /* + * If there is no mctx in subregion + * after I/O progress for HPB_READ_BUFFER, the region to which the + * subregion belongs was evicted. + * Make sure the region must not evict in I/O progress + */ + if (!srgn->mctx) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "no mctx in region %d subregion %d.\n", + srgn->rgn_idx, srgn->srgn_idx); + srgn->srgn_state = HPB_SRGN_INVALID; + return; + } + + rgn = hpb->rgn_tbl + srgn->rgn_idx; + + if (unlikely(rgn->rgn_state == HPB_RGN_INACTIVE)) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "region %d subregion %d evicted\n", + srgn->rgn_idx, srgn->srgn_idx); + srgn->srgn_state = HPB_SRGN_INVALID; + return; + } + srgn->srgn_state = HPB_SRGN_VALID; +} + +static void ufshpb_umap_req_compl_fn(struct request *req, blk_status_t error) +{ + struct ufshpb_req *umap_req = (struct ufshpb_req *)req->end_io_data; + + ufshpb_put_req(umap_req->hpb, umap_req); +} + +static void ufshpb_map_req_compl_fn(struct request *req, blk_status_t error) +{ + struct ufshpb_req *map_req = (struct ufshpb_req *) req->end_io_data; + struct ufshpb_lu *hpb = map_req->hpb; + struct ufshpb_subregion *srgn; + unsigned long flags; + + srgn = hpb->rgn_tbl[map_req->rb.rgn_idx].srgn_tbl + + map_req->rb.srgn_idx; + + ufshpb_clear_dirty_bitmap(hpb, srgn); + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + ufshpb_activate_subregion(hpb, srgn); + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + ufshpb_put_map_req(map_req->hpb, map_req); +} + +static void ufshpb_set_unmap_cmd(unsigned char *cdb, struct ufshpb_region *rgn) +{ + cdb[0] = UFSHPB_WRITE_BUFFER; + cdb[1] = rgn ? UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID : + UFSHPB_WRITE_BUFFER_INACT_ALL_ID; + if (rgn) + put_unaligned_be16(rgn->rgn_idx, &cdb[2]); + cdb[9] = 0x00; +} + +static void ufshpb_set_read_buf_cmd(unsigned char *cdb, int rgn_idx, + int srgn_idx, int srgn_mem_size) +{ + cdb[0] = UFSHPB_READ_BUFFER; + cdb[1] = UFSHPB_READ_BUFFER_ID; + + put_unaligned_be16(rgn_idx, &cdb[2]); + put_unaligned_be16(srgn_idx, &cdb[4]); + put_unaligned_be24(srgn_mem_size, &cdb[6]); + + cdb[9] = 0x00; +} + +static void ufshpb_execute_umap_req(struct ufshpb_lu *hpb, + struct ufshpb_req *umap_req, + struct ufshpb_region *rgn) +{ + struct request *req; + struct scsi_request *rq; + + req = umap_req->req; + req->timeout = 0; + req->end_io_data = (void *)umap_req; + rq = scsi_req(req); + ufshpb_set_unmap_cmd(rq->cmd, rgn); + rq->cmd_len = HPB_WRITE_BUFFER_CMD_LENGTH; + + blk_execute_rq_nowait(req->q, NULL, req, 1, ufshpb_umap_req_compl_fn); + + hpb->stats.umap_req_cnt++; +} + +static int ufshpb_execute_map_req(struct ufshpb_lu *hpb, + struct ufshpb_req *map_req, bool last) +{ + struct request_queue *q; + struct request *req; + struct scsi_request *rq; + int mem_size = hpb->srgn_mem_size; + int ret = 0; + int i; + + q = hpb->sdev_ufs_lu->request_queue; + for (i = 0; i < hpb->pages_per_srgn; i++) { + ret = bio_add_pc_page(q, map_req->bio, map_req->rb.mctx->m_page[i], + PAGE_SIZE, 0); + if (ret != PAGE_SIZE) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "bio_add_pc_page fail %d - %d\n", + map_req->rb.rgn_idx, map_req->rb.srgn_idx); + return ret; + } + } + + req = map_req->req; + + blk_rq_append_bio(req, &map_req->bio); + + req->end_io_data = map_req; + + rq = scsi_req(req); + + if (unlikely(last)) + mem_size = hpb->last_srgn_entries * HPB_ENTRY_SIZE; + + ufshpb_set_read_buf_cmd(rq->cmd, map_req->rb.rgn_idx, + map_req->rb.srgn_idx, mem_size); + rq->cmd_len = HPB_READ_BUFFER_CMD_LENGTH; + + blk_execute_rq_nowait(q, NULL, req, 1, ufshpb_map_req_compl_fn); + + hpb->stats.map_req_cnt++; + return 0; +} + +static struct ufshpb_map_ctx *ufshpb_get_map_ctx(struct ufshpb_lu *hpb, + bool last) +{ + struct ufshpb_map_ctx *mctx; + u32 num_entries = hpb->entries_per_srgn; + int i, j; + + mctx = mempool_alloc(ufshpb_mctx_pool, GFP_KERNEL); + if (!mctx) + return NULL; + + mctx->m_page = kmem_cache_alloc(hpb->m_page_cache, GFP_KERNEL); + if (!mctx->m_page) + goto release_mctx; + + if (unlikely(last)) + num_entries = hpb->last_srgn_entries; + + mctx->ppn_dirty = bitmap_zalloc(num_entries, GFP_KERNEL); + if (!mctx->ppn_dirty) + goto release_m_page; + + for (i = 0; i < hpb->pages_per_srgn; i++) { + mctx->m_page[i] = mempool_alloc(ufshpb_page_pool, GFP_KERNEL); + if (!mctx->m_page[i]) { + for (j = 0; j < i; j++) + mempool_free(mctx->m_page[j], ufshpb_page_pool); + goto release_ppn_dirty; + } + clear_page(page_address(mctx->m_page[i])); + } + + return mctx; + +release_ppn_dirty: + bitmap_free(mctx->ppn_dirty); +release_m_page: + kmem_cache_free(hpb->m_page_cache, mctx->m_page); +release_mctx: + mempool_free(mctx, ufshpb_mctx_pool); + return NULL; +} + +static void ufshpb_put_map_ctx(struct ufshpb_lu *hpb, + struct ufshpb_map_ctx *mctx) +{ + int i; + + for (i = 0; i < hpb->pages_per_srgn; i++) + mempool_free(mctx->m_page[i], ufshpb_page_pool); + + bitmap_free(mctx->ppn_dirty); + kmem_cache_free(hpb->m_page_cache, mctx->m_page); + mempool_free(mctx, ufshpb_mctx_pool); +} + +static int ufshpb_check_srgns_issue_state(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + struct ufshpb_subregion *srgn; + int srgn_idx; + + for_each_sub_region(rgn, srgn_idx, srgn) + if (srgn->srgn_state == HPB_SRGN_ISSUED) + return -EPERM; + + return 0; +} + +static void ufshpb_read_to_handler(struct work_struct *work) +{ + struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, + ufshpb_read_to_work.work); + struct victim_select_info *lru_info = &hpb->lru_info; + struct ufshpb_region *rgn, *next_rgn; + unsigned long flags; + unsigned int poll; + LIST_HEAD(expired_list); + + if (test_and_set_bit(TIMEOUT_WORK_RUNNING, &hpb->work_data_bits)) + return; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + + list_for_each_entry_safe(rgn, next_rgn, &lru_info->lh_lru_rgn, + list_lru_rgn) { + bool timedout = ktime_after(ktime_get(), rgn->read_timeout); + + if (timedout) { + rgn->read_timeout_expiries--; + if (is_rgn_dirty(rgn) || + rgn->read_timeout_expiries == 0) + list_add(&rgn->list_expired_rgn, &expired_list); + else + rgn->read_timeout = ktime_add_ms(ktime_get(), + hpb->params.read_timeout_ms); + } + } + + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + list_for_each_entry_safe(rgn, next_rgn, &expired_list, + list_expired_rgn) { + list_del_init(&rgn->list_expired_rgn); + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + ufshpb_update_inactive_info(hpb, rgn->rgn_idx); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + } + + ufshpb_kick_map_work(hpb); + + clear_bit(TIMEOUT_WORK_RUNNING, &hpb->work_data_bits); + + poll = hpb->params.timeout_polling_interval_ms; + schedule_delayed_work(&hpb->ufshpb_read_to_work, + msecs_to_jiffies(poll)); +} + +static void ufshpb_add_lru_info(struct victim_select_info *lru_info, + struct ufshpb_region *rgn) +{ + rgn->rgn_state = HPB_RGN_ACTIVE; + list_add_tail(&rgn->list_lru_rgn, &lru_info->lh_lru_rgn); + atomic_inc(&lru_info->active_cnt); + if (rgn->hpb->is_hcm) { + rgn->read_timeout = + ktime_add_ms(ktime_get(), + rgn->hpb->params.read_timeout_ms); + rgn->read_timeout_expiries = + rgn->hpb->params.read_timeout_expiries; + } +} + +static void ufshpb_hit_lru_info(struct victim_select_info *lru_info, + struct ufshpb_region *rgn) +{ + list_move_tail(&rgn->list_lru_rgn, &lru_info->lh_lru_rgn); +} + +static struct ufshpb_region *ufshpb_victim_lru_info(struct ufshpb_lu *hpb) +{ + struct victim_select_info *lru_info = &hpb->lru_info; + struct ufshpb_region *rgn, *victim_rgn = NULL; + + list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn) { + if (!rgn) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "%s: no region allocated\n", + __func__); + return NULL; + } + if (ufshpb_check_srgns_issue_state(hpb, rgn)) + continue; + + /* + * in host control mode, verify that the exiting region + * has less reads + */ + if (hpb->is_hcm && + rgn->reads > hpb->params.eviction_thld_exit) + continue; + + victim_rgn = rgn; + break; + } + + return victim_rgn; +} + +static void ufshpb_cleanup_lru_info(struct victim_select_info *lru_info, + struct ufshpb_region *rgn) +{ + list_del_init(&rgn->list_lru_rgn); + rgn->rgn_state = HPB_RGN_INACTIVE; + atomic_dec(&lru_info->active_cnt); +} + +static void ufshpb_purge_active_subregion(struct ufshpb_lu *hpb, + struct ufshpb_subregion *srgn) +{ + if (srgn->srgn_state != HPB_SRGN_UNUSED) { + ufshpb_put_map_ctx(hpb, srgn->mctx); + srgn->srgn_state = HPB_SRGN_UNUSED; + srgn->mctx = NULL; + } +} + +static int ufshpb_issue_umap_req(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, + bool atomic) +{ + struct ufshpb_req *umap_req; + int rgn_idx = rgn ? rgn->rgn_idx : 0; + + umap_req = ufshpb_get_req(hpb, rgn_idx, REQ_OP_SCSI_OUT, atomic); + if (!umap_req) + return -ENOMEM; + + ufshpb_execute_umap_req(hpb, umap_req, rgn); + + return 0; +} + +static int ufshpb_issue_umap_single_req(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + return ufshpb_issue_umap_req(hpb, rgn, true); +} + +static int ufshpb_issue_umap_all_req(struct ufshpb_lu *hpb) +{ + return ufshpb_issue_umap_req(hpb, NULL, false); +} + +static void __ufshpb_evict_region(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + struct victim_select_info *lru_info; + struct ufshpb_subregion *srgn; + int srgn_idx; + + lru_info = &hpb->lru_info; + + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "evict region %d\n", rgn->rgn_idx); + + ufshpb_cleanup_lru_info(lru_info, rgn); + + for_each_sub_region(rgn, srgn_idx, srgn) + ufshpb_purge_active_subregion(hpb, srgn); +} + +static int ufshpb_evict_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) +{ + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + if (rgn->rgn_state == HPB_RGN_PINNED) { + dev_warn(&hpb->sdev_ufs_lu->sdev_dev, + "pinned region cannot drop-out. region %d\n", + rgn->rgn_idx); + goto out; + } + if (!list_empty(&rgn->list_lru_rgn)) { + if (ufshpb_check_srgns_issue_state(hpb, rgn)) { + ret = -EBUSY; + goto out; + } + + if (hpb->is_hcm) { + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + ret = ufshpb_issue_umap_single_req(hpb, rgn); + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + if (ret) + goto out; + } + + __ufshpb_evict_region(hpb, rgn); + } +out: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return ret; +} + +static int ufshpb_issue_map_req(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, + struct ufshpb_subregion *srgn) +{ + struct ufshpb_req *map_req; + unsigned long flags; + int ret; + int err = -EAGAIN; + bool alloc_required = false; + enum HPB_SRGN_STATE state = HPB_SRGN_INVALID; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + + if (ufshpb_get_state(hpb) != HPB_PRESENT) { + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "%s: ufshpb state is not PRESENT\n", __func__); + goto unlock_out; + } + + if ((rgn->rgn_state == HPB_RGN_INACTIVE) && + (srgn->srgn_state == HPB_SRGN_INVALID)) { + err = 0; + goto unlock_out; + } + + if (srgn->srgn_state == HPB_SRGN_UNUSED) + alloc_required = true; + + /* + * If the subregion is already ISSUED state, + * a specific event (e.g., GC or wear-leveling, etc.) occurs in + * the device and HPB response for map loading is received. + * In this case, after finishing the HPB_READ_BUFFER, + * the next HPB_READ_BUFFER is performed again to obtain the latest + * map data. + */ + if (srgn->srgn_state == HPB_SRGN_ISSUED) + goto unlock_out; + + srgn->srgn_state = HPB_SRGN_ISSUED; + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + + if (alloc_required) { + srgn->mctx = ufshpb_get_map_ctx(hpb, srgn->is_last); + if (!srgn->mctx) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "get map_ctx failed. region %d - %d\n", + rgn->rgn_idx, srgn->srgn_idx); + state = HPB_SRGN_UNUSED; + goto change_srgn_state; + } + } + + map_req = ufshpb_get_map_req(hpb, srgn); + if (!map_req) + goto change_srgn_state; + + + ret = ufshpb_execute_map_req(hpb, map_req, srgn->is_last); + if (ret) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "%s: issue map_req failed: %d, region %d - %d\n", + __func__, ret, srgn->rgn_idx, srgn->srgn_idx); + goto free_map_req; + } + return 0; + +free_map_req: + ufshpb_put_map_req(hpb, map_req); +change_srgn_state: + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + srgn->srgn_state = state; +unlock_out: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return err; +} + +static int ufshpb_add_region(struct ufshpb_lu *hpb, struct ufshpb_region *rgn) +{ + struct ufshpb_region *victim_rgn = NULL; + struct victim_select_info *lru_info = &hpb->lru_info; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + /* + * If region belongs to lru_list, just move the region + * to the front of lru list. because the state of the region + * is already active-state + */ + if (!list_empty(&rgn->list_lru_rgn)) { + ufshpb_hit_lru_info(lru_info, rgn); + goto out; + } + + if (rgn->rgn_state == HPB_RGN_INACTIVE) { + if (atomic_read(&lru_info->active_cnt) == + lru_info->max_lru_active_cnt) { + /* + * If the maximum number of active regions + * is exceeded, evict the least recently used region. + * This case may occur when the device responds + * to the eviction information late. + * It is okay to evict the least recently used region, + * because the device could detect this region + * by not issuing HPB_READ + * + * in host control mode, verify that the entering + * region has enough reads + */ + if (hpb->is_hcm && + rgn->reads < hpb->params.eviction_thld_enter) { + ret = -EACCES; + goto out; + } + + victim_rgn = ufshpb_victim_lru_info(hpb); + if (!victim_rgn) { + dev_warn(&hpb->sdev_ufs_lu->sdev_dev, + "cannot get victim region error\n"); + ret = -ENOMEM; + goto out; + } + + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, + "LRU full (%d), choose victim %d\n", + atomic_read(&lru_info->active_cnt), + victim_rgn->rgn_idx); + + if (hpb->is_hcm) { + spin_unlock_irqrestore(&hpb->rgn_state_lock, + flags); + ret = ufshpb_issue_umap_single_req(hpb, + victim_rgn); + spin_lock_irqsave(&hpb->rgn_state_lock, + flags); + if (ret) + goto out; + } + + __ufshpb_evict_region(hpb, victim_rgn); + } + + /* + * When a region is added to lru_info list_head, + * it is guaranteed that the subregion has been + * assigned all mctx. If failed, try to receive mctx again + * without being added to lru_info list_head + */ + ufshpb_add_lru_info(lru_info, rgn); + } +out: + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); + return ret; +} + +static void ufshpb_rsp_req_region_update(struct ufshpb_lu *hpb, + struct utp_hpb_rsp *rsp_field) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + int i, rgn_i, srgn_i; + + BUILD_BUG_ON(sizeof(struct ufshpb_active_field) != HPB_ACT_FIELD_SIZE); + /* + * If the active region and the inactive region are the same, + * we will inactivate this region. + * The device could check this (region inactivated) and + * will response the proper active region information + */ + for (i = 0; i < rsp_field->active_rgn_cnt; i++) { + rgn_i = + be16_to_cpu(rsp_field->hpb_active_field[i].active_rgn); + srgn_i = + be16_to_cpu(rsp_field->hpb_active_field[i].active_srgn); + + rgn = hpb->rgn_tbl + rgn_i; + if (hpb->is_hcm && + (rgn->rgn_state != HPB_RGN_ACTIVE || is_rgn_dirty(rgn))) { + /* + * in host control mode, subregion activation + * recommendations are only allowed to active regions. + * Also, ignore recommendations for dirty regions - the + * host will make decisions concerning those by himself + */ + continue; + } + + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, + "activate(%d) region %d - %d\n", i, rgn_i, srgn_i); + + spin_lock(&hpb->rsp_list_lock); + ufshpb_update_active_info(hpb, rgn_i, srgn_i); + spin_unlock(&hpb->rsp_list_lock); + + srgn = rgn->srgn_tbl + srgn_i; + + /* blocking HPB_READ */ + spin_lock(&hpb->rgn_state_lock); + if (srgn->srgn_state == HPB_SRGN_VALID) + srgn->srgn_state = HPB_SRGN_INVALID; + spin_unlock(&hpb->rgn_state_lock); + } + + if (hpb->is_hcm) { + /* + * in host control mode the device is not allowed to inactivate + * regions + */ + goto out; + } + + for (i = 0; i < rsp_field->inactive_rgn_cnt; i++) { + rgn_i = be16_to_cpu(rsp_field->hpb_inactive_field[i]); + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, + "inactivate(%d) region %d\n", i, rgn_i); + + spin_lock(&hpb->rsp_list_lock); + ufshpb_update_inactive_info(hpb, rgn_i); + spin_unlock(&hpb->rsp_list_lock); + + rgn = hpb->rgn_tbl + rgn_i; + + spin_lock(&hpb->rgn_state_lock); + if (rgn->rgn_state != HPB_RGN_INACTIVE) { + for (srgn_i = 0; srgn_i < rgn->srgn_cnt; srgn_i++) { + srgn = rgn->srgn_tbl + srgn_i; + if (srgn->srgn_state == HPB_SRGN_VALID) + srgn->srgn_state = HPB_SRGN_INVALID; + } + } + spin_unlock(&hpb->rgn_state_lock); + } + +out: + dev_dbg(&hpb->sdev_ufs_lu->sdev_dev, "Noti: #ACT %u #INACT %u\n", + rsp_field->active_rgn_cnt, rsp_field->inactive_rgn_cnt); + + if (ufshpb_get_state(hpb) == HPB_PRESENT) + queue_work(ufshpb_wq, &hpb->map_work); +} + +static void ufshpb_dev_reset_handler(struct ufshpb_lu *hpb) +{ + struct victim_select_info *lru_info = &hpb->lru_info; + struct ufshpb_region *rgn; + unsigned long flags; + + spin_lock_irqsave(&hpb->rgn_state_lock, flags); + + list_for_each_entry(rgn, &lru_info->lh_lru_rgn, list_lru_rgn) + set_bit(RGN_FLAG_UPDATE, &rgn->rgn_flags); + + spin_unlock_irqrestore(&hpb->rgn_state_lock, flags); +} + + +/* + * This function will parse recommended active subregion information in sense + * data field of response UPIU with SAM_STAT_GOOD state. + */ +void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) +{ + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(lrbp->cmd->device); + struct utp_hpb_rsp *rsp_field = &lrbp->ucd_rsp_ptr->hr; + int data_seg_len; + + if (unlikely(lrbp->lun != rsp_field->lun)) { + struct scsi_device *sdev; + bool found = false; + + __shost_for_each_device(sdev, hba->host) { + hpb = ufshpb_get_hpb_data(sdev); + + if (!hpb) + continue; + + if (rsp_field->lun == hpb->lun) { + found = true; + break; + } + } + + if (!found) + return; + } + + if (!hpb) + return; + + if (ufshpb_get_state(hpb) == HPB_INIT) + return; + + if ((ufshpb_get_state(hpb) != HPB_PRESENT) && + (ufshpb_get_state(hpb) != HPB_SUSPEND)) { + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "%s: ufshpb state is not PRESENT/SUSPEND\n", + __func__); + return; + } + + data_seg_len = be32_to_cpu(lrbp->ucd_rsp_ptr->header.dword_2) + & MASK_RSP_UPIU_DATA_SEG_LEN; + + /* To flush remained rsp_list, we queue the map_work task */ + if (!data_seg_len) { + if (!ufshpb_is_general_lun(hpb->lun)) + return; + + ufshpb_kick_map_work(hpb); + return; + } + + BUILD_BUG_ON(sizeof(struct utp_hpb_rsp) != UTP_HPB_RSP_SIZE); + + if (!ufshpb_is_hpb_rsp_valid(hba, lrbp, rsp_field)) + return; + + hpb->stats.rb_noti_cnt++; + + switch (rsp_field->hpb_op) { + case HPB_RSP_REQ_REGION_UPDATE: + if (data_seg_len != DEV_DATA_SEG_LEN) + dev_warn(&hpb->sdev_ufs_lu->sdev_dev, + "%s: data seg length is not same.\n", + __func__); + ufshpb_rsp_req_region_update(hpb, rsp_field); + break; + case HPB_RSP_DEV_RESET: + dev_warn(&hpb->sdev_ufs_lu->sdev_dev, + "UFS device lost HPB information during PM.\n"); + + if (hpb->is_hcm) { + struct scsi_device *sdev; + + __shost_for_each_device(sdev, hba->host) { + struct ufshpb_lu *h = sdev->hostdata; + + if (h) + ufshpb_dev_reset_handler(h); + } + } + + break; + default: + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "hpb_op is not available: %d\n", + rsp_field->hpb_op); + break; + } +} + +static void ufshpb_add_active_list(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, + struct ufshpb_subregion *srgn) +{ + if (!list_empty(&rgn->list_inact_rgn)) + return; + + if (!list_empty(&srgn->list_act_srgn)) { + list_move(&srgn->list_act_srgn, &hpb->lh_act_srgn); + return; + } + + list_add(&srgn->list_act_srgn, &hpb->lh_act_srgn); +} + +static void ufshpb_add_pending_evict_list(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, + struct list_head *pending_list) +{ + struct ufshpb_subregion *srgn; + int srgn_idx; + + if (!list_empty(&rgn->list_inact_rgn)) + return; + + for_each_sub_region(rgn, srgn_idx, srgn) + if (!list_empty(&srgn->list_act_srgn)) + return; + + list_add_tail(&rgn->list_inact_rgn, pending_list); +} + +static void ufshpb_run_active_subregion_list(struct ufshpb_lu *hpb) +{ + struct ufshpb_region *rgn; + struct ufshpb_subregion *srgn; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + while ((srgn = list_first_entry_or_null(&hpb->lh_act_srgn, + struct ufshpb_subregion, + list_act_srgn))) { + if (ufshpb_get_state(hpb) == HPB_SUSPEND) + break; + + list_del_init(&srgn->list_act_srgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + + rgn = hpb->rgn_tbl + srgn->rgn_idx; + ret = ufshpb_add_region(hpb, rgn); + if (ret) + goto active_failed; + + ret = ufshpb_issue_map_req(hpb, rgn, srgn); + if (ret) { + dev_err(&hpb->sdev_ufs_lu->sdev_dev, + "issue map_req failed. ret %d, region %d - %d\n", + ret, rgn->rgn_idx, srgn->srgn_idx); + goto active_failed; + } + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + } + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + return; + +active_failed: + dev_err(&hpb->sdev_ufs_lu->sdev_dev, "failed to activate region %d - %d, will retry\n", + rgn->rgn_idx, srgn->srgn_idx); + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + ufshpb_add_active_list(hpb, rgn, srgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); +} + +static void ufshpb_run_inactive_region_list(struct ufshpb_lu *hpb) +{ + struct ufshpb_region *rgn; + unsigned long flags; + int ret; + LIST_HEAD(pending_list); + + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + while ((rgn = list_first_entry_or_null(&hpb->lh_inact_rgn, + struct ufshpb_region, + list_inact_rgn))) { + if (ufshpb_get_state(hpb) == HPB_SUSPEND) + break; + + list_del_init(&rgn->list_inact_rgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + + ret = ufshpb_evict_region(hpb, rgn); + if (ret) { + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + ufshpb_add_pending_evict_list(hpb, rgn, &pending_list); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); + } + + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + } + + list_splice(&pending_list, &hpb->lh_inact_rgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); +} + +static void ufshpb_normalization_work_handler(struct work_struct *work) +{ + struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, + ufshpb_normalization_work); + int rgn_idx; + u8 factor = hpb->params.normalization_factor; + + for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) { + struct ufshpb_region *rgn = hpb->rgn_tbl + rgn_idx; + int srgn_idx; + + spin_lock(&rgn->rgn_lock); + rgn->reads = 0; + for (srgn_idx = 0; srgn_idx < hpb->srgns_per_rgn; srgn_idx++) { + struct ufshpb_subregion *srgn = rgn->srgn_tbl + srgn_idx; + + srgn->reads >>= factor; + rgn->reads += srgn->reads; + } + spin_unlock(&rgn->rgn_lock); + + if (rgn->rgn_state != HPB_RGN_ACTIVE || rgn->reads) + continue; + + /* if region is active but has no reads - inactivate it */ + spin_lock(&hpb->rsp_list_lock); + ufshpb_update_inactive_info(hpb, rgn->rgn_idx); + spin_unlock(&hpb->rsp_list_lock); + } +} + +static void ufshpb_map_work_handler(struct work_struct *work) +{ + struct ufshpb_lu *hpb = container_of(work, struct ufshpb_lu, map_work); + + if (ufshpb_get_state(hpb) != HPB_PRESENT) { + dev_notice(&hpb->sdev_ufs_lu->sdev_dev, + "%s: ufshpb state is not PRESENT\n", __func__); + return; + } + + ufshpb_run_inactive_region_list(hpb); + ufshpb_run_active_subregion_list(hpb); +} + +/* + * this function doesn't need to hold lock due to be called in init. + * (rgn_state_lock, rsp_list_lock, etc..) + */ +static int ufshpb_init_pinned_active_region(struct ufs_hba *hba, + struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + struct ufshpb_subregion *srgn; + int srgn_idx, i; + int err = 0; + + for_each_sub_region(rgn, srgn_idx, srgn) { + srgn->mctx = ufshpb_get_map_ctx(hpb, srgn->is_last); + srgn->srgn_state = HPB_SRGN_INVALID; + if (!srgn->mctx) { + err = -ENOMEM; + dev_err(hba->dev, + "alloc mctx for pinned region failed\n"); + goto release; + } + + list_add_tail(&srgn->list_act_srgn, &hpb->lh_act_srgn); + } + + rgn->rgn_state = HPB_RGN_PINNED; + return 0; + +release: + for (i = 0; i < srgn_idx; i++) { + srgn = rgn->srgn_tbl + i; + ufshpb_put_map_ctx(hpb, srgn->mctx); + } + return err; +} + +static void ufshpb_init_subregion_tbl(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, bool last) +{ + int srgn_idx; + struct ufshpb_subregion *srgn; + + for_each_sub_region(rgn, srgn_idx, srgn) { + INIT_LIST_HEAD(&srgn->list_act_srgn); + + srgn->rgn_idx = rgn->rgn_idx; + srgn->srgn_idx = srgn_idx; + srgn->srgn_state = HPB_SRGN_UNUSED; + } + + if (unlikely(last && hpb->last_srgn_entries)) + srgn->is_last = true; +} + +static int ufshpb_alloc_subregion_tbl(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn, int srgn_cnt) +{ + rgn->srgn_tbl = kvcalloc(srgn_cnt, sizeof(struct ufshpb_subregion), + GFP_KERNEL); + if (!rgn->srgn_tbl) + return -ENOMEM; + + rgn->srgn_cnt = srgn_cnt; + return 0; +} + +static void ufshpb_lu_parameter_init(struct ufs_hba *hba, + struct ufshpb_lu *hpb, + struct ufshpb_dev_info *hpb_dev_info, + struct ufshpb_lu_info *hpb_lu_info) +{ + u32 entries_per_rgn; + u64 rgn_mem_size, tmp; + + /* for pre_req */ + hpb->pre_req_min_tr_len = hpb_dev_info->max_hpb_single_cmd + 1; + + if (ufshpb_is_legacy(hba)) + hpb->pre_req_max_tr_len = HPB_LEGACY_CHUNK_HIGH; + else + hpb->pre_req_max_tr_len = HPB_MULTI_CHUNK_HIGH; + + + hpb->cur_read_id = 0; + + hpb->lu_pinned_start = hpb_lu_info->pinned_start; + hpb->lu_pinned_end = hpb_lu_info->num_pinned ? + (hpb_lu_info->pinned_start + hpb_lu_info->num_pinned - 1) + : PINNED_NOT_SET; + hpb->lru_info.max_lru_active_cnt = + hpb_lu_info->max_active_rgns - hpb_lu_info->num_pinned; + + rgn_mem_size = (1ULL << hpb_dev_info->rgn_size) * HPB_RGN_SIZE_UNIT + * HPB_ENTRY_SIZE; + do_div(rgn_mem_size, HPB_ENTRY_BLOCK_SIZE); + hpb->srgn_mem_size = (1ULL << hpb_dev_info->srgn_size) + * HPB_RGN_SIZE_UNIT / HPB_ENTRY_BLOCK_SIZE * HPB_ENTRY_SIZE; + + tmp = rgn_mem_size; + do_div(tmp, HPB_ENTRY_SIZE); + entries_per_rgn = (u32)tmp; + hpb->entries_per_rgn_shift = ilog2(entries_per_rgn); + hpb->entries_per_rgn_mask = entries_per_rgn - 1; + + hpb->entries_per_srgn = hpb->srgn_mem_size / HPB_ENTRY_SIZE; + hpb->entries_per_srgn_shift = ilog2(hpb->entries_per_srgn); + hpb->entries_per_srgn_mask = hpb->entries_per_srgn - 1; + + tmp = rgn_mem_size; + do_div(tmp, hpb->srgn_mem_size); + hpb->srgns_per_rgn = (int)tmp; + + hpb->rgns_per_lu = DIV_ROUND_UP(hpb_lu_info->num_blocks, + entries_per_rgn); + hpb->srgns_per_lu = DIV_ROUND_UP(hpb_lu_info->num_blocks, + (hpb->srgn_mem_size / HPB_ENTRY_SIZE)); + hpb->last_srgn_entries = hpb_lu_info->num_blocks + % (hpb->srgn_mem_size / HPB_ENTRY_SIZE); + + hpb->pages_per_srgn = DIV_ROUND_UP(hpb->srgn_mem_size, PAGE_SIZE); + + if (hpb_dev_info->control_mode == HPB_HOST_CONTROL) + hpb->is_hcm = true; +} + +static int ufshpb_alloc_region_tbl(struct ufs_hba *hba, struct ufshpb_lu *hpb) +{ + struct ufshpb_region *rgn_table, *rgn; + int rgn_idx, i; + int ret = 0; + + rgn_table = kvcalloc(hpb->rgns_per_lu, sizeof(struct ufshpb_region), + GFP_KERNEL); + if (!rgn_table) + return -ENOMEM; + + hpb->rgn_tbl = rgn_table; + + for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) { + int srgn_cnt = hpb->srgns_per_rgn; + bool last_srgn = false; + + rgn = rgn_table + rgn_idx; + rgn->rgn_idx = rgn_idx; + + spin_lock_init(&rgn->rgn_lock); + + INIT_LIST_HEAD(&rgn->list_inact_rgn); + INIT_LIST_HEAD(&rgn->list_lru_rgn); + INIT_LIST_HEAD(&rgn->list_expired_rgn); + + if (rgn_idx == hpb->rgns_per_lu - 1) { + srgn_cnt = ((hpb->srgns_per_lu - 1) % + hpb->srgns_per_rgn) + 1; + last_srgn = true; + } + + ret = ufshpb_alloc_subregion_tbl(hpb, rgn, srgn_cnt); + if (ret) + goto release_srgn_table; + ufshpb_init_subregion_tbl(hpb, rgn, last_srgn); + + if (ufshpb_is_pinned_region(hpb, rgn_idx)) { + ret = ufshpb_init_pinned_active_region(hba, hpb, rgn); + if (ret) + goto release_srgn_table; + } else { + rgn->rgn_state = HPB_RGN_INACTIVE; + } + + rgn->rgn_flags = 0; + rgn->hpb = hpb; + } + + return 0; + +release_srgn_table: + for (i = 0; i < rgn_idx; i++) { + rgn = rgn_table + i; + kvfree(rgn->srgn_tbl); + } + kvfree(rgn_table); + return ret; +} + +static void ufshpb_destroy_subregion_tbl(struct ufshpb_lu *hpb, + struct ufshpb_region *rgn) +{ + int srgn_idx; + struct ufshpb_subregion *srgn; + + for_each_sub_region(rgn, srgn_idx, srgn) + if (srgn->srgn_state != HPB_SRGN_UNUSED) { + srgn->srgn_state = HPB_SRGN_UNUSED; + ufshpb_put_map_ctx(hpb, srgn->mctx); + } +} + +static void ufshpb_destroy_region_tbl(struct ufshpb_lu *hpb) +{ + int rgn_idx; + + for (rgn_idx = 0; rgn_idx < hpb->rgns_per_lu; rgn_idx++) { + struct ufshpb_region *rgn; + + rgn = hpb->rgn_tbl + rgn_idx; + if (rgn->rgn_state != HPB_RGN_INACTIVE) { + rgn->rgn_state = HPB_RGN_INACTIVE; + + ufshpb_destroy_subregion_tbl(hpb, rgn); + } + + kvfree(rgn->srgn_tbl); + } + + kvfree(hpb->rgn_tbl); +} + +/* SYSFS functions */ +#define ufshpb_sysfs_attr_show_func(__name) \ +static ssize_t __name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); \ + \ + if (!hpb) \ + return -ENODEV; \ + \ + return sysfs_emit(buf, "%llu\n", hpb->stats.__name); \ +} \ +\ +static DEVICE_ATTR_RO(__name) + +ufshpb_sysfs_attr_show_func(hit_cnt); +ufshpb_sysfs_attr_show_func(miss_cnt); +ufshpb_sysfs_attr_show_func(rb_noti_cnt); +ufshpb_sysfs_attr_show_func(rb_active_cnt); +ufshpb_sysfs_attr_show_func(rb_inactive_cnt); +ufshpb_sysfs_attr_show_func(map_req_cnt); +ufshpb_sysfs_attr_show_func(umap_req_cnt); + +static struct attribute *hpb_dev_stat_attrs[] = { + &dev_attr_hit_cnt.attr, + &dev_attr_miss_cnt.attr, + &dev_attr_rb_noti_cnt.attr, + &dev_attr_rb_active_cnt.attr, + &dev_attr_rb_inactive_cnt.attr, + &dev_attr_map_req_cnt.attr, + &dev_attr_umap_req_cnt.attr, + NULL, +}; + +struct attribute_group ufs_sysfs_hpb_stat_group = { + .name = "hpb_stats", + .attrs = hpb_dev_stat_attrs, +}; + +/* SYSFS functions */ +#define ufshpb_sysfs_param_show_func(__name) \ +static ssize_t __name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct scsi_device *sdev = to_scsi_device(dev); \ + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); \ + \ + if (!hpb) \ + return -ENODEV; \ + \ + return sysfs_emit(buf, "%d\n", hpb->params.__name); \ +} + +ufshpb_sysfs_param_show_func(requeue_timeout_ms); +static ssize_t +requeue_timeout_ms_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val < 0) + return -EINVAL; + + hpb->params.requeue_timeout_ms = val; + + return count; +} +static DEVICE_ATTR_RW(requeue_timeout_ms); + +ufshpb_sysfs_param_show_func(activation_thld); +static ssize_t +activation_thld_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= 0) + return -EINVAL; + + hpb->params.activation_thld = val; + + return count; +} +static DEVICE_ATTR_RW(activation_thld); + +ufshpb_sysfs_param_show_func(normalization_factor); +static ssize_t +normalization_factor_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= 0 || val > ilog2(hpb->entries_per_srgn)) + return -EINVAL; + + hpb->params.normalization_factor = val; + + return count; +} +static DEVICE_ATTR_RW(normalization_factor); + +ufshpb_sysfs_param_show_func(eviction_thld_enter); +static ssize_t +eviction_thld_enter_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= hpb->params.eviction_thld_exit) + return -EINVAL; + + hpb->params.eviction_thld_enter = val; + + return count; +} +static DEVICE_ATTR_RW(eviction_thld_enter); + +ufshpb_sysfs_param_show_func(eviction_thld_exit); +static ssize_t +eviction_thld_exit_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= hpb->params.activation_thld) + return -EINVAL; + + hpb->params.eviction_thld_exit = val; + + return count; +} +static DEVICE_ATTR_RW(eviction_thld_exit); + +ufshpb_sysfs_param_show_func(read_timeout_ms); +static ssize_t +read_timeout_ms_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + /* read_timeout >> timeout_polling_interval */ + if (val < hpb->params.timeout_polling_interval_ms * 2) + return -EINVAL; + + hpb->params.read_timeout_ms = val; + + return count; +} +static DEVICE_ATTR_RW(read_timeout_ms); + +ufshpb_sysfs_param_show_func(read_timeout_expiries); +static ssize_t +read_timeout_expiries_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= 0) + return -EINVAL; + + hpb->params.read_timeout_expiries = val; + + return count; +} +static DEVICE_ATTR_RW(read_timeout_expiries); + +ufshpb_sysfs_param_show_func(timeout_polling_interval_ms); +static ssize_t +timeout_polling_interval_ms_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + /* timeout_polling_interval << read_timeout */ + if (val <= 0 || val > hpb->params.read_timeout_ms / 2) + return -EINVAL; + + hpb->params.timeout_polling_interval_ms = val; + + return count; +} +static DEVICE_ATTR_RW(timeout_polling_interval_ms); + +ufshpb_sysfs_param_show_func(inflight_map_req); +static ssize_t inflight_map_req_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_device *sdev = to_scsi_device(dev); + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + int val; + + if (!hpb) + return -ENODEV; + + if (!hpb->is_hcm) + return -EOPNOTSUPP; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + if (val <= 0 || val > hpb->sdev_ufs_lu->queue_depth - 1) + return -EINVAL; + + hpb->params.inflight_map_req = val; + + return count; +} +static DEVICE_ATTR_RW(inflight_map_req); + + +static void ufshpb_hcm_param_init(struct ufshpb_lu *hpb) +{ + hpb->params.activation_thld = ACTIVATION_THRESHOLD; + hpb->params.normalization_factor = 1; + hpb->params.eviction_thld_enter = (ACTIVATION_THRESHOLD << 5); + hpb->params.eviction_thld_exit = (ACTIVATION_THRESHOLD << 4); + hpb->params.read_timeout_ms = READ_TO_MS; + hpb->params.read_timeout_expiries = READ_TO_EXPIRIES; + hpb->params.timeout_polling_interval_ms = POLLING_INTERVAL_MS; + hpb->params.inflight_map_req = THROTTLE_MAP_REQ_DEFAULT; +} + +static struct attribute *hpb_dev_param_attrs[] = { + &dev_attr_requeue_timeout_ms.attr, + &dev_attr_activation_thld.attr, + &dev_attr_normalization_factor.attr, + &dev_attr_eviction_thld_enter.attr, + &dev_attr_eviction_thld_exit.attr, + &dev_attr_read_timeout_ms.attr, + &dev_attr_read_timeout_expiries.attr, + &dev_attr_timeout_polling_interval_ms.attr, + &dev_attr_inflight_map_req.attr, + NULL, +}; + +struct attribute_group ufs_sysfs_hpb_param_group = { + .name = "hpb_params", + .attrs = hpb_dev_param_attrs, +}; + +static int ufshpb_pre_req_mempool_init(struct ufshpb_lu *hpb) +{ + struct ufshpb_req *pre_req = NULL, *t; + int qd = hpb->sdev_ufs_lu->queue_depth / 2; + int i; + + INIT_LIST_HEAD(&hpb->lh_pre_req_free); + + hpb->pre_req = kcalloc(qd, sizeof(struct ufshpb_req), GFP_KERNEL); + hpb->throttle_pre_req = qd; + hpb->num_inflight_pre_req = 0; + + if (!hpb->pre_req) + goto release_mem; + + for (i = 0; i < qd; i++) { + pre_req = hpb->pre_req + i; + INIT_LIST_HEAD(&pre_req->list_req); + pre_req->req = NULL; + + pre_req->bio = bio_alloc(GFP_KERNEL, 1); + if (!pre_req->bio) + goto release_mem; + + pre_req->wb.m_page = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!pre_req->wb.m_page) { + bio_put(pre_req->bio); + goto release_mem; + } + + list_add_tail(&pre_req->list_req, &hpb->lh_pre_req_free); + } + + return 0; +release_mem: + list_for_each_entry_safe(pre_req, t, &hpb->lh_pre_req_free, list_req) { + list_del_init(&pre_req->list_req); + bio_put(pre_req->bio); + __free_page(pre_req->wb.m_page); + } + + kfree(hpb->pre_req); + return -ENOMEM; +} + +static void ufshpb_pre_req_mempool_destroy(struct ufshpb_lu *hpb) +{ + struct ufshpb_req *pre_req = NULL; + int i; + + for (i = 0; i < hpb->throttle_pre_req; i++) { + pre_req = hpb->pre_req + i; + bio_put(hpb->pre_req[i].bio); + if (!pre_req->wb.m_page) + __free_page(hpb->pre_req[i].wb.m_page); + list_del_init(&pre_req->list_req); + } + + kfree(hpb->pre_req); +} + +static void ufshpb_stat_init(struct ufshpb_lu *hpb) +{ + hpb->stats.hit_cnt = 0; + hpb->stats.miss_cnt = 0; + hpb->stats.rb_noti_cnt = 0; + hpb->stats.rb_active_cnt = 0; + hpb->stats.rb_inactive_cnt = 0; + hpb->stats.map_req_cnt = 0; + hpb->stats.umap_req_cnt = 0; +} + +static void ufshpb_param_init(struct ufshpb_lu *hpb) +{ + hpb->params.requeue_timeout_ms = HPB_REQUEUE_TIME_MS; + if (hpb->is_hcm) + ufshpb_hcm_param_init(hpb); +} + +static int ufshpb_lu_hpb_init(struct ufs_hba *hba, struct ufshpb_lu *hpb) +{ + int ret; + + spin_lock_init(&hpb->rgn_state_lock); + spin_lock_init(&hpb->rsp_list_lock); + + INIT_LIST_HEAD(&hpb->lru_info.lh_lru_rgn); + INIT_LIST_HEAD(&hpb->lh_act_srgn); + INIT_LIST_HEAD(&hpb->lh_inact_rgn); + INIT_LIST_HEAD(&hpb->list_hpb_lu); + + INIT_WORK(&hpb->map_work, ufshpb_map_work_handler); + if (hpb->is_hcm) { + INIT_WORK(&hpb->ufshpb_normalization_work, + ufshpb_normalization_work_handler); + INIT_DELAYED_WORK(&hpb->ufshpb_read_to_work, + ufshpb_read_to_handler); + } + + hpb->map_req_cache = kmem_cache_create("ufshpb_req_cache", + sizeof(struct ufshpb_req), 0, 0, NULL); + if (!hpb->map_req_cache) { + dev_err(hba->dev, "ufshpb(%d) ufshpb_req_cache create fail", + hpb->lun); + return -ENOMEM; + } + + hpb->m_page_cache = kmem_cache_create("ufshpb_m_page_cache", + sizeof(struct page *) * hpb->pages_per_srgn, + 0, 0, NULL); + if (!hpb->m_page_cache) { + dev_err(hba->dev, "ufshpb(%d) ufshpb_m_page_cache create fail", + hpb->lun); + ret = -ENOMEM; + goto release_req_cache; + } + + ret = ufshpb_pre_req_mempool_init(hpb); + if (ret) { + dev_err(hba->dev, "ufshpb(%d) pre_req_mempool init fail", + hpb->lun); + goto release_m_page_cache; + } + + ret = ufshpb_alloc_region_tbl(hba, hpb); + if (ret) + goto release_pre_req_mempool; + + ufshpb_stat_init(hpb); + ufshpb_param_init(hpb); + + if (hpb->is_hcm) { + unsigned int poll; + + poll = hpb->params.timeout_polling_interval_ms; + schedule_delayed_work(&hpb->ufshpb_read_to_work, + msecs_to_jiffies(poll)); + } + + return 0; + +release_pre_req_mempool: + ufshpb_pre_req_mempool_destroy(hpb); +release_m_page_cache: + kmem_cache_destroy(hpb->m_page_cache); +release_req_cache: + kmem_cache_destroy(hpb->map_req_cache); + return ret; +} + +static struct ufshpb_lu * +ufshpb_alloc_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev, + struct ufshpb_dev_info *hpb_dev_info, + struct ufshpb_lu_info *hpb_lu_info) +{ + struct ufshpb_lu *hpb; + int ret; + + hpb = kzalloc(sizeof(struct ufshpb_lu), GFP_KERNEL); + if (!hpb) + return NULL; + + hpb->lun = sdev->lun; + hpb->sdev_ufs_lu = sdev; + + ufshpb_lu_parameter_init(hba, hpb, hpb_dev_info, hpb_lu_info); + + ret = ufshpb_lu_hpb_init(hba, hpb); + if (ret) { + dev_err(hba->dev, "hpb lu init failed. ret %d", ret); + goto release_hpb; + } + + sdev->hostdata = hpb; + return hpb; + +release_hpb: + kfree(hpb); + return NULL; +} + +static void ufshpb_discard_rsp_lists(struct ufshpb_lu *hpb) +{ + struct ufshpb_region *rgn, *next_rgn; + struct ufshpb_subregion *srgn, *next_srgn; + unsigned long flags; + + /* + * If the device reset occurred, the remained HPB region information + * may be stale. Therefore, by dicarding the lists of HPB response + * that remained after reset, it prevents unnecessary work. + */ + spin_lock_irqsave(&hpb->rsp_list_lock, flags); + list_for_each_entry_safe(rgn, next_rgn, &hpb->lh_inact_rgn, + list_inact_rgn) + list_del_init(&rgn->list_inact_rgn); + + list_for_each_entry_safe(srgn, next_srgn, &hpb->lh_act_srgn, + list_act_srgn) + list_del_init(&srgn->list_act_srgn); + spin_unlock_irqrestore(&hpb->rsp_list_lock, flags); +} + +static void ufshpb_cancel_jobs(struct ufshpb_lu *hpb) +{ + if (hpb->is_hcm) { + cancel_delayed_work_sync(&hpb->ufshpb_read_to_work); + cancel_work_sync(&hpb->ufshpb_normalization_work); + } + cancel_work_sync(&hpb->map_work); +} + +static bool ufshpb_check_hpb_reset_query(struct ufs_hba *hba) +{ + int err = 0; + bool flag_res = true; + int try; + + /* wait for the device to complete HPB reset query */ + for (try = 0; try < HPB_RESET_REQ_RETRIES; try++) { + dev_dbg(hba->dev, + "%s start flag reset polling %d times\n", + __func__, try); + + /* Poll fHpbReset flag to be cleared */ + err = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG, + QUERY_FLAG_IDN_HPB_RESET, 0, &flag_res); + + if (err) { + dev_err(hba->dev, + "%s reading fHpbReset flag failed with error %d\n", + __func__, err); + return flag_res; + } + + if (!flag_res) + goto out; + + usleep_range(1000, 1100); + } + if (flag_res) { + dev_err(hba->dev, + "%s fHpbReset was not cleared by the device\n", + __func__); + } +out: + return flag_res; +} + +void ufshpb_reset(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + + shost_for_each_device(sdev, hba->host) { + hpb = ufshpb_get_hpb_data(sdev); + if (!hpb) + continue; + + if (ufshpb_get_state(hpb) != HPB_RESET) + continue; + + ufshpb_set_state(hpb, HPB_PRESENT); + } +} + +void ufshpb_reset_host(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + + shost_for_each_device(sdev, hba->host) { + hpb = ufshpb_get_hpb_data(sdev); + if (!hpb) + continue; + + if (ufshpb_get_state(hpb) != HPB_PRESENT) + continue; + ufshpb_set_state(hpb, HPB_RESET); + ufshpb_cancel_jobs(hpb); + ufshpb_discard_rsp_lists(hpb); + } +} + +void ufshpb_suspend(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + + shost_for_each_device(sdev, hba->host) { + hpb = ufshpb_get_hpb_data(sdev); + if (!hpb) + continue; + + if (ufshpb_get_state(hpb) != HPB_PRESENT) + continue; + ufshpb_set_state(hpb, HPB_SUSPEND); + ufshpb_cancel_jobs(hpb); + } +} + +void ufshpb_resume(struct ufs_hba *hba) +{ + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + + shost_for_each_device(sdev, hba->host) { + hpb = ufshpb_get_hpb_data(sdev); + if (!hpb) + continue; + + if ((ufshpb_get_state(hpb) != HPB_PRESENT) && + (ufshpb_get_state(hpb) != HPB_SUSPEND)) + continue; + ufshpb_set_state(hpb, HPB_PRESENT); + ufshpb_kick_map_work(hpb); + if (hpb->is_hcm) { + unsigned int poll = + hpb->params.timeout_polling_interval_ms; + + schedule_delayed_work(&hpb->ufshpb_read_to_work, + msecs_to_jiffies(poll)); + } + } +} + +static int ufshpb_get_lu_info(struct ufs_hba *hba, int lun, + struct ufshpb_lu_info *hpb_lu_info) +{ + u16 max_active_rgns; + u8 lu_enable; + int size; + int ret; + char desc_buf[QUERY_DESC_MAX_SIZE]; + + ufshcd_map_desc_id_to_length(hba, QUERY_DESC_IDN_UNIT, &size); + + pm_runtime_get_sync(hba->dev); + ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC, + QUERY_DESC_IDN_UNIT, lun, 0, + desc_buf, &size); + pm_runtime_put_sync(hba->dev); + + if (ret) { + dev_err(hba->dev, + "%s: idn: %d lun: %d query request failed", + __func__, QUERY_DESC_IDN_UNIT, lun); + return ret; + } + + lu_enable = desc_buf[UNIT_DESC_PARAM_LU_ENABLE]; + if (lu_enable != LU_ENABLED_HPB_FUNC) + return -ENODEV; + + max_active_rgns = get_unaligned_be16( + desc_buf + UNIT_DESC_PARAM_HPB_LU_MAX_ACTIVE_RGNS); + if (!max_active_rgns) { + dev_err(hba->dev, + "lun %d wrong number of max active regions\n", lun); + return -ENODEV; + } + + hpb_lu_info->num_blocks = get_unaligned_be64( + desc_buf + UNIT_DESC_PARAM_LOGICAL_BLK_COUNT); + hpb_lu_info->pinned_start = get_unaligned_be16( + desc_buf + UNIT_DESC_PARAM_HPB_PIN_RGN_START_OFF); + hpb_lu_info->num_pinned = get_unaligned_be16( + desc_buf + UNIT_DESC_PARAM_HPB_NUM_PIN_RGNS); + hpb_lu_info->max_active_rgns = max_active_rgns; + + return 0; +} + +void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) +{ + struct ufshpb_lu *hpb = ufshpb_get_hpb_data(sdev); + + if (!hpb) + return; + + ufshpb_set_state(hpb, HPB_FAILED); + + sdev = hpb->sdev_ufs_lu; + sdev->hostdata = NULL; + + ufshpb_cancel_jobs(hpb); + + ufshpb_pre_req_mempool_destroy(hpb); + ufshpb_destroy_region_tbl(hpb); + + kmem_cache_destroy(hpb->map_req_cache); + kmem_cache_destroy(hpb->m_page_cache); + + list_del_init(&hpb->list_hpb_lu); + + kfree(hpb); +} + +static void ufshpb_hpb_lu_prepared(struct ufs_hba *hba) +{ + int pool_size; + struct ufshpb_lu *hpb; + struct scsi_device *sdev; + bool init_success; + + if (tot_active_srgn_pages == 0) { + ufshpb_remove(hba); + return; + } + + init_success = !ufshpb_check_hpb_reset_query(hba); + + pool_size = PAGE_ALIGN(ufshpb_host_map_kbytes * 1024) / PAGE_SIZE; + if (pool_size > tot_active_srgn_pages) { + mempool_resize(ufshpb_mctx_pool, tot_active_srgn_pages); + mempool_resize(ufshpb_page_pool, tot_active_srgn_pages); + } + + shost_for_each_device(sdev, hba->host) { + hpb = ufshpb_get_hpb_data(sdev); + if (!hpb) + continue; + + if (init_success) { + ufshpb_set_state(hpb, HPB_PRESENT); + if ((hpb->lu_pinned_end - hpb->lu_pinned_start) > 0) + queue_work(ufshpb_wq, &hpb->map_work); + if (!hpb->is_hcm) + ufshpb_issue_umap_all_req(hpb); + } else { + dev_err(hba->dev, "destroy HPB lu %d\n", hpb->lun); + ufshpb_destroy_lu(hba, sdev); + } + } + + if (!init_success) + ufshpb_remove(hba); +} + +void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) +{ + struct ufshpb_lu *hpb; + int ret; + struct ufshpb_lu_info hpb_lu_info = { 0 }; + int lun = sdev->lun; + + if (lun >= hba->dev_info.max_lu_supported) + goto out; + + ret = ufshpb_get_lu_info(hba, lun, &hpb_lu_info); + if (ret) + goto out; + + hpb = ufshpb_alloc_hpb_lu(hba, sdev, ufs_hba_to_hpb(hba), &hpb_lu_info); + if (!hpb) + goto out; + + tot_active_srgn_pages += hpb_lu_info.max_active_rgns * + hpb->srgns_per_rgn * hpb->pages_per_srgn; + +out: + /* All LUs are initialized */ + if (atomic_dec_and_test(&ufs_hba_to_hpb(hba)->slave_conf_cnt)) + ufshpb_hpb_lu_prepared(hba); +} + +static int ufshpb_init_mem_wq(struct ufs_hba *hba) +{ + int ret; + unsigned int pool_size; + + ufshpb_mctx_cache = kmem_cache_create("ufshpb_mctx_cache", + sizeof(struct ufshpb_map_ctx), + 0, 0, NULL); + if (!ufshpb_mctx_cache) { + dev_err(hba->dev, "ufshpb: cannot init mctx cache\n"); + return -ENOMEM; + } + + pool_size = PAGE_ALIGN(ufshpb_host_map_kbytes * 1024) / PAGE_SIZE; + dev_info(hba->dev, "%s:%d ufshpb_host_map_kbytes %u pool_size %u\n", + __func__, __LINE__, ufshpb_host_map_kbytes, pool_size); + + ufshpb_mctx_pool = mempool_create_slab_pool(pool_size, + ufshpb_mctx_cache); + if (!ufshpb_mctx_pool) { + dev_err(hba->dev, "ufshpb: cannot init mctx pool\n"); + ret = -ENOMEM; + goto release_mctx_cache; + } + + ufshpb_page_pool = mempool_create_page_pool(pool_size, 0); + if (!ufshpb_page_pool) { + dev_err(hba->dev, "ufshpb: cannot init page pool\n"); + ret = -ENOMEM; + goto release_mctx_pool; + } + + ufshpb_wq = alloc_workqueue("ufshpb-wq", + WQ_UNBOUND | WQ_MEM_RECLAIM, 0); + if (!ufshpb_wq) { + dev_err(hba->dev, "ufshpb: alloc workqueue failed\n"); + ret = -ENOMEM; + goto release_page_pool; + } + + return 0; + +release_page_pool: + mempool_destroy(ufshpb_page_pool); +release_mctx_pool: + mempool_destroy(ufshpb_mctx_pool); +release_mctx_cache: + kmem_cache_destroy(ufshpb_mctx_cache); + return ret; +} + +void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) +{ + struct ufshpb_dev_info *hpb_info = ufs_hba_to_hpb(hba); + int max_active_rgns = 0; + int hpb_num_lu; + + hpb_num_lu = geo_buf[GEOMETRY_DESC_PARAM_HPB_NUMBER_LU]; + if (hpb_num_lu == 0) { + dev_err(hba->dev, "No HPB LU supported\n"); + hpb_info->hpb_disabled = true; + return; + } + + hpb_info->rgn_size = geo_buf[GEOMETRY_DESC_PARAM_HPB_REGION_SIZE]; + hpb_info->srgn_size = geo_buf[GEOMETRY_DESC_PARAM_HPB_SUBREGION_SIZE]; + max_active_rgns = get_unaligned_be16(geo_buf + + GEOMETRY_DESC_PARAM_HPB_MAX_ACTIVE_REGS); + + if (hpb_info->rgn_size == 0 || hpb_info->srgn_size == 0 || + max_active_rgns == 0) { + dev_err(hba->dev, "No HPB supported device\n"); + hpb_info->hpb_disabled = true; + return; + } +} + +void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) +{ + struct ufshpb_dev_info *hpb_dev_info = ufs_hba_to_hpb(hba); + int version, ret; + u32 max_hpb_single_cmd = HPB_MULTI_CHUNK_LOW; + + hpb_dev_info->control_mode = desc_buf[DEVICE_DESC_PARAM_HPB_CONTROL]; + + version = get_unaligned_be16(desc_buf + DEVICE_DESC_PARAM_HPB_VER); + if ((version != HPB_SUPPORT_VERSION) && + (version != HPB_SUPPORT_LEGACY_VERSION)) { + dev_err(hba->dev, "%s: HPB %x version is not supported.\n", + __func__, version); + hpb_dev_info->hpb_disabled = true; + return; + } + + if (version == HPB_SUPPORT_LEGACY_VERSION) + hpb_dev_info->is_legacy = true; + + pm_runtime_get_sync(hba->dev); + ret = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR, + QUERY_ATTR_IDN_MAX_HPB_SINGLE_CMD, 0, 0, &max_hpb_single_cmd); + pm_runtime_put_sync(hba->dev); + + if (ret) + dev_err(hba->dev, "%s: idn: read max size of single hpb cmd query request failed", + __func__); + hpb_dev_info->max_hpb_single_cmd = max_hpb_single_cmd; + + /* + * Get the number of user logical unit to check whether all + * scsi_device finish initialization + */ + hpb_dev_info->num_lu = desc_buf[DEVICE_DESC_PARAM_NUM_LU]; +} + +void ufshpb_init(struct ufs_hba *hba) +{ + struct ufshpb_dev_info *hpb_dev_info = ufs_hba_to_hpb(hba); + int try; + int ret; + + if (!ufshpb_is_allowed(hba) || !hba->dev_info.hpb_enabled) + return; + + if (ufshpb_init_mem_wq(hba)) { + hpb_dev_info->hpb_disabled = true; + return; + } + + atomic_set(&hpb_dev_info->slave_conf_cnt, hpb_dev_info->num_lu); + tot_active_srgn_pages = 0; + /* issue HPB reset query */ + for (try = 0; try < HPB_RESET_REQ_RETRIES; try++) { + ret = ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_SET_FLAG, + QUERY_FLAG_IDN_HPB_RESET, 0, NULL); + if (!ret) + break; + } +} + +void ufshpb_remove(struct ufs_hba *hba) +{ + mempool_destroy(ufshpb_page_pool); + mempool_destroy(ufshpb_mctx_pool); + kmem_cache_destroy(ufshpb_mctx_cache); + + destroy_workqueue(ufshpb_wq); +} + +module_param(ufshpb_host_map_kbytes, uint, 0644); +MODULE_PARM_DESC(ufshpb_host_map_kbytes, + "ufshpb host mapping memory kilo-bytes for ufshpb memory-pool"); diff --git a/drivers/scsi/ufs/ufshpb.h b/drivers/scsi/ufs/ufshpb.h new file mode 100644 index 000000000000..c74a6c35a446 --- /dev/null +++ b/drivers/scsi/ufs/ufshpb.h @@ -0,0 +1,321 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Universal Flash Storage Host Performance Booster + * + * Copyright (C) 2017-2021 Samsung Electronics Co., Ltd. + * + * Authors: + * Yongmyung Lee + * Jinyoung Choi + */ + +#ifndef _UFSHPB_H_ +#define _UFSHPB_H_ + +/* hpb response UPIU macro */ +#define HPB_RSP_NONE 0x0 +#define HPB_RSP_REQ_REGION_UPDATE 0x1 +#define HPB_RSP_DEV_RESET 0x2 +#define MAX_ACTIVE_NUM 2 +#define MAX_INACTIVE_NUM 2 +#define DEV_DATA_SEG_LEN 0x14 +#define DEV_SENSE_SEG_LEN 0x12 +#define DEV_DES_TYPE 0x80 +#define DEV_ADDITIONAL_LEN 0x10 + +/* hpb map & entries macro */ +#define HPB_RGN_SIZE_UNIT 512 +#define HPB_ENTRY_BLOCK_SIZE 4096 +#define HPB_ENTRY_SIZE 0x8 +#define PINNED_NOT_SET U32_MAX + +/* hpb support chunk size */ +#define HPB_LEGACY_CHUNK_HIGH 1 +#define HPB_MULTI_CHUNK_LOW 7 +#define HPB_MULTI_CHUNK_HIGH 256 + +/* hpb vender defined opcode */ +#define UFSHPB_READ 0xF8 +#define UFSHPB_READ_BUFFER 0xF9 +#define UFSHPB_READ_BUFFER_ID 0x01 +#define UFSHPB_WRITE_BUFFER 0xFA +#define UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID 0x01 +#define UFSHPB_WRITE_BUFFER_PREFETCH_ID 0x02 +#define UFSHPB_WRITE_BUFFER_INACT_ALL_ID 0x03 +#define HPB_WRITE_BUFFER_CMD_LENGTH 10 +#define MAX_HPB_READ_ID 0x7F +#define HPB_READ_BUFFER_CMD_LENGTH 10 +#define LU_ENABLED_HPB_FUNC 0x02 + +#define HPB_RESET_REQ_RETRIES 10 +#define HPB_MAP_REQ_RETRIES 5 +#define HPB_REQUEUE_TIME_MS 0 + +#define HPB_SUPPORT_VERSION 0x200 +#define HPB_SUPPORT_LEGACY_VERSION 0x100 + +enum UFSHPB_MODE { + HPB_HOST_CONTROL, + HPB_DEVICE_CONTROL, +}; + +enum UFSHPB_STATE { + HPB_INIT = 0, + HPB_PRESENT = 1, + HPB_SUSPEND, + HPB_FAILED, + HPB_RESET, +}; + +enum HPB_RGN_STATE { + HPB_RGN_INACTIVE, + HPB_RGN_ACTIVE, + /* pinned regions are always active */ + HPB_RGN_PINNED, +}; + +enum HPB_SRGN_STATE { + HPB_SRGN_UNUSED, + HPB_SRGN_INVALID, + HPB_SRGN_VALID, + HPB_SRGN_ISSUED, +}; + +/** + * struct ufshpb_lu_info - UFSHPB logical unit related info + * @num_blocks: the number of logical block + * @pinned_start: the start region number of pinned region + * @num_pinned: the number of pinned regions + * @max_active_rgns: maximum number of active regions + */ +struct ufshpb_lu_info { + int num_blocks; + int pinned_start; + int num_pinned; + int max_active_rgns; +}; + +struct ufshpb_map_ctx { + struct page **m_page; + unsigned long *ppn_dirty; +}; + +struct ufshpb_subregion { + struct ufshpb_map_ctx *mctx; + enum HPB_SRGN_STATE srgn_state; + int rgn_idx; + int srgn_idx; + bool is_last; + + /* subregion reads - for host mode */ + unsigned int reads; + + /* below information is used by rsp_list */ + struct list_head list_act_srgn; +}; + +struct ufshpb_region { + struct ufshpb_lu *hpb; + struct ufshpb_subregion *srgn_tbl; + enum HPB_RGN_STATE rgn_state; + int rgn_idx; + int srgn_cnt; + + /* below information is used by rsp_list */ + struct list_head list_inact_rgn; + + /* below information is used by lru */ + struct list_head list_lru_rgn; + unsigned long rgn_flags; +#define RGN_FLAG_DIRTY 0 +#define RGN_FLAG_UPDATE 1 + + /* region reads - for host mode */ + spinlock_t rgn_lock; + unsigned int reads; + /* region "cold" timer - for host mode */ + ktime_t read_timeout; + unsigned int read_timeout_expiries; + struct list_head list_expired_rgn; +}; + +#define for_each_sub_region(rgn, i, srgn) \ + for ((i) = 0; \ + ((i) < (rgn)->srgn_cnt) && ((srgn) = &(rgn)->srgn_tbl[i]); \ + (i)++) + +/** + * struct ufshpb_req - HPB related request structure (write/read buffer) + * @req: block layer request structure + * @bio: bio for this request + * @hpb: ufshpb_lu structure that related to + * @list_req: ufshpb_req mempool list + * @sense: store its sense data + * @mctx: L2P map information + * @rgn_idx: target region index + * @srgn_idx: target sub-region index + * @lun: target logical unit number + * @m_page: L2P map information data for pre-request + * @len: length of host-side cached L2P map in m_page + * @lpn: start LPN of L2P map in m_page + */ +struct ufshpb_req { + struct request *req; + struct bio *bio; + struct ufshpb_lu *hpb; + struct list_head list_req; + union { + struct { + struct ufshpb_map_ctx *mctx; + unsigned int rgn_idx; + unsigned int srgn_idx; + unsigned int lun; + } rb; + struct { + struct page *m_page; + unsigned int len; + unsigned long lpn; + } wb; + }; +}; + +struct victim_select_info { + struct list_head lh_lru_rgn; /* LRU list of regions */ + int max_lru_active_cnt; /* supported hpb #region - pinned #region */ + atomic_t active_cnt; +}; + +/** + * ufshpb_params - ufs hpb parameters + * @requeue_timeout_ms - requeue threshold of wb command (0x2) + * @activation_thld - min reads [IOs] to activate/update a region + * @normalization_factor - shift right the region's reads + * @eviction_thld_enter - min reads [IOs] for the entering region in eviction + * @eviction_thld_exit - max reads [IOs] for the exiting region in eviction + * @read_timeout_ms - timeout [ms] from the last read IO to the region + * @read_timeout_expiries - amount of allowable timeout expireis + * @timeout_polling_interval_ms - frequency in which timeouts are checked + * @inflight_map_req - number of inflight map requests + */ +struct ufshpb_params { + unsigned int requeue_timeout_ms; + unsigned int activation_thld; + unsigned int normalization_factor; + unsigned int eviction_thld_enter; + unsigned int eviction_thld_exit; + unsigned int read_timeout_ms; + unsigned int read_timeout_expiries; + unsigned int timeout_polling_interval_ms; + unsigned int inflight_map_req; +}; + +struct ufshpb_stats { + u64 hit_cnt; + u64 miss_cnt; + u64 rb_noti_cnt; + u64 rb_active_cnt; + u64 rb_inactive_cnt; + u64 map_req_cnt; + u64 pre_req_cnt; + u64 umap_req_cnt; +}; + +struct ufshpb_lu { + int lun; + struct scsi_device *sdev_ufs_lu; + + spinlock_t rgn_state_lock; /* for protect rgn/srgn state */ + struct ufshpb_region *rgn_tbl; + + atomic_t hpb_state; + + spinlock_t rsp_list_lock; + struct list_head lh_act_srgn; /* hold rsp_list_lock */ + struct list_head lh_inact_rgn; /* hold rsp_list_lock */ + + /* pre request information */ + struct ufshpb_req *pre_req; + int num_inflight_pre_req; + int throttle_pre_req; + int num_inflight_map_req; + struct list_head lh_pre_req_free; + int cur_read_id; + int pre_req_min_tr_len; + int pre_req_max_tr_len; + + /* cached L2P map management worker */ + struct work_struct map_work; + + /* for selecting victim */ + struct victim_select_info lru_info; + struct work_struct ufshpb_normalization_work; + struct delayed_work ufshpb_read_to_work; + unsigned long work_data_bits; +#define TIMEOUT_WORK_RUNNING 0 + + /* pinned region information */ + u32 lu_pinned_start; + u32 lu_pinned_end; + + /* HPB related configuration */ + u32 rgns_per_lu; + u32 srgns_per_lu; + u32 last_srgn_entries; + int srgns_per_rgn; + u32 srgn_mem_size; + u32 entries_per_rgn_mask; + u32 entries_per_rgn_shift; + u32 entries_per_srgn; + u32 entries_per_srgn_mask; + u32 entries_per_srgn_shift; + u32 pages_per_srgn; + + bool is_hcm; + + struct ufshpb_stats stats; + struct ufshpb_params params; + + struct kmem_cache *map_req_cache; + struct kmem_cache *m_page_cache; + + struct list_head list_hpb_lu; +}; + +struct ufs_hba; +struct ufshcd_lrb; + +#ifndef CONFIG_SCSI_UFS_HPB +static int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { return 0; } +static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {} +static void ufshpb_resume(struct ufs_hba *hba) {} +static void ufshpb_suspend(struct ufs_hba *hba) {} +static void ufshpb_reset(struct ufs_hba *hba) {} +static void ufshpb_reset_host(struct ufs_hba *hba) {} +static void ufshpb_init(struct ufs_hba *hba) {} +static void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) {} +static void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) {} +static void ufshpb_remove(struct ufs_hba *hba) {} +static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; } +static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {} +static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {} +static bool ufshpb_is_legacy(struct ufs_hba *hba) { return false; } +#else +int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); +void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp); +void ufshpb_resume(struct ufs_hba *hba); +void ufshpb_suspend(struct ufs_hba *hba); +void ufshpb_reset(struct ufs_hba *hba); +void ufshpb_reset_host(struct ufs_hba *hba); +void ufshpb_init(struct ufs_hba *hba); +void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev); +void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev); +void ufshpb_remove(struct ufs_hba *hba); +bool ufshpb_is_allowed(struct ufs_hba *hba); +void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf); +void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf); +bool ufshpb_is_legacy(struct ufs_hba *hba); +extern struct attribute_group ufs_sysfs_hpb_stat_group; +extern struct attribute_group ufs_sysfs_hpb_param_group; +#endif + +#endif /* End of Header */ diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 10b4be1f3e78..05e47ce9657d 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -894,6 +894,8 @@ static void ashmem_show_fdinfo(struct seq_file *m, struct file *file) seq_printf(m, "name:\t%s\n", asma->name + ASHMEM_NAME_PREFIX_LEN); + seq_printf(m, "size:\t%zu\n", asma->size); + mutex_unlock(&ashmem_mutex); } #endif @@ -913,6 +915,15 @@ static const struct file_operations ashmem_fops = { #endif }; +/* + * is_ashmem_file - Check if struct file* is associated with ashmem + */ +int is_ashmem_file(struct file *file) +{ + return file->f_op == &ashmem_fops; +} +EXPORT_SYMBOL_GPL(is_ashmem_file); + static struct miscdevice ashmem_misc = { .minor = MISC_DYNAMIC_MINOR, .name = "ashmem", diff --git a/drivers/staging/android/ashmem.h b/drivers/staging/android/ashmem.h index 1a478173cd21..9fa72ed7b7ed 100644 --- a/drivers/staging/android/ashmem.h +++ b/drivers/staging/android/ashmem.h @@ -21,4 +21,6 @@ #define COMPAT_ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned int) #endif +int is_ashmem_file(struct file *file); + #endif /* _LINUX_ASHMEM_H */ diff --git a/drivers/staging/android/debug_kinfo.c b/drivers/staging/android/debug_kinfo.c index ca10756a040f..0a8d4deeb6dc 100644 --- a/drivers/staging/android/debug_kinfo.c +++ b/drivers/staging/android/debug_kinfo.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "debug_kinfo.h" /* @@ -162,7 +163,13 @@ static int debug_kinfo_probe(struct platform_device *pdev) info->mod_core_layout_offset = offsetof(struct module, core_layout); info->mod_init_layout_offset = offsetof(struct module, init_layout); info->mod_kallsyms_offset = offsetof(struct module, kallsyms); - +#if defined(CONFIG_MODULES) && defined(MODULES_VADDR) + info->module_start_va = MODULES_VADDR; + info->module_end_va = MODULES_END; +#else + info->module_start_va = VMALLOC_START; + info->module_end_va = VMALLOC_END; +#endif update_kernel_all_info(all_info); return 0; diff --git a/drivers/staging/android/debug_kinfo.h b/drivers/staging/android/debug_kinfo.h index 1af4ace4796c..921f140ce027 100644 --- a/drivers/staging/android/debug_kinfo.h +++ b/drivers/staging/android/debug_kinfo.h @@ -58,6 +58,8 @@ struct kernel_info { __u32 mod_core_layout_offset; __u32 mod_init_layout_offset; __u32 mod_kallsyms_offset; + __u64 module_start_va; + __u64 module_end_va; } __packed; struct kernel_all_info { diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 4dfa44d6cc3c..6253dce08cc6 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -34,6 +34,7 @@ #include "usb.h" +#include /* * Adds a new dynamic USBdevice ID to this driver, @@ -1403,11 +1404,16 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) int status = 0; int i = 0, n = 0; struct usb_interface *intf; + int bypass = 0; if (udev->state == USB_STATE_NOTATTACHED || udev->state == USB_STATE_SUSPENDED) goto done; + trace_android_vh_usb_dev_suspend(udev, msg, &bypass); + if (bypass) + goto done; + /* Suspend all the interfaces and then udev itself */ if (udev->actconfig) { n = udev->actconfig->desc.bNumInterfaces; @@ -1504,11 +1510,17 @@ static int usb_resume_both(struct usb_device *udev, pm_message_t msg) int status = 0; int i; struct usb_interface *intf; + int bypass = 0; if (udev->state == USB_STATE_NOTATTACHED) { status = -ENODEV; goto done; } + + trace_android_vh_usb_dev_resume(udev, msg, &bypass); + if (bypass) + goto done; + udev->can_submit = 1; /* Resume the device */ diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 7fd7f1b8fda0..1fd8a5dc7d09 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1267,6 +1267,7 @@ static void dwc3_get_properties(struct dwc3 *dwc) u8 rx_max_burst_prd; u8 tx_thr_num_pkt_prd; u8 tx_max_burst_prd; + u8 tx_fifo_resize_max_num; const char *usb_psy_name; int ret; @@ -1282,6 +1283,13 @@ static void dwc3_get_properties(struct dwc3 *dwc) */ hird_threshold = 12; + /* + * default to a TXFIFO size large enough to fit 6 max packets. This + * allows for systems with larger bus latencies to have some headroom + * for endpoints that have a large bMaxBurst value. + */ + tx_fifo_resize_max_num = 6; + dwc->maximum_speed = usb_get_maximum_speed(dev); dwc->max_ssp_rate = usb_get_maximum_ssp_rate(dev); dwc->dr_mode = usb_get_dr_mode(dev); @@ -1325,6 +1333,11 @@ static void dwc3_get_properties(struct dwc3 *dwc) &tx_thr_num_pkt_prd); device_property_read_u8(dev, "snps,tx-max-burst-prd", &tx_max_burst_prd); + dwc->do_fifo_resize = device_property_read_bool(dev, + "tx-fifo-resize"); + if (dwc->do_fifo_resize) + device_property_read_u8(dev, "tx-fifo-max-num", + &tx_fifo_resize_max_num); dwc->disable_scramble_quirk = device_property_read_bool(dev, "snps,disable_scramble_quirk"); @@ -1390,6 +1403,8 @@ static void dwc3_get_properties(struct dwc3 *dwc) dwc->tx_max_burst_prd = tx_max_burst_prd; dwc->imod_interval = 0; + + dwc->tx_fifo_resize_max_num = tx_fifo_resize_max_num; } /* check whether the core supports IMOD */ diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 45fbc933dc20..07d70418b7bd 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -879,8 +879,6 @@ struct dwc3_hwparams { /* HWPARAMS0 */ #define DWC3_MODE(n) ((n) & 0x7) -#define DWC3_MDWIDTH(n) (((n) & 0xff00) >> 8) - /* HWPARAMS1 */ #define DWC3_NUM_INT(n) (((n) & (0x3f << 15)) >> 15) @@ -1040,6 +1038,7 @@ struct dwc3_scratchpad_array { * @rx_max_burst_prd: max periodic ESS receive burst size * @tx_thr_num_pkt_prd: periodic ESS transmit packet count * @tx_max_burst_prd: max periodic ESS transmit burst size + * @tx_fifo_resize_max_num: max number of fifos allocated during txfifo resize * @hsphy_interface: "utmi" or "ulpi" * @connected: true when we're connected to a host, false otherwise * @delayed_status: true when gadget driver asks for delayed status @@ -1054,6 +1053,7 @@ struct dwc3_scratchpad_array { * 1 - utmi_l1_suspend_n * @is_fpga: true when we are using the FPGA board * @pending_events: true when we have pending IRQs to be handled + * @do_fifo_resize: true when txfifo resizing is enabled for dwc3 endpoints * @pullups_connected: true when Run/Stop bit is set * @setup_packet_pending: true when there's a Setup Packet in FIFO. Workaround * @three_stage_setup: set if we perform a three phase setup @@ -1096,6 +1096,11 @@ struct dwc3_scratchpad_array { * @dis_split_quirk: set to disable split boundary. * @imod_interval: set the interrupt moderation interval in 250ns * increments or 0 to disable. + * @max_cfg_eps: current max number of IN eps used across all USB configs. + * @last_fifo_depth: last fifo depth used to determine next fifo ram start + * address. + * @num_ep_resized: carries the current number endpoints which have had its tx + * fifo resized. */ struct dwc3 { struct work_struct drd_work; @@ -1251,6 +1256,7 @@ struct dwc3 { u8 rx_max_burst_prd; u8 tx_thr_num_pkt_prd; u8 tx_max_burst_prd; + u8 tx_fifo_resize_max_num; const char *hsphy_interface; @@ -1264,6 +1270,7 @@ struct dwc3 { unsigned is_utmi_l1_suspend:1; unsigned is_fpga:1; unsigned pending_events:1; + unsigned do_fifo_resize:1; unsigned pullups_connected:1; unsigned setup_packet_pending:1; unsigned three_stage_setup:1; @@ -1297,9 +1304,14 @@ struct dwc3 { unsigned dis_metastability_quirk:1; unsigned dis_split_quirk:1; + unsigned async_callbacks:1; u16 imod_interval; + int max_cfg_eps; + int last_fifo_depth; + int num_ep_resized; + ANDROID_KABI_RESERVE(1); ANDROID_KABI_RESERVE(2); ANDROID_KABI_RESERVE(3); @@ -1493,6 +1505,23 @@ u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type); (!(_ip##_VERSIONTYPE_##_to) || \ dwc->version_type <= _ip##_VERSIONTYPE_##_to)) +/** + * dwc3_mdwidth - get MDWIDTH value in bits + * @dwc: pointer to our context structure + * + * Return MDWIDTH configuration value in bits. + */ +static inline u32 dwc3_mdwidth(struct dwc3 *dwc) +{ + u32 mdwidth; + + mdwidth = DWC3_GHWPARAMS0_MDWIDTH(dwc->hwparams.hwparams0); + if (DWC3_IP_IS(DWC32)) + mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); + + return mdwidth; +} + bool dwc3_has_imod(struct dwc3 *dwc); int dwc3_event_buffers_setup(struct dwc3 *dwc); @@ -1519,6 +1548,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd, u32 param); void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt); +void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc); #else static inline int dwc3_gadget_init(struct dwc3 *dwc) { return 0; } @@ -1541,6 +1571,8 @@ static inline int dwc3_send_gadget_generic_command(struct dwc3 *dwc, static inline void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool interrupt) { } +static inline void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc) +{ } #endif #if IS_ENABLED(CONFIG_USB_DWC3_DUAL_ROLE) diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 3ebe3e6c284d..23f4682ad104 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -638,16 +638,14 @@ static int dwc3_tx_fifo_size_show(struct seq_file *s, void *unused) struct dwc3_ep *dep = s->private; struct dwc3 *dwc = dep->dwc; unsigned long flags; - int mdwidth; + u32 mdwidth; u32 val; spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_TXFIFO); /* Convert to bytes */ - mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); - if (DWC3_IP_IS(DWC32)) - mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); + mdwidth = dwc3_mdwidth(dwc); val *= mdwidth; val >>= 3; @@ -662,16 +660,14 @@ static int dwc3_rx_fifo_size_show(struct seq_file *s, void *unused) struct dwc3_ep *dep = s->private; struct dwc3 *dwc = dep->dwc; unsigned long flags; - int mdwidth; + u32 mdwidth; u32 val; spin_lock_irqsave(&dwc->lock, flags); val = dwc3_core_fifo_space(dep, DWC3_RXFIFO); /* Convert to bytes */ - mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); - if (DWC3_IP_IS(DWC32)) - mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); + mdwidth = dwc3_mdwidth(dwc); val *= mdwidth; val >>= 3; diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c index 8bd077fb1190..a47af6082cc4 100644 --- a/drivers/usb/dwc3/dwc3-qcom.c +++ b/drivers/usb/dwc3/dwc3-qcom.c @@ -640,6 +640,7 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev) struct dwc3_qcom *qcom = platform_get_drvdata(pdev); struct device_node *np = pdev->dev.of_node, *dwc3_np; struct device *dev = &pdev->dev; + struct property *prop; int ret; dwc3_np = of_get_child_by_name(np, "dwc3"); @@ -648,6 +649,20 @@ static int dwc3_qcom_of_register_core(struct platform_device *pdev) return -ENODEV; } + prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL); + if (!prop) { + ret = -ENOMEM; + dev_err(dev, "unable to allocate memory for property\n"); + goto node_put; + } + + prop->name = "tx-fifo-resize"; + ret = of_add_property(dwc3_np, prop); + if (ret) { + dev_err(dev, "unable to add property\n"); + goto node_put; + } + ret = of_platform_populate(np, NULL, NULL, dev); if (ret) { dev_err(dev, "failed to register dwc3 core - %d\n", ret); diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 8b668ef46f7f..0c7e6eae940f 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -594,11 +594,13 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) static int dwc3_ep0_delegate_req(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) { - int ret; + int ret = -EINVAL; - spin_unlock(&dwc->lock); - ret = dwc->gadget_driver->setup(dwc->gadget, ctrl); - spin_lock(&dwc->lock); + if (dwc->async_callbacks) { + spin_unlock(&dwc->lock); + ret = dwc->gadget_driver->setup(dwc->gadget, ctrl); + spin_lock(&dwc->lock); + } return ret; } @@ -616,6 +618,8 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) return -EINVAL; case USB_STATE_ADDRESS: + dwc3_gadget_clear_tx_fifos(dwc); + ret = dwc3_ep0_delegate_req(dwc, ctrl); /* if the cfg matches and the cfg is non zero */ if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) { diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index f91cb42dc067..2b8377dbbab5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -629,6 +629,187 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action) return dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_SETEPCONFIG, ¶ms); } +/** + * dwc3_gadget_calc_tx_fifo_size - calculates the txfifo size value + * @dwc: pointer to the DWC3 context + * @nfifos: number of fifos to calculate for + * + * Calculates the size value based on the equation below: + * + * DWC3 revision 280A and prior: + * fifo_size = mult * (max_packet / mdwidth) + 1; + * + * DWC3 revision 290A and onwards: + * fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1 + * + * The max packet size is set to 1024, as the txfifo requirements mainly apply + * to super speed USB use cases. However, it is safe to overestimate the fifo + * allocations for other scenarios, i.e. high speed USB. + */ +static int dwc3_gadget_calc_tx_fifo_size(struct dwc3 *dwc, int mult) +{ + int max_packet = 1024; + int fifo_size; + int mdwidth; + + mdwidth = dwc3_mdwidth(dwc); + + /* MDWIDTH is represented in bits, we need it in bytes */ + mdwidth >>= 3; + + if (DWC3_VER_IS_PRIOR(DWC3, 290A)) + fifo_size = mult * (max_packet / mdwidth) + 1; + else + fifo_size = mult * ((max_packet + mdwidth) / mdwidth) + 1; + return fifo_size; +} + +/** + * dwc3_gadget_clear_tx_fifo_size - Clears txfifo allocation + * @dwc: pointer to the DWC3 context + * + * Iterates through all the endpoint registers and clears the previous txfifo + * allocations. + */ +void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc) +{ + struct dwc3_ep *dep; + int fifo_depth; + int size; + int num; + + if (!dwc->do_fifo_resize) + return; + + /* Read ep0IN related TXFIFO size */ + dep = dwc->eps[1]; + size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0)); + if (DWC3_IP_IS(DWC3)) + fifo_depth = DWC3_GTXFIFOSIZ_TXFDEP(size); + else + fifo_depth = DWC31_GTXFIFOSIZ_TXFDEP(size); + + dwc->last_fifo_depth = fifo_depth; + /* Clear existing TXFIFO for all IN eps except ep0 */ + for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); + num += 2) { + dep = dwc->eps[num]; + /* Don't change TXFRAMNUM on usb31 version */ + size = DWC3_IP_IS(DWC3) ? 0 : + dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) & + DWC31_GTXFIFOSIZ_TXFRAMNUM; + + dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1), size); + } + dwc->num_ep_resized = 0; +} + +/* + * dwc3_gadget_resize_tx_fifos - reallocate fifo spaces for current use-case + * @dwc: pointer to our context structure + * + * This function will a best effort FIFO allocation in order + * to improve FIFO usage and throughput, while still allowing + * us to enable as many endpoints as possible. + * + * Keep in mind that this operation will be highly dependent + * on the configured size for RAM1 - which contains TxFifo -, + * the amount of endpoints enabled on coreConsultant tool, and + * the width of the Master Bus. + * + * In general, FIFO depths are represented with the following equation: + * + * fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1 + * + * In conjunction with dwc3_gadget_check_config(), this resizing logic will + * ensure that all endpoints will have enough internal memory for one max + * packet per endpoint. + */ +static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) +{ + struct dwc3 *dwc = dep->dwc; + int fifo_0_start; + int ram1_depth; + int fifo_size; + int min_depth; + int num_in_ep; + int remaining; + int num_fifos = 1; + int fifo; + int tmp; + + if (!dwc->do_fifo_resize) + return 0; + + /* resize IN endpoints except ep0 */ + if (!usb_endpoint_dir_in(dep->endpoint.desc) || dep->number <= 1) + return 0; + + ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); + + if ((dep->endpoint.maxburst > 1 && + usb_endpoint_xfer_bulk(dep->endpoint.desc)) || + usb_endpoint_xfer_isoc(dep->endpoint.desc)) + num_fifos = 3; + + if (dep->endpoint.maxburst > 6 && + usb_endpoint_xfer_bulk(dep->endpoint.desc) && DWC3_IP_IS(DWC31)) + num_fifos = dwc->tx_fifo_resize_max_num; + + /* FIFO size for a single buffer */ + fifo = dwc3_gadget_calc_tx_fifo_size(dwc, 1); + + /* Calculate the number of remaining EPs w/o any FIFO */ + num_in_ep = dwc->max_cfg_eps; + num_in_ep -= dwc->num_ep_resized; + + /* Reserve at least one FIFO for the number of IN EPs */ + min_depth = num_in_ep * (fifo + 1); + remaining = ram1_depth - min_depth - dwc->last_fifo_depth; + remaining = max_t(int, 0, remaining); + /* + * We've already reserved 1 FIFO per EP, so check what we can fit in + * addition to it. If there is not enough remaining space, allocate + * all the remaining space to the EP. + */ + fifo_size = (num_fifos - 1) * fifo; + if (remaining < fifo_size) + fifo_size = remaining; + + fifo_size += fifo; + /* Last increment according to the TX FIFO size equation */ + fifo_size++; + + /* Check if TXFIFOs start at non-zero addr */ + tmp = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0)); + fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(tmp); + + fifo_size |= (fifo_0_start + (dwc->last_fifo_depth << 16)); + if (DWC3_IP_IS(DWC3)) + dwc->last_fifo_depth += DWC3_GTXFIFOSIZ_TXFDEP(fifo_size); + else + dwc->last_fifo_depth += DWC31_GTXFIFOSIZ_TXFDEP(fifo_size); + + /* Check fifo size allocation doesn't exceed available RAM size. */ + if (dwc->last_fifo_depth >= ram1_depth) { + dev_err(dwc->dev, "Fifosize(%d) > RAM size(%d) %s depth:%d\n", + dwc->last_fifo_depth, ram1_depth, + dep->endpoint.name, fifo_size); + if (DWC3_IP_IS(DWC3)) + fifo_size = DWC3_GTXFIFOSIZ_TXFDEP(fifo_size); + else + fifo_size = DWC31_GTXFIFOSIZ_TXFDEP(fifo_size); + + dwc->last_fifo_depth -= fifo_size; + return -ENOMEM; + } + + dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size); + dwc->num_ep_resized++; + + return 0; +} + /** * __dwc3_gadget_ep_enable - initializes a hw endpoint * @dep: endpoint to be initialized @@ -646,6 +827,10 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) int ret; if (!(dep->flags & DWC3_EP_ENABLED)) { + ret = dwc3_gadget_resize_tx_fifos(dep); + if (ret) + return ret; + ret = dwc3_gadget_start_config(dep); if (ret) return ret; @@ -2246,6 +2431,17 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on) } } + /* + * Avoid issuing a runtime resume if the device is already in the + * suspended state during gadget disconnect. DWC3 gadget was already + * halted/stopped during runtime suspend. + */ + if (!is_on) { + pm_runtime_barrier(dwc->dev); + if (pm_runtime_suspended(dwc->dev)) + return 0; + } + /* * Check the return value for successful resume, or error. For a * successful resume, the DWC3 runtime PM resume routine will handle @@ -2367,9 +2563,7 @@ static void dwc3_gadget_setup_nump(struct dwc3 *dwc) u32 reg; ram2_depth = DWC3_GHWPARAMS7_RAM2_DEPTH(dwc->hwparams.hwparams7); - mdwidth = DWC3_GHWPARAMS0_MDWIDTH(dwc->hwparams.hwparams0); - if (DWC3_IP_IS(DWC32)) - mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); + mdwidth = dwc3_mdwidth(dwc); nump = ((ram2_depth * mdwidth / 8) - 24 - 16) / 1024; nump = min_t(u32, nump, 16); @@ -2512,6 +2706,7 @@ static int dwc3_gadget_stop(struct usb_gadget *g) spin_lock_irqsave(&dwc->lock, flags); dwc->gadget_driver = NULL; + dwc->max_cfg_eps = 0; spin_unlock_irqrestore(&dwc->lock, flags); free_irq(dwc->irq_gadget, dwc->ev_buf); @@ -2599,6 +2794,61 @@ static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA) return ret; } +/** + * dwc3_gadget_check_config - ensure dwc3 can support the USB configuration + * @g: pointer to the USB gadget + * + * Used to record the maximum number of endpoints being used in a USB composite + * device. (across all configurations) This is to be used in the calculation + * of the TXFIFO sizes when resizing internal memory for individual endpoints. + * It will help ensured that the resizing logic reserves enough space for at + * least one max packet. + */ +static int dwc3_gadget_check_config(struct usb_gadget *g) +{ + struct dwc3 *dwc = gadget_to_dwc(g); + struct usb_ep *ep; + int fifo_size = 0; + int ram1_depth; + int ep_num = 0; + + if (!dwc->do_fifo_resize) + return 0; + + list_for_each_entry(ep, &g->ep_list, ep_list) { + /* Only interested in the IN endpoints */ + if (ep->claimed && (ep->address & USB_DIR_IN)) + ep_num++; + } + + if (ep_num <= dwc->max_cfg_eps) + return 0; + + /* Update the max number of eps in the composition */ + dwc->max_cfg_eps = ep_num; + + fifo_size = dwc3_gadget_calc_tx_fifo_size(dwc, dwc->max_cfg_eps); + /* Based on the equation, increment by one for every ep */ + fifo_size += dwc->max_cfg_eps; + + /* Check if we can fit a single fifo per endpoint */ + ram1_depth = DWC3_RAM1_DEPTH(dwc->hwparams.hwparams7); + if (fifo_size > ram1_depth) + return -ENOMEM; + + return 0; +} + +static void dwc3_gadget_async_callbacks(struct usb_gadget *g, bool enable) +{ + struct dwc3 *dwc = gadget_to_dwc(g); + unsigned long flags; + + spin_lock_irqsave(&dwc->lock, flags); + dwc->async_callbacks = enable; + spin_unlock_irqrestore(&dwc->lock, flags); +} + static const struct usb_gadget_ops dwc3_gadget_ops = { .get_frame = dwc3_gadget_get_frame, .wakeup = dwc3_gadget_wakeup, @@ -2610,6 +2860,8 @@ static const struct usb_gadget_ops dwc3_gadget_ops = { .udc_set_ssp_rate = dwc3_gadget_set_ssp_rate, .get_config_params = dwc3_gadget_config_params, .vbus_draw = dwc3_gadget_vbus_draw, + .check_config = dwc3_gadget_check_config, + .udc_async_callbacks = dwc3_gadget_async_callbacks, }; /* -------------------------------------------------------------------------- */ @@ -2632,12 +2884,10 @@ static int dwc3_gadget_init_control_endpoint(struct dwc3_ep *dep) static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) { struct dwc3 *dwc = dep->dwc; - int mdwidth; + u32 mdwidth; int size; - mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); - if (DWC3_IP_IS(DWC32)) - mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); + mdwidth = dwc3_mdwidth(dwc); /* MDWIDTH is represented in bits, we need it in bytes */ mdwidth /= 8; @@ -2679,12 +2929,10 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep) { struct dwc3 *dwc = dep->dwc; - int mdwidth; + u32 mdwidth; int size; - mdwidth = DWC3_MDWIDTH(dwc->hwparams.hwparams0); - if (DWC3_IP_IS(DWC32)) - mdwidth += DWC3_GHWPARAMS6_MDWIDTH(dwc->hwparams.hwparams6); + mdwidth = dwc3_mdwidth(dwc); /* MDWIDTH is represented in bits, convert to bytes */ mdwidth /= 8; @@ -3247,7 +3495,7 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, static void dwc3_disconnect_gadget(struct dwc3 *dwc) { - if (dwc->gadget_driver && dwc->gadget_driver->disconnect) { + if (dwc->async_callbacks && dwc->gadget_driver->disconnect) { spin_unlock(&dwc->lock); dwc->gadget_driver->disconnect(dwc->gadget); spin_lock(&dwc->lock); @@ -3256,7 +3504,7 @@ static void dwc3_disconnect_gadget(struct dwc3 *dwc) static void dwc3_suspend_gadget(struct dwc3 *dwc) { - if (dwc->gadget_driver && dwc->gadget_driver->suspend) { + if (dwc->async_callbacks && dwc->gadget_driver->suspend) { spin_unlock(&dwc->lock); dwc->gadget_driver->suspend(dwc->gadget); spin_lock(&dwc->lock); @@ -3265,7 +3513,7 @@ static void dwc3_suspend_gadget(struct dwc3 *dwc) static void dwc3_resume_gadget(struct dwc3 *dwc) { - if (dwc->gadget_driver && dwc->gadget_driver->resume) { + if (dwc->async_callbacks && dwc->gadget_driver->resume) { spin_unlock(&dwc->lock); dwc->gadget_driver->resume(dwc->gadget); spin_lock(&dwc->lock); @@ -3277,7 +3525,7 @@ static void dwc3_reset_gadget(struct dwc3 *dwc) if (!dwc->gadget_driver) return; - if (dwc->gadget->speed != USB_SPEED_UNKNOWN) { + if (dwc->async_callbacks && dwc->gadget->speed != USB_SPEED_UNKNOWN) { spin_unlock(&dwc->lock); usb_gadget_udc_reset(dwc->gadget, dwc->gadget_driver); spin_lock(&dwc->lock); @@ -3607,7 +3855,7 @@ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc) * implemented. */ - if (dwc->gadget_driver && dwc->gadget_driver->resume) { + if (dwc->async_callbacks && dwc->gadget_driver->resume) { spin_unlock(&dwc->lock); dwc->gadget_driver->resume(dwc->gadget); spin_lock(&dwc->lock); diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 72a9797dbbae..504c1cbc255d 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -482,7 +482,7 @@ static u8 encode_bMaxPower(enum usb_device_speed speed, { unsigned val; - if (c->MaxPower) + if (c->MaxPower || (c->bmAttributes & USB_CONFIG_ATT_SELFPOWER)) val = c->MaxPower; else val = CONFIG_USB_GADGET_VBUS_DRAW; @@ -936,7 +936,11 @@ static int set_config(struct usb_composite_dev *cdev, } /* when we return, be sure our power usage is valid */ - power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW; + if (c->MaxPower || (c->bmAttributes & USB_CONFIG_ATT_SELFPOWER)) + power = c->MaxPower; + else + power = CONFIG_USB_GADGET_VBUS_DRAW; + if (gadget->speed < USB_SPEED_SUPER) power = min(power, 500U); else diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 13cd4a21a2c9..18a096cac111 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -1439,6 +1439,10 @@ static int configfs_composite_bind(struct usb_gadget *gadget, goto err_purge_funcs; } } + ret = usb_gadget_check_config(cdev->gadget); + if (ret) + goto err_purge_funcs; + usb_ep_autoconfig_reset(cdev->gadget); } if (cdev->use_os_string) { @@ -1537,19 +1541,29 @@ static void configfs_composite_unbind(struct usb_gadget *gadget) static int android_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *c) { - struct usb_composite_dev *cdev = get_gadget_data(gadget); + struct usb_composite_dev *cdev; unsigned long flags; - struct gadget_info *gi = container_of(cdev, struct gadget_info, cdev); + struct gadget_info *gi; int value = -EOPNOTSUPP; struct usb_function_instance *fi; - spin_lock_irqsave(&cdev->lock, flags); + if (!android_device) + return 0; + + gi = dev_get_drvdata(android_device); + spin_lock_irqsave(&gi->spinlock, flags); + cdev = get_gadget_data(gadget); + if (!cdev || gi->unbind) { + spin_unlock_irqrestore(&gi->spinlock, flags); + return 0; + } + if (c->bRequest == USB_REQ_GET_DESCRIPTOR && (c->wValue >> 8) == USB_DT_CONFIG && !gi->connected) { gi->connected = 1; schedule_work(&gi->work); } - spin_unlock_irqrestore(&cdev->lock, flags); + list_for_each_entry(fi, &gi->available_func, cfs_list) { if (fi != NULL && fi->f != NULL && fi->f->setup != NULL) { value = fi->f->setup(fi->f, c); @@ -1566,12 +1580,11 @@ static int android_setup(struct usb_gadget *gadget, if (value < 0) value = composite_setup(gadget, c); - spin_lock_irqsave(&cdev->lock, flags); if (c->bRequest == USB_REQ_SET_CONFIGURATION && cdev->config) { schedule_work(&gi->work); } - spin_unlock_irqrestore(&cdev->lock, flags); + spin_unlock_irqrestore(&gi->spinlock, flags); return value; } diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index f0b839803ba1..dbd537b8ffcd 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1006,6 +1006,25 @@ int usb_gadget_ep_match_desc(struct usb_gadget *gadget, } EXPORT_SYMBOL_GPL(usb_gadget_ep_match_desc); +/** + * usb_gadget_check_config - checks if the UDC can support the binded + * configuration + * @gadget: controller to check the USB configuration + * + * Ensure that a UDC is able to support the requested resources by a + * configuration, and that there are no resource limitations, such as + * internal memory allocated to all requested endpoints. + * + * Returns zero on success, else a negative errno. + */ +int usb_gadget_check_config(struct usb_gadget *gadget) +{ + if (gadget->ops->check_config) + return gadget->ops->check_config(gadget); + return 0; +} +EXPORT_SYMBOL_GPL(usb_gadget_check_config); + /* ------------------------------------------------------------------------- */ static void usb_gadget_state_work(struct work_struct *work) @@ -1150,6 +1169,53 @@ static inline void usb_gadget_udc_set_speed(struct usb_udc *udc, gadget->ops->udc_set_speed(gadget, s); } +/** + * usb_gadget_enable_async_callbacks - tell usb device controller to enable asynchronous callbacks + * @udc: The UDC which should enable async callbacks + * + * This routine is used when binding gadget drivers. It undoes the effect + * of usb_gadget_disable_async_callbacks(); the UDC driver should enable IRQs + * (if necessary) and resume issuing callbacks. + * + * This routine will always be called in process context. + */ +static inline void usb_gadget_enable_async_callbacks(struct usb_udc *udc) +{ + struct usb_gadget *gadget = udc->gadget; + + if (gadget->ops->udc_async_callbacks) + gadget->ops->udc_async_callbacks(gadget, true); +} + +/** + * usb_gadget_disable_async_callbacks - tell usb device controller to disable asynchronous callbacks + * @udc: The UDC which should disable async callbacks + * + * This routine is used when unbinding gadget drivers. It prevents a race: + * The UDC driver doesn't know when the gadget driver's ->unbind callback + * runs, so unless it is told to disable asynchronous callbacks, it might + * issue a callback (such as ->disconnect) after the unbind has completed. + * + * After this function runs, the UDC driver must suppress all ->suspend, + * ->resume, ->disconnect, ->reset, and ->setup callbacks to the gadget driver + * until async callbacks are again enabled. A simple-minded but effective + * way to accomplish this is to tell the UDC hardware not to generate any + * more IRQs. + * + * Request completion callbacks must still be issued. However, it's okay + * to defer them until the request is cancelled, since the pull-up will be + * turned off during the time period when async callbacks are disabled. + * + * This routine will always be called in process context. + */ +static inline void usb_gadget_disable_async_callbacks(struct usb_udc *udc) +{ + struct usb_gadget *gadget = udc->gadget; + + if (gadget->ops->udc_async_callbacks) + gadget->ops->udc_async_callbacks(gadget, false); +} + /** * usb_udc_release - release the usb_udc struct * @dev: the dev member within usb_udc @@ -1364,6 +1430,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); usb_gadget_disconnect(udc->gadget); + usb_gadget_disable_async_callbacks(udc); if (udc->gadget->irq) synchronize_irq(udc->gadget->irq); udc->driver->unbind(udc->gadget); @@ -1445,6 +1512,7 @@ static int udc_bind_to_driver(struct usb_udc *udc, struct usb_gadget_driver *dri driver->unbind(udc->gadget); goto err1; } + usb_gadget_enable_async_callbacks(udc); usb_udc_connect_control(udc); kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE); diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index ea5e34b49df3..21280a6d589e 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -199,11 +199,10 @@ EXPORT_SYMBOL_GPL(xhci_plat_register_vendor_ops); static int xhci_vendor_init(struct xhci_hcd *xhci) { - struct xhci_vendor_ops *ops = xhci_vendor_get_ops(xhci); - struct xhci_plat_priv *priv = xhci_to_priv(xhci); + struct xhci_vendor_ops *ops = NULL; if (xhci_plat_vendor_overwrite.vendor_ops) - ops = priv->vendor_ops = xhci_plat_vendor_overwrite.vendor_ops; + ops = xhci->vendor_ops = xhci_plat_vendor_overwrite.vendor_ops; if (ops && ops->vendor_init) return ops->vendor_init(xhci); @@ -213,12 +212,11 @@ static int xhci_vendor_init(struct xhci_hcd *xhci) static void xhci_vendor_cleanup(struct xhci_hcd *xhci) { struct xhci_vendor_ops *ops = xhci_vendor_get_ops(xhci); - struct xhci_plat_priv *priv = xhci_to_priv(xhci); if (ops && ops->vendor_cleanup) ops->vendor_cleanup(xhci); - priv->vendor_ops = NULL; + xhci->vendor_ops = NULL; } static int xhci_plat_probe(struct platform_device *pdev) diff --git a/drivers/usb/host/xhci-plat.h b/drivers/usb/host/xhci-plat.h index 5b096f72636f..e726a572321d 100644 --- a/drivers/usb/host/xhci-plat.h +++ b/drivers/usb/host/xhci-plat.h @@ -13,7 +13,6 @@ struct xhci_plat_priv { const char *firmware_name; unsigned long long quirks; - struct xhci_vendor_ops *vendor_ops; struct xhci_vendor_data *vendor_data; int (*plat_setup)(struct usb_hcd *); void (*plat_start)(struct usb_hcd *); diff --git a/drivers/usb/host/xhci-trace.c b/drivers/usb/host/xhci-trace.c index d0070814d1ea..c4178357bd92 100644 --- a/drivers/usb/host/xhci-trace.c +++ b/drivers/usb/host/xhci-trace.c @@ -12,3 +12,6 @@ #include "xhci-trace.h" EXPORT_TRACEPOINT_SYMBOL_GPL(xhci_dbg_quirks); +EXPORT_TRACEPOINT_SYMBOL_GPL(xhci_urb_enqueue); +EXPORT_TRACEPOINT_SYMBOL_GPL(xhci_handle_transfer); +EXPORT_TRACEPOINT_SYMBOL_GPL(xhci_urb_giveback); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index dabc8a8cd7be..cd2d7caf248a 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -22,7 +22,6 @@ #include "xhci-trace.h" #include "xhci-debugfs.h" #include "xhci-dbgcap.h" -#include "xhci-plat.h" #define DRIVER_AUTHOR "Sarah Sharp" #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" @@ -4317,7 +4316,7 @@ static int __maybe_unused xhci_change_max_exit_latency(struct xhci_hcd *xhci, struct xhci_vendor_ops *xhci_vendor_get_ops(struct xhci_hcd *xhci) { - return xhci_to_priv(xhci)->vendor_ops; + return xhci->vendor_ops; } EXPORT_SYMBOL_GPL(xhci_vendor_get_ops); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 64a658aae707..29327c567084 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1928,7 +1928,9 @@ struct xhci_hcd { void *dbc; - ANDROID_KABI_RESERVE(1); + /* Used for bug 194461020 */ + ANDROID_KABI_USE(1, struct xhci_vendor_ops *vendor_ops); + ANDROID_KABI_RESERVE(2); ANDROID_KABI_RESERVE(3); ANDROID_KABI_RESERVE(4); diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 8eb05b6cff85..8277c2907b8e 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "bus.h" @@ -20,6 +21,7 @@ struct typec_plug { enum typec_plug_index index; struct ida mode_ids; int num_altmodes; + ANDROID_KABI_RESERVE(1); }; struct typec_cable { @@ -28,6 +30,7 @@ struct typec_cable { struct usb_pd_identity *identity; unsigned int active:1; u16 pd_revision; /* 0300H = "3.0" */ + ANDROID_KABI_RESERVE(1); }; struct typec_partner { @@ -39,6 +42,7 @@ struct typec_partner { int num_altmodes; u16 pd_revision; /* 0300H = "3.0" */ enum usb_pd_svdm_ver svdm_version; + ANDROID_KABI_RESERVE(1); }; struct typec_port { @@ -60,6 +64,7 @@ struct typec_port { const struct typec_capability *cap; const struct typec_operations *ops; + ANDROID_KABI_RESERVE(1); }; #define to_typec_port(_dev_) container_of(_dev_, struct typec_port, dev) @@ -572,8 +577,10 @@ typec_register_altmode(struct device *parent, int ret; alt = kzalloc(sizeof(*alt), GFP_KERNEL); - if (!alt) + if (!alt) { + altmode_id_remove(parent, id); return ERR_PTR(-ENOMEM); + } alt->adev.svid = desc->svid; alt->adev.mode = desc->mode; diff --git a/drivers/usb/typec/tcpm/tcpci.c b/drivers/usb/typec/tcpm/tcpci.c index bb47e5adcffa..05aa15aaf26a 100644 --- a/drivers/usb/typec/tcpm/tcpci.c +++ b/drivers/usb/typec/tcpm/tcpci.c @@ -22,8 +22,12 @@ #define PD_RETRY_COUNT_DEFAULT 3 #define PD_RETRY_COUNT_3_0_OR_HIGHER 2 #define AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV 3500 -#define AUTO_DISCHARGE_PD_HEADROOM_MV 850 -#define AUTO_DISCHARGE_PPS_HEADROOM_MV 1250 +#define VSINKPD_MIN_IR_DROP_MV 750 +#define VSRC_NEW_MIN_PERCENT 95 +#define VSRC_VALID_MIN_MV 500 +#define VPPS_NEW_MIN_PERCENT 95 +#define VPPS_VALID_MIN_MV 100 +#define VSINKDISCONNECT_PD_MIN_PERCENT 90 #define tcpc_presenting_rd(reg, cc) \ (!(TCPC_ROLE_CTRL_DRP & (reg)) && \ @@ -364,11 +368,13 @@ static int tcpci_set_auto_vbus_discharge_threshold(struct tcpc_dev *dev, enum ty threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV; } else if (mode == TYPEC_PWR_MODE_PD) { if (pps_active) - threshold = (95 * requested_vbus_voltage_mv / 100) - - AUTO_DISCHARGE_PD_HEADROOM_MV; + threshold = ((VPPS_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) - + VSINKPD_MIN_IR_DROP_MV - VPPS_VALID_MIN_MV) * + VSINKDISCONNECT_PD_MIN_PERCENT / 100; else - threshold = (95 * requested_vbus_voltage_mv / 100) - - AUTO_DISCHARGE_PPS_HEADROOM_MV; + threshold = ((VSRC_NEW_MIN_PERCENT * requested_vbus_voltage_mv / 100) - + VSINKPD_MIN_IR_DROP_MV - VSRC_VALID_MIN_MV) * + VSINKDISCONNECT_PD_MIN_PERCENT / 100; } else { /* 3.5V for non-pd sink */ threshold = AUTO_DISCHARGE_DEFAULT_THRESHOLD_MV; diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 871ba0c42c82..50ab02c902a3 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -402,6 +402,8 @@ struct tcpm_port { unsigned int nr_src_pdo; u32 snk_pdo[PDO_MAX_OBJECTS]; unsigned int nr_snk_pdo; + u32 snk_vdo_v1[VDO_MAX_OBJECTS]; + unsigned int nr_snk_vdo_v1; u32 snk_vdo[VDO_MAX_OBJECTS]; unsigned int nr_snk_vdo; @@ -1611,18 +1613,16 @@ static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev, */ if ((port->data_role == TYPEC_DEVICE || svdm_version >= SVDM_VER_2_0) && port->nr_snk_vdo) { - /* - * Product Type DFP and Connector Type are not defined in SVDM - * version 1.0 and shall be set to zero. - */ - if (svdm_version < SVDM_VER_2_0) - response[1] = port->snk_vdo[0] & ~IDH_DFP_MASK - & ~IDH_CONN_MASK; - else - response[1] = port->snk_vdo[0]; - for (i = 1; i < port->nr_snk_vdo; i++) - response[i + 1] = port->snk_vdo[i]; - rlen = port->nr_snk_vdo + 1; + if (svdm_version < SVDM_VER_2_0) { + for (i = 0; i < port->nr_snk_vdo_v1; i++) + response[i + 1] = port->snk_vdo_v1[i]; + rlen = port->nr_snk_vdo_v1 + 1; + + } else { + for (i = 0; i < port->nr_snk_vdo; i++) + response[i + 1] = port->snk_vdo[i]; + rlen = port->nr_snk_vdo + 1; + } } break; case CMD_DISCOVER_SVID: @@ -2629,6 +2629,11 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, } else { next_state = SNK_WAIT_CAPABILITIES; } + + /* Threshold was relaxed before sending Request. Restore it back. */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); tcpm_set_state(port, next_state, 0); break; case SNK_NEGOTIATE_PPS_CAPABILITIES: @@ -2642,6 +2647,11 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, port->send_discover) port->vdm_sm_running = true; + /* Threshold was relaxed before sending Request. Restore it back. */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); + tcpm_set_state(port, SNK_READY, 0); break; case DR_SWAP_SEND: @@ -3361,6 +3371,12 @@ static int tcpm_pd_send_request(struct tcpm_port *port) if (ret < 0) return ret; + /* + * Relax the threshold as voltage will be adjusted after Accept Message plus tSrcTransition. + * It is safer to modify the threshold here. + */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0); + memset(&msg, 0, sizeof(msg)); msg.header = PD_HEADER_LE(PD_DATA_REQUEST, port->pwr_role, @@ -3458,6 +3474,9 @@ static int tcpm_pd_send_pps_request(struct tcpm_port *port) if (ret < 0) return ret; + /* Relax the threshold as voltage will be adjusted right after Accept Message. */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0); + memset(&msg, 0, sizeof(msg)); msg.header = PD_HEADER_LE(PD_DATA_REQUEST, port->pwr_role, @@ -4285,6 +4304,10 @@ static void run_state_machine(struct tcpm_port *port) port->hard_reset_count = 0; ret = tcpm_pd_send_request(port); if (ret < 0) { + /* Restore back to the original state */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); /* Let the Source send capabilities again. */ tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0); } else { @@ -4295,6 +4318,10 @@ static void run_state_machine(struct tcpm_port *port) case SNK_NEGOTIATE_PPS_CAPABILITIES: ret = tcpm_pd_send_pps_request(port); if (ret < 0) { + /* Restore back to the original state */ + tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD, + port->pps_data.active, + port->supply_voltage); port->pps_status = ret; /* * If this was called due to updates to sink @@ -5332,6 +5359,7 @@ static void _tcpm_pd_vbus_vsafe0v(struct tcpm_port *port) } break; case PR_SWAP_SNK_SRC_SINK_OFF: + case PR_SWAP_SNK_SRC_SOURCE_ON: /* Do nothing, vsafe0v is expected during transition */ break; default: @@ -5461,7 +5489,7 @@ EXPORT_SYMBOL_GPL(tcpm_pd_hard_reset); void tcpm_sink_frs(struct tcpm_port *port) { spin_lock(&port->pd_event_lock); - port->pd_events = TCPM_FRS_EVENT; + port->pd_events |= TCPM_FRS_EVENT; spin_unlock(&port->pd_event_lock); kthread_queue_work(port->wq, &port->event_work); } @@ -5470,7 +5498,7 @@ EXPORT_SYMBOL_GPL(tcpm_sink_frs); void tcpm_sourcing_vbus(struct tcpm_port *port) { spin_lock(&port->pd_event_lock); - port->pd_events = TCPM_SOURCING_VBUS; + port->pd_events |= TCPM_SOURCING_VBUS; spin_unlock(&port->pd_event_lock); kthread_queue_work(port->wq, &port->event_work); } @@ -6084,6 +6112,22 @@ static int tcpm_fw_get_caps(struct tcpm_port *port, return ret; } + /* If sink-vdos is found, sink-vdos-v1 is expected for backward compatibility. */ + if (port->nr_snk_vdo) { + ret = fwnode_property_count_u32(fwnode, "sink-vdos-v1"); + if (ret < 0) + return ret; + else if (ret == 0) + return -ENODATA; + + port->nr_snk_vdo_v1 = min(ret, VDO_MAX_OBJECTS); + ret = fwnode_property_read_u32_array(fwnode, "sink-vdos-v1", + port->snk_vdo_v1, + port->nr_snk_vdo_v1); + if (ret < 0) + return ret; + } + return 0; } diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c index 181e2f18beae..41bd84335b23 100644 --- a/drivers/virtio/virtio_mem.c +++ b/drivers/virtio/virtio_mem.c @@ -1307,11 +1307,12 @@ static int virtio_mem_mb_unplug_sb_online(struct virtio_mem *vm, const unsigned long nr_pages = PFN_DOWN(vm->subblock_size) * count; unsigned long start_pfn; int rc; + struct acr_info dummy; start_pfn = PFN_DOWN(virtio_mem_mb_id_to_phys(mb_id) + sb_id * vm->subblock_size); rc = alloc_contig_range(start_pfn, start_pfn + nr_pages, - MIGRATE_MOVABLE, GFP_KERNEL); + MIGRATE_MOVABLE, GFP_KERNEL, &dummy); if (rc == -ENOMEM) /* whoops, out of memory */ return rc; diff --git a/fs/OWNERS b/fs/OWNERS deleted file mode 100644 index a838344a1137..000000000000 --- a/fs/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/fs/OWNERS diff --git a/fs/f2fs/OWNERS b/fs/f2fs/OWNERS deleted file mode 100644 index f981f44fbffd..000000000000 --- a/fs/f2fs/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/fs/f2fs/OWNERS diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 3497bac4c53d..23d36de40317 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -691,6 +691,9 @@ int f2fs_recover_orphan_inodes(struct f2fs_sb_info *sbi) } #ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sbi->sb->s_flags |= SB_ACTIVE; + /* * Turn on quotas which were not enabled for read-only mounts if * filesystem has quota feature, so that they are updated correctly. diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 1c3e98085591..455561826c7d 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -12,9 +12,11 @@ #include #include #include +#include #include "f2fs.h" #include "node.h" +#include "segment.h" #include static struct kmem_cache *cic_entry_slab; @@ -736,7 +738,7 @@ static int f2fs_compress_pages(struct compress_ctx *cc) return ret; } -static void f2fs_decompress_cluster(struct decompress_io_ctx *dic) +void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { struct f2fs_sb_info *sbi = F2FS_I_SB(dic->inode); struct f2fs_inode_info *fi = F2FS_I(dic->inode); @@ -835,7 +837,8 @@ static void f2fs_decompress_cluster(struct decompress_io_ctx *dic) * page being waited on in the cluster, and if so, it decompresses the cluster * (or in the case of a failure, cleans up without actually decompressing). */ -void f2fs_end_read_compressed_page(struct page *page, bool failed) +void f2fs_end_read_compressed_page(struct page *page, bool failed, + block_t blkaddr) { struct decompress_io_ctx *dic = (struct decompress_io_ctx *)page_private(page); @@ -845,6 +848,9 @@ void f2fs_end_read_compressed_page(struct page *page, bool failed) if (failed) WRITE_ONCE(dic->failed, true); + else if (blkaddr) + f2fs_cache_compressed_page(sbi, page, + dic->inode->i_ino, blkaddr); if (atomic_dec_and_test(&dic->remaining_pages)) f2fs_decompress_cluster(dic); @@ -1660,6 +1666,164 @@ void f2fs_put_page_dic(struct page *page) f2fs_put_dic(dic); } +const struct address_space_operations f2fs_compress_aops = { + .releasepage = f2fs_release_page, + .invalidatepage = f2fs_invalidate_page, +}; + +struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi) +{ + return sbi->compress_inode->i_mapping; +} + +void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr) +{ + if (!sbi->compress_inode) + return; + invalidate_mapping_pages(COMPRESS_MAPPING(sbi), blkaddr, blkaddr); +} + +void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + nid_t ino, block_t blkaddr) +{ + struct page *cpage; + int ret; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return; + + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) + return; + + if (!f2fs_available_free_memory(sbi, COMPRESS_PAGE)) + return; + + cpage = find_get_page(COMPRESS_MAPPING(sbi), blkaddr); + if (cpage) { + f2fs_put_page(cpage, 0); + return; + } + + cpage = alloc_page(__GFP_NOWARN | __GFP_IO); + if (!cpage) + return; + + ret = add_to_page_cache_lru(cpage, COMPRESS_MAPPING(sbi), + blkaddr, GFP_NOFS); + if (ret) { + f2fs_put_page(cpage, 0); + return; + } + + set_page_private_data(cpage, ino); + + if (!f2fs_is_valid_blkaddr(sbi, blkaddr, DATA_GENERIC_ENHANCE_READ)) + goto out; + + memcpy(page_address(cpage), page_address(page), PAGE_SIZE); + SetPageUptodate(cpage); +out: + f2fs_put_page(cpage, 1); +} + +bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + block_t blkaddr) +{ + struct page *cpage; + bool hitted = false; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return false; + + cpage = f2fs_pagecache_get_page(COMPRESS_MAPPING(sbi), + blkaddr, FGP_LOCK | FGP_NOWAIT, GFP_NOFS); + if (cpage) { + if (PageUptodate(cpage)) { + atomic_inc(&sbi->compress_page_hit); + memcpy(page_address(page), + page_address(cpage), PAGE_SIZE); + hitted = true; + } + f2fs_put_page(cpage, 1); + } + + return hitted; +} + +void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino) +{ + struct address_space *mapping = sbi->compress_inode->i_mapping; + struct pagevec pvec; + pgoff_t index = 0; + pgoff_t end = MAX_BLKADDR(sbi); + + if (!mapping->nrpages) + return; + + pagevec_init(&pvec); + + do { + unsigned int nr_pages; + int i; + + nr_pages = pagevec_lookup_range(&pvec, mapping, + &index, end - 1); + if (!nr_pages) + break; + + for (i = 0; i < nr_pages; i++) { + struct page *page = pvec.pages[i]; + + if (page->index > end) + break; + + lock_page(page); + if (page->mapping != mapping) { + unlock_page(page); + continue; + } + + if (ino != get_page_private_data(page)) { + unlock_page(page); + continue; + } + + generic_error_remove_page(mapping, page); + unlock_page(page); + } + pagevec_release(&pvec); + cond_resched(); + } while (index < end); +} + +int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) +{ + struct inode *inode; + + if (!test_opt(sbi, COMPRESS_CACHE)) + return 0; + + inode = f2fs_iget(sbi->sb, F2FS_COMPRESS_INO(sbi)); + if (IS_ERR(inode)) + return PTR_ERR(inode); + sbi->compress_inode = inode; + + sbi->compress_percent = COMPRESS_PERCENT; + sbi->compress_watermark = COMPRESS_WATERMARK; + + atomic_set(&sbi->compress_page_hit, 0); + + return 0; +} + +void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) +{ + if (!sbi->compress_inode) + return; + iput(sbi->compress_inode); + sbi->compress_inode = NULL; +} + int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { dev_t dev = sbi->sb->s_bdev->bd_dev; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 528190b46dee..821da92fe5c2 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -133,7 +133,7 @@ static void f2fs_finish_read_bio(struct bio *bio) if (f2fs_is_compressed_page(page)) { if (bio->bi_status) - f2fs_end_read_compressed_page(page, true); + f2fs_end_read_compressed_page(page, true, 0); f2fs_put_page_dic(page); continue; } @@ -229,15 +229,19 @@ static void f2fs_handle_step_decompress(struct bio_post_read_ctx *ctx) struct bio_vec *bv; struct bvec_iter_all iter_all; bool all_compressed = true; + block_t blkaddr = SECTOR_TO_BLOCK(ctx->bio->bi_iter.bi_sector); bio_for_each_segment_all(bv, ctx->bio, iter_all) { struct page *page = bv->bv_page; /* PG_error was set if decryption failed. */ if (f2fs_is_compressed_page(page)) - f2fs_end_read_compressed_page(page, PageError(page)); + f2fs_end_read_compressed_page(page, PageError(page), + blkaddr); else all_compressed = false; + + blkaddr++; } /* @@ -1368,9 +1372,11 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) old_blkaddr = dn->data_blkaddr; f2fs_allocate_data_block(sbi, NULL, old_blkaddr, &dn->data_blkaddr, &sum, seg_type, NULL); - if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) + if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(sbi), old_blkaddr, old_blkaddr); + f2fs_invalidate_compress_page(sbi, old_blkaddr); + } f2fs_update_data_blkaddr(dn, dn->data_blkaddr); /* @@ -2190,7 +2196,7 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, goto out_put_dnode; } - for (i = 0; i < dic->nr_cpages; i++) { + for (i = 0; i < cc->nr_cpages; i++) { struct page *page = dic->cpages[i]; block_t blkaddr; struct bio_post_read_ctx *ctx; @@ -2198,6 +2204,14 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, blkaddr = data_blkaddr(dn.inode, dn.node_page, dn.ofs_in_node + i + 1); + f2fs_wait_on_block_writeback(inode, blkaddr); + + if (f2fs_load_compressed_page(sbi, page, blkaddr)) { + if (atomic_dec_and_test(&dic->remaining_pages)) + f2fs_decompress_cluster(dic); + continue; + } + if (bio && (!page_is_mergeable(sbi, bio, *last_block_in_bio, blkaddr) || !f2fs_crypt_mergeable_bio(bio, inode, page->index, NULL))) { @@ -2219,8 +2233,6 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, } } - f2fs_wait_on_block_writeback(inode, blkaddr); - if (bio_add_page(bio, page, blocksize, 0) < blocksize) goto submit_and_realloc; @@ -2476,6 +2488,10 @@ static inline bool check_inplace_update_policy(struct inode *inode, bool f2fs_should_update_inplace(struct inode *inode, struct f2fs_io_info *fio) { + /* swap file is migrating in aligned write mode */ + if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) + return false; + if (f2fs_is_pinned_file(inode)) return true; @@ -2498,6 +2514,13 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) return true; if (f2fs_is_atomic_file(inode)) return true; + if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) + return true; + + /* swap file is migrating in aligned write mode */ + if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) + return true; + if (fio) { if (page_private_gcing(fio->page)) return true; @@ -3675,6 +3698,13 @@ void f2fs_invalidate_page(struct page *page, unsigned int offset, clear_page_private_gcing(page); + if (test_opt(sbi, COMPRESS_CACHE)) { + if (f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_COMPRESS_INO(sbi)) + clear_page_private_data(page); + } + if (page_private_atomic(page)) return f2fs_drop_inmem_page(inode, page); @@ -3692,6 +3722,16 @@ int f2fs_release_page(struct page *page, gfp_t wait) if (page_private_atomic(page)) return 0; + if (test_opt(F2FS_P_SB(page), COMPRESS_CACHE)) { + struct f2fs_sb_info *sbi = F2FS_P_SB(page); + struct inode *inode = page->mapping->host; + + if (f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_COMPRESS_INO(sbi)) + clear_page_private_data(page); + } + clear_page_private_gcing(page); detach_page_private(page); @@ -3838,6 +3878,8 @@ int f2fs_migrate_page(struct address_space *mapping, get_page(newpage); } + /* guarantee to start from no stale private field */ + set_page_private(newpage, 0); if (PagePrivate(page)) { set_page_private(newpage, page_private(page)); SetPagePrivate(newpage); @@ -3858,67 +3900,66 @@ int f2fs_migrate_page(struct address_space *mapping, #endif #ifdef CONFIG_SWAP -static int f2fs_is_file_aligned(struct inode *inode) +static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, + unsigned int blkcnt) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - block_t main_blkaddr = SM_I(sbi)->main_blkaddr; - block_t cur_lblock; - block_t last_lblock; - block_t pblock; - unsigned long nr_pblocks; - unsigned int blocks_per_sec = BLKS_PER_SEC(sbi); - unsigned int not_aligned = 0; + unsigned int blkofs; + unsigned int blk_per_sec = BLKS_PER_SEC(sbi); + unsigned int secidx = start_blk / blk_per_sec; + unsigned int end_sec = secidx + blkcnt / blk_per_sec; int ret = 0; - cur_lblock = 0; - last_lblock = bytes_to_blks(inode, i_size_read(inode)); + down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + down_write(&F2FS_I(inode)->i_mmap_sem); - while (cur_lblock < last_lblock) { - struct f2fs_map_blocks map; + set_inode_flag(inode, FI_ALIGNED_WRITE); - memset(&map, 0, sizeof(map)); - map.m_lblk = cur_lblock; - map.m_len = last_lblock - cur_lblock; - map.m_next_pgofs = NULL; - map.m_next_extent = NULL; - map.m_seg_type = NO_CHECK_TYPE; - map.m_may_create = false; + for (; secidx < end_sec; secidx++) { + down_write(&sbi->pin_sem); - ret = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_FIEMAP); - if (ret) - goto out; + f2fs_lock_op(sbi); + f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false); + f2fs_unlock_op(sbi); - /* hole */ - if (!(map.m_flags & F2FS_MAP_FLAGS)) { - f2fs_err(sbi, "Swapfile has holes\n"); - ret = -ENOENT; - goto out; - } + set_inode_flag(inode, FI_DO_DEFRAG); - pblock = map.m_pblk; - nr_pblocks = map.m_len; + for (blkofs = 0; blkofs < blk_per_sec; blkofs++) { + struct page *page; + unsigned int blkidx = secidx * blk_per_sec + blkofs; - if ((pblock - main_blkaddr) & (blocks_per_sec - 1) || - nr_pblocks & (blocks_per_sec - 1)) { - if (f2fs_is_pinned_file(inode)) { - f2fs_err(sbi, "Swapfile does not align to section"); - ret = -EINVAL; - goto out; + page = f2fs_get_lock_data_page(inode, blkidx, true); + if (IS_ERR(page)) { + up_write(&sbi->pin_sem); + ret = PTR_ERR(page); + goto done; } - not_aligned++; + + set_page_dirty(page); + f2fs_put_page(page, 1); } - cur_lblock += nr_pblocks; + clear_inode_flag(inode, FI_DO_DEFRAG); + + ret = filemap_fdatawrite(inode->i_mapping); + + up_write(&sbi->pin_sem); + + if (ret) + break; } - if (not_aligned) - f2fs_warn(sbi, "Swapfile (%u) is not align to section: \n" - "\t1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate()", - not_aligned); -out: + +done: + clear_inode_flag(inode, FI_DO_DEFRAG); + clear_inode_flag(inode, FI_ALIGNED_WRITE); + + up_write(&F2FS_I(inode)->i_mmap_sem); + up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + return ret; } -static int check_swap_activate_fast(struct swap_info_struct *sis, +static int check_swap_activate(struct swap_info_struct *sis, struct file *swap_file, sector_t *span) { struct address_space *mapping = swap_file->f_mapping; @@ -3931,7 +3972,8 @@ static int check_swap_activate_fast(struct swap_info_struct *sis, sector_t highest_pblock = 0; int nr_extents = 0; unsigned long nr_pblocks; - unsigned int blocks_per_sec = BLKS_PER_SEC(sbi); + unsigned int blks_per_sec = BLKS_PER_SEC(sbi); + unsigned int sec_blks_mask = BLKS_PER_SEC(sbi) - 1; unsigned int not_aligned = 0; int ret = 0; @@ -3944,7 +3986,7 @@ static int check_swap_activate_fast(struct swap_info_struct *sis, while (cur_lblock < last_lblock && cur_lblock < sis->max) { struct f2fs_map_blocks map; - +retry: cond_resched(); memset(&map, 0, sizeof(map)); @@ -3961,7 +4003,7 @@ static int check_swap_activate_fast(struct swap_info_struct *sis, /* hole */ if (!(map.m_flags & F2FS_MAP_FLAGS)) { - f2fs_err(sbi, "Swapfile has holes\n"); + f2fs_err(sbi, "Swapfile has holes"); ret = -EINVAL; goto out; } @@ -3969,16 +4011,28 @@ static int check_swap_activate_fast(struct swap_info_struct *sis, pblock = map.m_pblk; nr_pblocks = map.m_len; - if ((pblock - SM_I(sbi)->main_blkaddr) & (blocks_per_sec - 1) || - nr_pblocks & (blocks_per_sec - 1)) { - if (f2fs_is_pinned_file(inode)) { - f2fs_err(sbi, "Swapfile does not align to section"); - ret = -EINVAL; - goto out; - } + if ((pblock - SM_I(sbi)->main_blkaddr) & sec_blks_mask || + nr_pblocks & sec_blks_mask) { not_aligned++; - } + nr_pblocks = roundup(nr_pblocks, blks_per_sec); + if (cur_lblock + nr_pblocks > sis->max) + nr_pblocks -= blks_per_sec; + + if (!nr_pblocks) { + /* this extent is last one */ + nr_pblocks = map.m_len; + f2fs_warn(sbi, "Swapfile: last extent is not aligned to section"); + goto next; + } + + ret = f2fs_migrate_blocks(inode, cur_lblock, + nr_pblocks); + if (ret) + goto out; + goto retry; + } +next: if (cur_lblock + nr_pblocks >= sis->max) nr_pblocks = sis->max - cur_lblock; @@ -4005,122 +4059,13 @@ static int check_swap_activate_fast(struct swap_info_struct *sis, sis->max = cur_lblock; sis->pages = cur_lblock - 1; sis->highest_bit = cur_lblock - 1; - +out: if (not_aligned) - f2fs_warn(sbi, "Swapfile (%u) is not align to section: \n" - "\t1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate()", - not_aligned); -out: + f2fs_warn(sbi, "Swapfile (%u) is not align to section: 1) creat(), 2) ioctl(F2FS_IOC_SET_PIN_FILE), 3) fallocate(%u * N)", + not_aligned, blks_per_sec * F2FS_BLKSIZE); return ret; } -/* Copied from generic_swapfile_activate() to check any holes */ -static int check_swap_activate(struct swap_info_struct *sis, - struct file *swap_file, sector_t *span) -{ - struct address_space *mapping = swap_file->f_mapping; - struct inode *inode = mapping->host; - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - unsigned blocks_per_page; - unsigned long page_no; - sector_t probe_block; - sector_t last_block; - sector_t lowest_block = -1; - sector_t highest_block = 0; - int nr_extents = 0; - int ret = 0; - - if (PAGE_SIZE == F2FS_BLKSIZE) - return check_swap_activate_fast(sis, swap_file, span); - - ret = f2fs_is_file_aligned(inode); - if (ret) - goto out; - - blocks_per_page = bytes_to_blks(inode, PAGE_SIZE); - - /* - * Map all the blocks into the extent list. This code doesn't try - * to be very smart. - */ - probe_block = 0; - page_no = 0; - last_block = bytes_to_blks(inode, i_size_read(inode)); - while ((probe_block + blocks_per_page) <= last_block && - page_no < sis->max) { - unsigned block_in_page; - sector_t first_block; - sector_t block = 0; - - cond_resched(); - - block = probe_block; - ret = bmap(inode, &block); - if (ret) - goto out; - if (!block) - goto bad_bmap; - first_block = block; - - /* - * It must be PAGE_SIZE aligned on-disk - */ - if (first_block & (blocks_per_page - 1)) { - probe_block++; - goto reprobe; - } - - for (block_in_page = 1; block_in_page < blocks_per_page; - block_in_page++) { - - block = probe_block + block_in_page; - ret = bmap(inode, &block); - if (ret) - goto out; - if (!block) - goto bad_bmap; - - if (block != first_block + block_in_page) { - /* Discontiguity */ - probe_block++; - goto reprobe; - } - } - - first_block >>= (PAGE_SHIFT - inode->i_blkbits); - if (page_no) { /* exclude the header page */ - if (first_block < lowest_block) - lowest_block = first_block; - if (first_block > highest_block) - highest_block = first_block; - } - - /* - * We found a PAGE_SIZE-length, PAGE_SIZE-aligned run of blocks - */ - ret = add_swap_extent(sis, page_no, 1, first_block); - if (ret < 0) - goto out; - nr_extents += ret; - page_no++; - probe_block += blocks_per_page; -reprobe: - continue; - } - ret = nr_extents; - *span = 1 + highest_block - lowest_block; - if (page_no == 0) - page_no = 1; /* force Empty message */ - sis->max = page_no; - sis->pages = page_no - 1; - sis->highest_bit = page_no - 1; -out: - return ret; -bad_bmap: - f2fs_err(sbi, "Swapfile has holes\n"); - return -EINVAL; -} - static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file, sector_t *span) { diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index c03949a7ccff..53ed1e9191f0 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -152,6 +152,12 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->node_pages = NODE_MAPPING(sbi)->nrpages; if (sbi->meta_inode) si->meta_pages = META_MAPPING(sbi)->nrpages; +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (sbi->compress_inode) { + si->compress_pages = COMPRESS_MAPPING(sbi)->nrpages; + si->compress_page_hit = atomic_read(&sbi->compress_page_hit); + } +#endif si->nats = NM_I(sbi)->nat_cnt[TOTAL_NAT]; si->dirty_nats = NM_I(sbi)->nat_cnt[DIRTY_NAT]; si->sits = MAIN_SEGS(sbi); @@ -309,6 +315,12 @@ static void update_mem_info(struct f2fs_sb_info *sbi) si->page_mem += (unsigned long long)npages << PAGE_SHIFT; } +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (sbi->compress_inode) { + unsigned npages = COMPRESS_MAPPING(sbi)->nrpages; + si->page_mem += (unsigned long long)npages << PAGE_SHIFT; + } +#endif } static int stat_show(struct seq_file *s, void *v) @@ -438,6 +450,15 @@ static int stat_show(struct seq_file *s, void *v) si->data_segs, si->bg_data_segs); seq_printf(s, " - node segments : %d (%d)\n", si->node_segs, si->bg_node_segs); + seq_printf(s, " - Reclaimed segs : Normal (%d), Idle CB (%d), " + "Idle Greedy (%d), Idle AT (%d), " + "Urgent High (%d), Urgent Low (%d)\n", + si->sbi->gc_reclaimed_segs[GC_NORMAL], + si->sbi->gc_reclaimed_segs[GC_IDLE_CB], + si->sbi->gc_reclaimed_segs[GC_IDLE_GREEDY], + si->sbi->gc_reclaimed_segs[GC_IDLE_AT], + si->sbi->gc_reclaimed_segs[GC_URGENT_HIGH], + si->sbi->gc_reclaimed_segs[GC_URGENT_LOW]); seq_printf(s, "Try to move %d blocks (BG: %d)\n", si->tot_blks, si->bg_data_blks + si->bg_node_blks); seq_printf(s, " - data blocks : %d (%d)\n", si->data_blks, @@ -476,6 +497,7 @@ static int stat_show(struct seq_file *s, void *v) "volatile IO: %4d (Max. %4d)\n", si->inmem_pages, si->aw_cnt, si->max_aw_cnt, si->vw_cnt, si->max_vw_cnt); + seq_printf(s, " - compress: %4d, hit:%8d\n", si->compress_pages, si->compress_page_hit); seq_printf(s, " - nodes: %4d in %4d\n", si->ndirty_node, si->node_pages); seq_printf(s, " - dents: %4d in dirs:%4d (%4d)\n", diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 4cf07050fefe..2d93dc257ea1 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -16,6 +16,10 @@ #include "xattr.h" #include +#ifdef CONFIG_UNICODE +extern struct kmem_cache *f2fs_cf_name_slab; +#endif + static unsigned long dir_blocks(struct inode *inode) { return ((unsigned long long) (i_size_read(inode) + PAGE_SIZE - 1)) @@ -77,11 +81,10 @@ int f2fs_init_casefolded_name(const struct inode *dir, { #ifdef CONFIG_UNICODE struct super_block *sb = dir->i_sb; - struct f2fs_sb_info *sbi = F2FS_SB(sb); if (IS_CASEFOLDED(dir)) { - fname->cf_name.name = f2fs_kmalloc(sbi, F2FS_NAME_LEN, - GFP_NOFS); + fname->cf_name.name = kmem_cache_alloc(f2fs_cf_name_slab, + GFP_NOFS); if (!fname->cf_name.name) return -ENOMEM; fname->cf_name.len = utf8_casefold(sb->s_encoding, @@ -89,7 +92,7 @@ int f2fs_init_casefolded_name(const struct inode *dir, fname->cf_name.name, F2FS_NAME_LEN); if ((int)fname->cf_name.len <= 0) { - kfree(fname->cf_name.name); + kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); fname->cf_name.name = NULL; if (sb_has_strict_encoding(sb)) return -EINVAL; @@ -172,8 +175,10 @@ void f2fs_free_filename(struct f2fs_filename *fname) fname->crypto_buf.name = NULL; #endif #ifdef CONFIG_UNICODE - kfree(fname->cf_name.name); - fname->cf_name.name = NULL; + if (fname->cf_name.name) { + kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); + fname->cf_name.name = NULL; + } #endif } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index f1de0faff9e1..738f37441db8 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -100,6 +100,7 @@ extern const char *f2fs_fault_name[FAULT_MAX]; #define F2FS_MOUNT_ATGC 0x08000000 #define F2FS_MOUNT_MERGE_CHECKPOINT 0x10000000 #define F2FS_MOUNT_GC_MERGE 0x20000000 +#define F2FS_MOUNT_COMPRESS_CACHE 0x40000000 #define F2FS_OPTION(sbi) ((sbi)->mount_opt) #define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option) @@ -170,6 +171,7 @@ struct f2fs_mount_info { #define F2FS_FEATURE_SB_CHKSUM 0x0800 #define F2FS_FEATURE_CASEFOLD 0x1000 #define F2FS_FEATURE_COMPRESSION 0x2000 +#define F2FS_FEATURE_RO 0x4000 #define __F2FS_HAS_FEATURE(raw_super, mask) \ ((raw_super->feature & cpu_to_le32(mask)) != 0) @@ -709,6 +711,7 @@ enum { FI_MMAP_FILE, /* indicate file was mmapped */ FI_ENABLE_COMPRESS, /* enable compression in "user" compression mode */ FI_COMPRESS_RELEASED, /* compressed blocks were released */ + FI_ALIGNED_WRITE, /* enable aligned write */ FI_MAX, /* max flag, never be used */ }; @@ -942,6 +945,7 @@ static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode, #define NR_CURSEG_DATA_TYPE (3) #define NR_CURSEG_NODE_TYPE (3) #define NR_CURSEG_INMEM_TYPE (2) +#define NR_CURSEG_RO_TYPE (2) #define NR_CURSEG_PERSIST_TYPE (NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE) #define NR_CURSEG_TYPE (NR_CURSEG_INMEM_TYPE + NR_CURSEG_PERSIST_TYPE) @@ -1249,6 +1253,7 @@ enum { GC_IDLE_AT, GC_URGENT_HIGH, GC_URGENT_LOW, + MAX_GC_MODE, }; enum { @@ -1327,7 +1332,8 @@ enum { #define PAGE_PRIVATE_GET_FUNC(name, flagname) \ static inline bool page_private_##name(struct page *page) \ { \ - return test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \ + return PagePrivate(page) && \ + test_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)) && \ test_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \ } @@ -1337,6 +1343,7 @@ static inline void set_page_private_##name(struct page *page) \ if (!PagePrivate(page)) { \ get_page(page); \ SetPagePrivate(page); \ + set_page_private(page, 0); \ } \ set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); \ set_bit(PAGE_PRIVATE_##flagname, &page_private(page)); \ @@ -1374,6 +1381,38 @@ PAGE_PRIVATE_CLEAR_FUNC(gcing, ONGOING_MIGRATION); PAGE_PRIVATE_CLEAR_FUNC(atomic, ATOMIC_WRITE); PAGE_PRIVATE_CLEAR_FUNC(dummy, DUMMY_WRITE); +static inline unsigned long get_page_private_data(struct page *page) +{ + unsigned long data = page_private(page); + + if (!test_bit(PAGE_PRIVATE_NOT_POINTER, &data)) + return 0; + return data >> PAGE_PRIVATE_MAX; +} + +static inline void set_page_private_data(struct page *page, unsigned long data) +{ + if (!PagePrivate(page)) { + get_page(page); + SetPagePrivate(page); + set_page_private(page, 0); + } + set_bit(PAGE_PRIVATE_NOT_POINTER, &page_private(page)); + page_private(page) |= data << PAGE_PRIVATE_MAX; +} + +static inline void clear_page_private_data(struct page *page) +{ + page_private(page) &= (1 << PAGE_PRIVATE_MAX) - 1; + if (page_private(page) == 1 << PAGE_PRIVATE_NOT_POINTER) { + set_page_private(page, 0); + if (PagePrivate(page)) { + ClearPagePrivate(page); + put_page(page); + } + } +} + /* For compression */ enum compress_algorithm_type { COMPRESS_LZO, @@ -1388,6 +1427,9 @@ enum compress_flag { COMPRESS_MAX_FLAG, }; +#define COMPRESS_WATERMARK 20 +#define COMPRESS_PERCENT 20 + #define COMPRESS_DATA_RESERVED_SIZE 4 struct compress_data { __le32 clen; /* compressed data size */ @@ -1667,6 +1709,9 @@ struct f2fs_sb_info { struct kobject s_stat_kobj; /* /sys/fs/f2fs//stat */ struct completion s_stat_kobj_unregister; + struct kobject s_feature_list_kobj; /* /sys/fs/f2fs//feature_list */ + struct completion s_feature_list_kobj_unregister; + /* For shrinker support */ struct list_head s_list; int s_ndevs; /* number of devices */ @@ -1691,6 +1736,10 @@ struct f2fs_sb_info { struct kmem_cache *inline_xattr_slab; /* inline xattr entry */ unsigned int inline_xattr_slab_size; /* default inline xattr slab size */ + /* For reclaimed segs statistics per each GC mode */ + unsigned int gc_segment_mode; /* GC state for reclaimed segments */ + unsigned int gc_reclaimed_segs[MAX_GC_MODE]; /* Reclaimed segs for each mode */ + #ifdef CONFIG_F2FS_FS_COMPRESSION struct kmem_cache *page_array_slab; /* page array entry */ unsigned int page_array_slab_size; /* default page array slab size */ @@ -1699,6 +1748,12 @@ struct f2fs_sb_info { u64 compr_written_block; u64 compr_saved_block; u32 compr_new_inode; + + /* For compressed block cache */ + struct inode *compress_inode; /* cache compressed blocks */ + unsigned int compress_percent; /* cache page percentage */ + unsigned int compress_watermark; /* cache page watermark */ + atomic_t compress_page_hit; /* cache hit count */ #endif }; @@ -3105,25 +3160,6 @@ static inline bool is_dot_dotdot(const u8 *name, size_t len) return false; } -static inline bool f2fs_may_extent_tree(struct inode *inode) -{ - struct f2fs_sb_info *sbi = F2FS_I_SB(inode); - - if (!test_opt(sbi, EXTENT_CACHE) || - is_inode_flag_set(inode, FI_NO_EXTENT) || - is_inode_flag_set(inode, FI_COMPRESSED_FILE)) - return false; - - /* - * for recovered files during mount do not create extents - * if shrinker is not registered. - */ - if (list_empty(&sbi->s_list)) - return false; - - return S_ISREG(inode->i_mode); -} - static inline void *f2fs_kmalloc(struct f2fs_sb_info *sbi, size_t size, gfp_t flags) { @@ -3666,7 +3702,8 @@ struct f2fs_stat_info { unsigned int bimodal, avg_vblocks; int util_free, util_valid, util_invalid; int rsvd_segs, overp_segs; - int dirty_count, node_pages, meta_pages; + int dirty_count, node_pages, meta_pages, compress_pages; + int compress_page_hit; int prefree_count, call_count, cp_count, bg_cp_count; int tot_segs, node_segs, data_segs, free_segs, free_secs; int bg_node_segs, bg_data_segs; @@ -4002,7 +4039,9 @@ void f2fs_compress_write_end_io(struct bio *bio, struct page *page); bool f2fs_is_compress_backend_ready(struct inode *inode); int f2fs_init_compress_mempool(void); void f2fs_destroy_compress_mempool(void); -void f2fs_end_read_compressed_page(struct page *page, bool failed); +void f2fs_decompress_cluster(struct decompress_io_ctx *dic); +void f2fs_end_read_compressed_page(struct page *page, bool failed, + block_t blkaddr); bool f2fs_cluster_is_empty(struct compress_ctx *cc); bool f2fs_cluster_can_merge_page(struct compress_ctx *cc, pgoff_t index); void f2fs_compress_ctx_add_page(struct compress_ctx *cc, struct page *page); @@ -4020,10 +4059,19 @@ void f2fs_put_page_dic(struct page *page); int f2fs_init_compress_ctx(struct compress_ctx *cc); void f2fs_destroy_compress_ctx(struct compress_ctx *cc, bool reuse); void f2fs_init_compress_info(struct f2fs_sb_info *sbi); +int f2fs_init_compress_inode(struct f2fs_sb_info *sbi); +void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi); int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi); void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi); int __init f2fs_init_compress_cache(void); void f2fs_destroy_compress_cache(void); +struct address_space *COMPRESS_MAPPING(struct f2fs_sb_info *sbi); +void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, block_t blkaddr); +void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + nid_t ino, block_t blkaddr); +bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, struct page *page, + block_t blkaddr); +void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, nid_t ino); #define inc_compr_inode_stat(inode) \ do { \ struct f2fs_sb_info *sbi = F2FS_I_SB(inode); \ @@ -4052,7 +4100,9 @@ static inline struct page *f2fs_compress_control_page(struct page *page) } static inline int f2fs_init_compress_mempool(void) { return 0; } static inline void f2fs_destroy_compress_mempool(void) { } -static inline void f2fs_end_read_compressed_page(struct page *page, bool failed) +static inline void f2fs_decompress_cluster(struct decompress_io_ctx *dic) { } +static inline void f2fs_end_read_compressed_page(struct page *page, + bool failed, block_t blkaddr) { WARN_ON_ONCE(1); } @@ -4060,10 +4110,20 @@ static inline void f2fs_put_page_dic(struct page *page) { WARN_ON_ONCE(1); } +static inline int f2fs_init_compress_inode(struct f2fs_sb_info *sbi) { return 0; } +static inline void f2fs_destroy_compress_inode(struct f2fs_sb_info *sbi) { } static inline int f2fs_init_page_array_cache(struct f2fs_sb_info *sbi) { return 0; } static inline void f2fs_destroy_page_array_cache(struct f2fs_sb_info *sbi) { } static inline int __init f2fs_init_compress_cache(void) { return 0; } static inline void f2fs_destroy_compress_cache(void) { } +static inline void f2fs_invalidate_compress_page(struct f2fs_sb_info *sbi, + block_t blkaddr) { } +static inline void f2fs_cache_compressed_page(struct f2fs_sb_info *sbi, + struct page *page, nid_t ino, block_t blkaddr) { } +static inline bool f2fs_load_compressed_page(struct f2fs_sb_info *sbi, + struct page *page, block_t blkaddr) { return false; } +static inline void f2fs_invalidate_compress_pages(struct f2fs_sb_info *sbi, + nid_t ino) { } #define inc_compr_inode_stat(inode) do { } while (0) #endif @@ -4128,6 +4188,27 @@ F2FS_FEATURE_FUNCS(verity, VERITY); F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM); F2FS_FEATURE_FUNCS(casefold, CASEFOLD); F2FS_FEATURE_FUNCS(compression, COMPRESSION); +F2FS_FEATURE_FUNCS(readonly, RO); + +static inline bool f2fs_may_extent_tree(struct inode *inode) +{ + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + + if (!test_opt(sbi, EXTENT_CACHE) || + is_inode_flag_set(inode, FI_NO_EXTENT) || + (is_inode_flag_set(inode, FI_COMPRESSED_FILE) && + !f2fs_sb_has_readonly(sbi))) + return false; + + /* + * for recovered files during mount do not create extents + * if shrinker is not registered. + */ + if (list_empty(&sbi->s_list)) + return false; + + return S_ISREG(inode->i_mode); +} #ifdef CONFIG_BLK_DEV_ZONED static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi, diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 3f4195ba5586..3ebdf44d243c 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -3381,7 +3381,7 @@ static int f2fs_ioc_enable_verity(struct file *filp, unsigned long arg) if (!f2fs_sb_has_verity(F2FS_I_SB(inode))) { f2fs_warn(F2FS_I_SB(inode), - "Can't enable fs-verity on inode %lu: the verity feature is not enabled on this filesystem.\n", + "Can't enable fs-verity on inode %lu: the verity feature is not enabled on this filesystem", inode->i_ino); return -EOPNOTSUPP; } @@ -4165,9 +4165,8 @@ static int f2fs_ioc_decompress_file(struct file *filp, unsigned long arg) LLONG_MAX); if (ret) - f2fs_warn(sbi, "%s: The file might be partially decompressed " - "(errno=%d). Please delete the file.\n", - __func__, ret); + f2fs_warn(sbi, "%s: The file might be partially decompressed (errno=%d). Please delete the file.", + __func__, ret); out: inode_unlock(inode); file_end_write(filp); @@ -4239,9 +4238,8 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg) clear_inode_flag(inode, FI_ENABLE_COMPRESS); if (ret) - f2fs_warn(sbi, "%s: The file might be partially compressed " - "(errno=%d). Please delete the file.\n", - __func__, ret); + f2fs_warn(sbi, "%s: The file might be partially compressed (errno=%d). Please delete the file.", + __func__, ret); out: inode_unlock(inode); file_end_write(filp); diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index bcb3b488dbca..d9511827dc83 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1031,8 +1031,8 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (unlikely(check_valid_map(sbi, segno, offset))) { if (!test_and_set_bit(segno, SIT_I(sbi)->invalid_segmap)) { - f2fs_err(sbi, "mismatched blkaddr %u (source_blkaddr %u) in seg %u\n", - blkaddr, source_blkaddr, segno); + f2fs_err(sbi, "mismatched blkaddr %u (source_blkaddr %u) in seg %u", + blkaddr, source_blkaddr, segno); f2fs_bug_on(sbi, 1); } } @@ -1261,6 +1261,7 @@ static int move_data_block(struct inode *inode, block_t bidx, f2fs_put_page(mpage, 1); invalidate_mapping_pages(META_MAPPING(fio.sbi), fio.old_blkaddr, fio.old_blkaddr); + f2fs_invalidate_compress_page(fio.sbi, fio.old_blkaddr); set_page_dirty(fio.encrypted_page); if (clear_page_dirty_for_io(fio.encrypted_page)) @@ -1450,10 +1451,8 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (phase == 3) { inode = f2fs_iget(sb, dni.ino); - if (IS_ERR(inode) || is_bad_inode(inode)) { - set_sbi_flag(sbi, SBI_NEED_FSCK); + if (IS_ERR(inode) || is_bad_inode(inode)) continue; - } if (!down_write_trylock( &F2FS_I(inode)->i_gc_rwsem[WRITE])) { @@ -1647,6 +1646,7 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, force_migrate); stat_inc_seg_count(sbi, type, gc_type); + sbi->gc_reclaimed_segs[sbi->gc_mode]++; migrated++; freed: diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index cbda7ca3b3be..9141147b5bb0 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -18,6 +18,10 @@ #include +#ifdef CONFIG_F2FS_FS_COMPRESSION +extern const struct address_space_operations f2fs_compress_aops; +#endif + void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync) { if (is_inode_flag_set(inode, FI_NEW_INODE)) @@ -494,6 +498,11 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) if (ino == F2FS_NODE_INO(sbi) || ino == F2FS_META_INO(sbi)) goto make_now; +#ifdef CONFIG_F2FS_FS_COMPRESSION + if (ino == F2FS_COMPRESS_INO(sbi)) + goto make_now; +#endif + ret = do_read_inode(inode); if (ret) goto bad_inode; @@ -504,6 +513,12 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) } else if (ino == F2FS_META_INO(sbi)) { inode->i_mapping->a_ops = &f2fs_meta_aops; mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); + } else if (ino == F2FS_COMPRESS_INO(sbi)) { +#ifdef CONFIG_F2FS_FS_COMPRESSION + inode->i_mapping->a_ops = &f2fs_compress_aops; +#endif + mapping_set_gfp_mask(inode->i_mapping, + GFP_NOFS | __GFP_HIGHMEM | __GFP_MOVABLE); } else if (S_ISREG(inode->i_mode)) { inode->i_op = &f2fs_file_inode_operations; inode->i_fop = &f2fs_file_operations; @@ -723,8 +738,12 @@ void f2fs_evict_inode(struct inode *inode) trace_f2fs_evict_inode(inode); truncate_inode_pages_final(&inode->i_data); + if (test_opt(sbi, COMPRESS_CACHE) && f2fs_compressed_file(inode)) + f2fs_invalidate_compress_pages(sbi, inode->i_ino); + if (inode->i_ino == F2FS_NODE_INO(sbi) || - inode->i_ino == F2FS_META_INO(sbi)) + inode->i_ino == F2FS_META_INO(sbi) || + inode->i_ino == F2FS_COMPRESS_INO(sbi)) goto out_clear; f2fs_bug_on(sbi, get_dirty_pages(inode)); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 7dc18676f204..28cfc9a86010 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -97,6 +97,20 @@ bool f2fs_available_free_memory(struct f2fs_sb_info *sbi, int type) mem_size = (atomic_read(&dcc->discard_cmd_cnt) * sizeof(struct discard_cmd)) >> PAGE_SHIFT; res = mem_size < (avail_ram * nm_i->ram_thresh / 100); + } else if (type == COMPRESS_PAGE) { +#ifdef CONFIG_F2FS_FS_COMPRESSION + unsigned long free_ram = val.freeram; + + /* + * free memory is lower than watermark or cached page count + * exceed threshold, deny caching compress page. + */ + res = (free_ram > avail_ram * sbi->compress_watermark / 100) && + (COMPRESS_MAPPING(sbi)->nrpages < + free_ram * sbi->compress_percent / 100); +#else + res = false; +#endif } else { if (!sbi->sb->s_bdi->wb.dirty_exceeded) return true; @@ -538,7 +552,7 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, int i; ni->nid = nid; - +retry: /* Check nat cache */ down_read(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); @@ -550,10 +564,19 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, return 0; } - memset(&ne, 0, sizeof(struct f2fs_nat_entry)); + /* + * Check current segment summary by trying to grab journal_rwsem first. + * This sem is on the critical path on the checkpoint requiring the above + * nat_tree_lock. Therefore, we should retry, if we failed to grab here + * while not bothering checkpoint. + */ + if (!rwsem_is_locked(&sbi->cp_global_sem)) { + down_read(&curseg->journal_rwsem); + } else if (!down_read_trylock(&curseg->journal_rwsem)) { + up_read(&nm_i->nat_tree_lock); + goto retry; + } - /* Check current segment summary */ - down_read(&curseg->journal_rwsem); i = f2fs_lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0); if (i >= 0) { ne = nat_in_journal(journal, i); diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index d85e8659cfda..ff14a6e5ac1c 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -38,6 +38,9 @@ /* return value for read_node_page */ #define LOCKED_PAGE 1 +/* check pinned file's alignment status of physical blocks */ +#define FILE_NOT_ALIGNED 1 + /* For flag in struct node_info */ enum { IS_CHECKPOINTED, /* is it checkpointed before? */ @@ -148,6 +151,7 @@ enum mem_type { EXTENT_CACHE, /* indicates extent cache */ INMEM_PAGES, /* indicates inmemory pages */ DISCARD_CACHE, /* indicates memory of cached discard cmds */ + COMPRESS_PAGE, /* indicates memory of cached compressed pages */ BASE_CHECK, /* check kernel status */ }; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 4cfe36fa41be..695eacfe776c 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -45,6 +45,10 @@ static struct kmem_cache *fsync_entry_slab; +#ifdef CONFIG_UNICODE +extern struct kmem_cache *f2fs_cf_name_slab; +#endif + bool f2fs_space_for_roll_forward(struct f2fs_sb_info *sbi) { s64 nalloc = percpu_counter_sum_positive(&sbi->alloc_valid_block_count); @@ -145,7 +149,7 @@ static int init_recovered_filename(const struct inode *dir, f2fs_hash_filename(dir, fname); #ifdef CONFIG_UNICODE /* Case-sensitive match is fine for recovery */ - kfree(fname->cf_name.name); + kmem_cache_free(f2fs_cf_name_slab, fname->cf_name.name); fname->cf_name.name = NULL; #endif } else { @@ -782,6 +786,8 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) } #ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sbi->sb->s_flags |= SB_ACTIVE; /* Turn on quotas so that they are updated correctly */ quota_enabled = f2fs_enable_quota_files(sbi, s_flags & SB_RDONLY); #endif @@ -809,8 +815,10 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) err = recover_data(sbi, &inode_list, &tmp_inode_list, &dir_list); if (!err) f2fs_bug_on(sbi, !list_empty(&inode_list)); - else - f2fs_bug_on(sbi, sbi->sb->s_flags & SB_ACTIVE); + else { + /* restore s_flags to let iput() trash data */ + sbi->sb->s_flags = s_flags; + } skip: fix_curseg_write_pointer = !check_only || list_empty(&inode_list); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 880f72b7c2e7..95bfcff5ce8c 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -2322,6 +2322,7 @@ void f2fs_invalidate_blocks(struct f2fs_sb_info *sbi, block_t addr) return; invalidate_mapping_pages(META_MAPPING(sbi), addr, addr); + f2fs_invalidate_compress_page(sbi, addr); /* add it into sit main buffer */ down_write(&sit_i->sentry_lock); @@ -3290,6 +3291,9 @@ static int __get_segment_type_6(struct f2fs_io_info *fio) if (fio->type == DATA) { struct inode *inode = fio->page->mapping->host; + if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) + return CURSEG_COLD_DATA_PINNED; + if (page_private_gcing(fio->page)) { if (fio->sbi->am.atgc_enabled && (fio->io_type == FS_DATA_IO) && @@ -3469,9 +3473,11 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio) reallocate: f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr, &fio->new_blkaddr, sum, type, fio); - if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO) + if (GET_SEGNO(fio->sbi, fio->old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(fio->sbi), fio->old_blkaddr, fio->old_blkaddr); + f2fs_invalidate_compress_page(fio->sbi, fio->old_blkaddr); + } /* writeout dirty page into bdev */ f2fs_submit_page_write(fio); @@ -3557,7 +3563,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio) goto drop_bio; } - if (is_sbi_flag_set(sbi, SBI_NEED_FSCK) || f2fs_cp_error(sbi)) { + if (f2fs_cp_error(sbi)) { err = -EIO; goto drop_bio; } @@ -3661,6 +3667,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (GET_SEGNO(sbi, old_blkaddr) != NULL_SEGNO) { invalidate_mapping_pages(META_MAPPING(sbi), old_blkaddr, old_blkaddr); + f2fs_invalidate_compress_page(sbi, old_blkaddr); if (!from_gc) update_segment_mtime(sbi, old_blkaddr, 0); update_sit_entry(sbi, old_blkaddr, -1); @@ -3920,7 +3927,7 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) /* sanity check for summary blocks */ if (nats_in_cursum(nat_j) > NAT_JOURNAL_ENTRIES || sits_in_cursum(sit_j) > SIT_JOURNAL_ENTRIES) { - f2fs_err(sbi, "invalid journal entries nats %u sits %u\n", + f2fs_err(sbi, "invalid journal entries nats %u sits %u", nats_in_cursum(nat_j), sits_in_cursum(sit_j)); return -EINVAL; } @@ -4683,6 +4690,10 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi) struct seg_entry *se = get_seg_entry(sbi, curseg->segno); unsigned int blkofs = curseg->next_blkoff; + if (f2fs_sb_has_readonly(sbi) && + i != CURSEG_HOT_DATA && i != CURSEG_HOT_NODE) + continue; + sanity_check_seg_type(sbi, curseg->seg_type); if (f2fs_test_bit(blkofs, se->cur_valid_map)) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 6244b87dbb0d..4748af5d522c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -150,6 +150,7 @@ enum { Opt_compress_extension, Opt_compress_chksum, Opt_compress_mode, + Opt_compress_cache, Opt_atgc, Opt_gc_merge, Opt_nogc_merge, @@ -224,6 +225,7 @@ static match_table_t f2fs_tokens = { {Opt_compress_extension, "compress_extension=%s"}, {Opt_compress_chksum, "compress_chksum"}, {Opt_compress_mode, "compress_mode=%s"}, + {Opt_compress_cache, "compress_cache"}, {Opt_atgc, "atgc"}, {Opt_gc_merge, "gc_merge"}, {Opt_nogc_merge, "nogc_merge"}, @@ -275,6 +277,24 @@ static int f2fs_sb_read_encoding(const struct f2fs_super_block *sb, return 0; } + +struct kmem_cache *f2fs_cf_name_slab; +static int __init f2fs_create_casefold_cache(void) +{ + f2fs_cf_name_slab = f2fs_kmem_cache_create("f2fs_casefolded_name", + F2FS_NAME_LEN); + if (!f2fs_cf_name_slab) + return -ENOMEM; + return 0; +} + +static void f2fs_destroy_casefold_cache(void) +{ + kmem_cache_destroy(f2fs_cf_name_slab); +} +#else +static int __init f2fs_create_casefold_cache(void) { return 0; } +static void f2fs_destroy_casefold_cache(void) { } #endif static inline void limit_reserve_root(struct f2fs_sb_info *sbi) @@ -556,7 +576,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) int ret; if (!options) - return 0; + goto default_check; while ((p = strsep(&options, ",")) != NULL) { int token; @@ -1067,12 +1087,16 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) } kfree(name); break; + case Opt_compress_cache: + set_opt(sbi, COMPRESS_CACHE); + break; #else case Opt_compress_algorithm: case Opt_compress_log_size: case Opt_compress_extension: case Opt_compress_chksum: case Opt_compress_mode: + case Opt_compress_cache: f2fs_info(sbi, "compression options not supported"); break; #endif @@ -1091,6 +1115,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) return -EINVAL; } } +default_check: #ifdef CONFIG_QUOTA if (f2fs_check_quota_options(sbi)) return -EINVAL; @@ -1154,7 +1179,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) } if (test_opt(sbi, DISABLE_CHECKPOINT) && f2fs_lfs_mode(sbi)) { - f2fs_err(sbi, "LFS not compatible with checkpoint=disable\n"); + f2fs_err(sbi, "LFS not compatible with checkpoint=disable"); return -EINVAL; } @@ -1163,6 +1188,11 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) */ if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_TYPE) F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF; + + if (f2fs_sb_has_readonly(sbi) && !f2fs_readonly(sbi->sb)) { + f2fs_err(sbi, "Allow to mount readonly mode only"); + return -EROFS; + } return 0; } @@ -1407,6 +1437,8 @@ static void f2fs_put_super(struct super_block *sb) f2fs_bug_on(sbi, sbi->fsync_node_num); + f2fs_destroy_compress_inode(sbi); + iput(sbi->node_inode); sbi->node_inode = NULL; @@ -1679,6 +1711,9 @@ static inline void f2fs_show_compress_options(struct seq_file *seq, seq_printf(seq, ",compress_mode=%s", "fs"); else if (F2FS_OPTION(sbi).compress_mode == COMPR_MODE_USER) seq_printf(seq, ",compress_mode=%s", "user"); + + if (test_opt(sbi, COMPRESS_CACHE)) + seq_puts(seq, ",compress_cache"); } #endif @@ -1826,7 +1861,11 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) static void default_options(struct f2fs_sb_info *sbi) { /* init some FS parameters */ - F2FS_OPTION(sbi).active_logs = NR_CURSEG_PERSIST_TYPE; + if (f2fs_sb_has_readonly(sbi)) + F2FS_OPTION(sbi).active_logs = NR_CURSEG_RO_TYPE; + else + F2FS_OPTION(sbi).active_logs = NR_CURSEG_PERSIST_TYPE; + F2FS_OPTION(sbi).inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS; F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF; F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT; @@ -1873,15 +1912,17 @@ static int f2fs_enable_quotas(struct super_block *sb); static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) { + unsigned int s_flags = sbi->sb->s_flags; struct cp_control cpc; int err = 0; int ret; block_t unusable; - if (sbi->sb->s_flags & SB_RDONLY) { + if (s_flags & SB_RDONLY) { f2fs_err(sbi, "checkpoint=disable on readonly fs"); return -EINVAL; } + sbi->sb->s_flags |= SB_ACTIVE; f2fs_update_time(sbi, DISABLE_TIME); @@ -1899,13 +1940,13 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) ret = sync_filesystem(sbi->sb); if (ret || err) { err = ret ? ret : err; - goto out; + goto restore_flag; } unusable = f2fs_get_unusable_blocks(sbi); if (f2fs_disable_cp_again(sbi, unusable)) { err = -EAGAIN; - goto out; + goto restore_flag; } down_write(&sbi->gc_lock); @@ -1921,7 +1962,8 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) out_unlock: up_write(&sbi->gc_lock); -out: +restore_flag: + sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */ return err; } @@ -1953,6 +1995,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) bool disable_checkpoint = test_opt(sbi, DISABLE_CHECKPOINT); bool no_io_align = !F2FS_IO_ALIGNED(sbi); bool no_atgc = !test_opt(sbi, ATGC); + bool no_compress_cache = !test_opt(sbi, COMPRESS_CACHE); bool checkpoint_changed; #ifdef CONFIG_QUOTA int i, j; @@ -2008,6 +2051,11 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) if (f2fs_readonly(sb) && (*flags & SB_RDONLY)) goto skip; + if (f2fs_sb_has_readonly(sbi) && !(*flags & SB_RDONLY)) { + err = -EROFS; + goto restore_opts; + } + #ifdef CONFIG_QUOTA if (!f2fs_readonly(sb) && (*flags & SB_RDONLY)) { err = dquot_suspend(sb, -1); @@ -2045,6 +2093,12 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) goto restore_opts; } + if (no_compress_cache == !!test_opt(sbi, COMPRESS_CACHE)) { + err = -EINVAL; + f2fs_warn(sbi, "switch compress_cache option is not allowed"); + goto restore_opts; + } + if ((*flags & SB_RDONLY) && test_opt(sbi, DISABLE_CHECKPOINT)) { err = -EINVAL; f2fs_warn(sbi, "disabling checkpoint not compatible with read-only"); @@ -3141,14 +3195,15 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) ovp_segments = le32_to_cpu(ckpt->overprov_segment_count); reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count); - if (unlikely(fsmeta < F2FS_MIN_META_SEGMENTS || + if (!f2fs_sb_has_readonly(sbi) && + unlikely(fsmeta < F2FS_MIN_META_SEGMENTS || ovp_segments == 0 || reserved_segments == 0)) { f2fs_err(sbi, "Wrong layout: check mkfs.f2fs version"); return 1; } - user_block_count = le64_to_cpu(ckpt->user_block_count); - segment_count_main = le32_to_cpu(raw_super->segment_count_main); + segment_count_main = le32_to_cpu(raw_super->segment_count_main) + + (f2fs_sb_has_readonly(sbi) ? 1 : 0); log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg); if (!user_block_count || user_block_count >= segment_count_main << log_blocks_per_seg) { @@ -3179,6 +3234,10 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) if (le32_to_cpu(ckpt->cur_node_segno[i]) >= main_segs || le16_to_cpu(ckpt->cur_node_blkoff[i]) >= blocks_per_seg) return 1; + + if (f2fs_sb_has_readonly(sbi)) + goto check_data; + for (j = i + 1; j < NR_CURSEG_NODE_TYPE; j++) { if (le32_to_cpu(ckpt->cur_node_segno[i]) == le32_to_cpu(ckpt->cur_node_segno[j])) { @@ -3189,10 +3248,15 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) } } } +check_data: for (i = 0; i < NR_CURSEG_DATA_TYPE; i++) { if (le32_to_cpu(ckpt->cur_data_segno[i]) >= main_segs || le16_to_cpu(ckpt->cur_data_blkoff[i]) >= blocks_per_seg) return 1; + + if (f2fs_sb_has_readonly(sbi)) + goto skip_cross; + for (j = i + 1; j < NR_CURSEG_DATA_TYPE; j++) { if (le32_to_cpu(ckpt->cur_data_segno[i]) == le32_to_cpu(ckpt->cur_data_segno[j])) { @@ -3214,7 +3278,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) } } } - +skip_cross: sit_bitmap_size = le32_to_cpu(ckpt->sit_ver_bitmap_bytesize); nat_bitmap_size = le32_to_cpu(ckpt->nat_ver_bitmap_bytesize); @@ -3559,7 +3623,7 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi) #ifdef CONFIG_BLK_DEV_ZONED if (bdev_zoned_model(FDEV(i).bdev) == BLK_ZONED_HM && !f2fs_sb_has_blkzoned(sbi)) { - f2fs_err(sbi, "Zoned block device feature not enabled\n"); + f2fs_err(sbi, "Zoned block device feature not enabled"); return -EINVAL; } if (bdev_zoned_model(FDEV(i).bdev) != BLK_ZONED_NONE) { @@ -3946,10 +4010,14 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) goto free_node_inode; } - err = f2fs_register_sysfs(sbi); + err = f2fs_init_compress_inode(sbi); if (err) goto free_root_inode; + err = f2fs_register_sysfs(sbi); + if (err) + goto free_compress_inode; + #ifdef CONFIG_QUOTA /* Enable quota usage during mount */ if (f2fs_sb_has_quota_ino(sbi) && !f2fs_readonly(sb)) { @@ -4090,6 +4158,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) /* evict some inodes being cached by GC */ evict_inodes(sb); f2fs_unregister_sysfs(sbi); +free_compress_inode: + f2fs_destroy_compress_inode(sbi); free_root_inode: dput(sb->s_root); sb->s_root = NULL; @@ -4168,6 +4238,15 @@ static void kill_f2fs_super(struct super_block *sb) f2fs_stop_gc_thread(sbi); f2fs_stop_discard_thread(sbi); +#ifdef CONFIG_F2FS_FS_COMPRESSION + /* + * latter evict_inode() can bypass checking and invalidating + * compress inode cache. + */ + if (test_opt(sbi, COMPRESS_CACHE)) + truncate_inode_pages_final(COMPRESS_MAPPING(sbi)); +#endif + if (is_sbi_flag_set(sbi, SBI_IS_DIRTY) || !is_set_ckpt_flags(sbi, CP_UMOUNT_FLAG)) { struct cp_control cpc = { @@ -4267,7 +4346,12 @@ static int __init init_f2fs_fs(void) err = f2fs_init_compress_cache(); if (err) goto free_compress_mempool; + err = f2fs_create_casefold_cache(); + if (err) + goto free_compress_cache; return 0; +free_compress_cache: + f2fs_destroy_compress_cache(); free_compress_mempool: f2fs_destroy_compress_mempool(); free_bioset: @@ -4303,6 +4387,7 @@ static int __init init_f2fs_fs(void) static void __exit exit_f2fs_fs(void) { + f2fs_destroy_casefold_cache(); f2fs_destroy_compress_cache(); f2fs_destroy_compress_mempool(); f2fs_destroy_bioset(); diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index dc71bc968c72..15fe30d3aeb5 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -158,6 +158,9 @@ static ssize_t features_show(struct f2fs_attr *a, if (f2fs_sb_has_casefold(sbi)) len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", len ? ", " : "", "casefold"); + if (f2fs_sb_has_readonly(sbi)) + len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", + len ? ", " : "", "readonly"); if (f2fs_sb_has_compression(sbi)) len += scnprintf(buf + len, PAGE_SIZE - len, "%s%s", len ? ", " : "", "compression"); @@ -304,6 +307,14 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, return sysfs_emit(buf, "%u\n", sbi->compr_new_inode); #endif + if (!strcmp(a->attr.name, "gc_segment_mode")) + return sysfs_emit(buf, "%u\n", sbi->gc_segment_mode); + + if (!strcmp(a->attr.name, "gc_reclaimed_segments")) { + return sysfs_emit(buf, "%u\n", + sbi->gc_reclaimed_segs[sbi->gc_segment_mode]); + } + ui = (unsigned int *)(ptr + a->offset); return sprintf(buf, "%u\n", *ui); @@ -512,6 +523,21 @@ static ssize_t __sbi_store(struct f2fs_attr *a, return count; } + if (!strcmp(a->attr.name, "gc_segment_mode")) { + if (t < MAX_GC_MODE) + sbi->gc_segment_mode = t; + else + return -EINVAL; + return count; + } + + if (!strcmp(a->attr.name, "gc_reclaimed_segments")) { + if (t != 0) + return -EINVAL; + sbi->gc_reclaimed_segs[sbi->gc_segment_mode] = 0; + return count; + } + *ui = (unsigned int)t; return count; @@ -563,46 +589,49 @@ static void f2fs_sb_release(struct kobject *kobj) complete(&sbi->s_kobj_unregister); } -enum feat_id { - FEAT_CRYPTO = 0, - FEAT_BLKZONED, - FEAT_ATOMIC_WRITE, - FEAT_EXTRA_ATTR, - FEAT_PROJECT_QUOTA, - FEAT_INODE_CHECKSUM, - FEAT_FLEXIBLE_INLINE_XATTR, - FEAT_QUOTA_INO, - FEAT_INODE_CRTIME, - FEAT_LOST_FOUND, - FEAT_VERITY, - FEAT_SB_CHECKSUM, - FEAT_CASEFOLD, - FEAT_COMPRESSION, - FEAT_TEST_DUMMY_ENCRYPTION_V2, -}; - +/* + * Note that there are three feature list entries: + * 1) /sys/fs/f2fs/features + * : shows runtime features supported by in-kernel f2fs along with Kconfig. + * - ref. F2FS_FEATURE_RO_ATTR() + * + * 2) /sys/fs/f2fs/$s_id/features + * : shows on-disk features enabled by mkfs.f2fs, used for old kernels. This + * won't add new feature anymore, and thus, users should check entries in 3) + * instead of this 2). + * + * 3) /sys/fs/f2fs/$s_id/feature_list + * : shows on-disk features enabled by mkfs.f2fs per instance, which follows + * sysfs entry rule where each entry should expose single value. + * This list covers old feature list provided by 2) and beyond. Therefore, + * please add new on-disk feature in this list only. + * - ref. F2FS_SB_FEATURE_RO_ATTR() + */ static ssize_t f2fs_feature_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { - switch (a->id) { - case FEAT_CRYPTO: - case FEAT_BLKZONED: - case FEAT_ATOMIC_WRITE: - case FEAT_EXTRA_ATTR: - case FEAT_PROJECT_QUOTA: - case FEAT_INODE_CHECKSUM: - case FEAT_FLEXIBLE_INLINE_XATTR: - case FEAT_QUOTA_INO: - case FEAT_INODE_CRTIME: - case FEAT_LOST_FOUND: - case FEAT_VERITY: - case FEAT_SB_CHECKSUM: - case FEAT_CASEFOLD: - case FEAT_COMPRESSION: - case FEAT_TEST_DUMMY_ENCRYPTION_V2: + return sprintf(buf, "supported\n"); +} + +#define F2FS_FEATURE_RO_ATTR(_name) \ +static struct f2fs_attr f2fs_attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = 0444 }, \ + .show = f2fs_feature_show, \ +} + +static ssize_t f2fs_sb_feature_show(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf) +{ + if (F2FS_HAS_FEATURE(sbi, a->id)) return sprintf(buf, "supported\n"); - } - return 0; + return sprintf(buf, "unsupported\n"); +} + +#define F2FS_SB_FEATURE_RO_ATTR(_name, _feat) \ +static struct f2fs_attr f2fs_attr_sb_##_name = { \ + .attr = {.name = __stringify(_name), .mode = 0444 }, \ + .show = f2fs_sb_feature_show, \ + .id = F2FS_FEATURE_##_feat, \ } #define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ @@ -622,13 +651,6 @@ static struct f2fs_attr f2fs_attr_##_name = { \ #define F2FS_GENERAL_RO_ATTR(name) \ static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) -#define F2FS_FEATURE_RO_ATTR(_name, _id) \ -static struct f2fs_attr f2fs_attr_##_name = { \ - .attr = {.name = __stringify(_name), .mode = 0444 }, \ - .show = f2fs_feature_show, \ - .id = _id, \ -} - #define F2FS_STAT_ATTR(_struct_type, _struct_name, _name, _elname) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = 0444 }, \ @@ -702,37 +724,48 @@ F2FS_GENERAL_RO_ATTR(avg_vblocks); #endif #ifdef CONFIG_FS_ENCRYPTION -F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); -F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2, FEAT_TEST_DUMMY_ENCRYPTION_V2); +F2FS_FEATURE_RO_ATTR(encryption); +F2FS_FEATURE_RO_ATTR(test_dummy_encryption_v2); +#ifdef CONFIG_UNICODE +F2FS_FEATURE_RO_ATTR(encrypted_casefold); #endif +#endif /* CONFIG_FS_ENCRYPTION */ #ifdef CONFIG_BLK_DEV_ZONED -F2FS_FEATURE_RO_ATTR(block_zoned, FEAT_BLKZONED); +F2FS_FEATURE_RO_ATTR(block_zoned); #endif -F2FS_FEATURE_RO_ATTR(atomic_write, FEAT_ATOMIC_WRITE); -F2FS_FEATURE_RO_ATTR(extra_attr, FEAT_EXTRA_ATTR); -F2FS_FEATURE_RO_ATTR(project_quota, FEAT_PROJECT_QUOTA); -F2FS_FEATURE_RO_ATTR(inode_checksum, FEAT_INODE_CHECKSUM); -F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR); -F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO); -F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME); -F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND); +F2FS_FEATURE_RO_ATTR(atomic_write); +F2FS_FEATURE_RO_ATTR(extra_attr); +F2FS_FEATURE_RO_ATTR(project_quota); +F2FS_FEATURE_RO_ATTR(inode_checksum); +F2FS_FEATURE_RO_ATTR(flexible_inline_xattr); +F2FS_FEATURE_RO_ATTR(quota_ino); +F2FS_FEATURE_RO_ATTR(inode_crtime); +F2FS_FEATURE_RO_ATTR(lost_found); #ifdef CONFIG_FS_VERITY -F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY); +F2FS_FEATURE_RO_ATTR(verity); #endif -F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); -F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD); +F2FS_FEATURE_RO_ATTR(sb_checksum); +#ifdef CONFIG_UNICODE +F2FS_FEATURE_RO_ATTR(casefold); +#endif +F2FS_FEATURE_RO_ATTR(readonly); #ifdef CONFIG_F2FS_FS_COMPRESSION -F2FS_FEATURE_RO_ATTR(compression, FEAT_COMPRESSION); +F2FS_FEATURE_RO_ATTR(compression); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_written_block, compr_written_block); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_saved_block, compr_saved_block); F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, compr_new_inode, compr_new_inode); #endif +F2FS_FEATURE_RO_ATTR(pin_file); + /* For ATGC */ F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_ratio, candidate_ratio); F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_candidate_count, max_candidate_count); F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_weight, age_weight); F2FS_RW_ATTR(ATGC_INFO, atgc_management, atgc_age_threshold, age_threshold); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_segment_mode, gc_segment_mode); +F2FS_RW_ATTR(F2FS_SBI, f2fs_sb_info, gc_reclaimed_segments, gc_reclaimed_segs); + #define ATTR_LIST(name) (&f2fs_attr_##name.attr) static struct attribute *f2fs_attrs[] = { ATTR_LIST(gc_urgent_sleep_time), @@ -805,6 +838,8 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(atgc_candidate_count), ATTR_LIST(atgc_age_weight), ATTR_LIST(atgc_age_threshold), + ATTR_LIST(gc_segment_mode), + ATTR_LIST(gc_reclaimed_segments), NULL, }; ATTRIBUTE_GROUPS(f2fs); @@ -813,7 +848,10 @@ static struct attribute *f2fs_feat_attrs[] = { #ifdef CONFIG_FS_ENCRYPTION ATTR_LIST(encryption), ATTR_LIST(test_dummy_encryption_v2), +#ifdef CONFIG_UNICODE + ATTR_LIST(encrypted_casefold), #endif +#endif /* CONFIG_FS_ENCRYPTION */ #ifdef CONFIG_BLK_DEV_ZONED ATTR_LIST(block_zoned), #endif @@ -829,10 +867,14 @@ static struct attribute *f2fs_feat_attrs[] = { ATTR_LIST(verity), #endif ATTR_LIST(sb_checksum), +#ifdef CONFIG_UNICODE ATTR_LIST(casefold), +#endif + ATTR_LIST(readonly), #ifdef CONFIG_F2FS_FS_COMPRESSION ATTR_LIST(compression), #endif + ATTR_LIST(pin_file), NULL, }; ATTRIBUTE_GROUPS(f2fs_feat); @@ -844,6 +886,40 @@ static struct attribute *f2fs_stat_attrs[] = { }; ATTRIBUTE_GROUPS(f2fs_stat); +F2FS_SB_FEATURE_RO_ATTR(encryption, ENCRYPT); +F2FS_SB_FEATURE_RO_ATTR(block_zoned, BLKZONED); +F2FS_SB_FEATURE_RO_ATTR(extra_attr, EXTRA_ATTR); +F2FS_SB_FEATURE_RO_ATTR(project_quota, PRJQUOTA); +F2FS_SB_FEATURE_RO_ATTR(inode_checksum, INODE_CHKSUM); +F2FS_SB_FEATURE_RO_ATTR(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR); +F2FS_SB_FEATURE_RO_ATTR(quota_ino, QUOTA_INO); +F2FS_SB_FEATURE_RO_ATTR(inode_crtime, INODE_CRTIME); +F2FS_SB_FEATURE_RO_ATTR(lost_found, LOST_FOUND); +F2FS_SB_FEATURE_RO_ATTR(verity, VERITY); +F2FS_SB_FEATURE_RO_ATTR(sb_checksum, SB_CHKSUM); +F2FS_SB_FEATURE_RO_ATTR(casefold, CASEFOLD); +F2FS_SB_FEATURE_RO_ATTR(compression, COMPRESSION); +F2FS_SB_FEATURE_RO_ATTR(readonly, RO); + +static struct attribute *f2fs_sb_feat_attrs[] = { + ATTR_LIST(sb_encryption), + ATTR_LIST(sb_block_zoned), + ATTR_LIST(sb_extra_attr), + ATTR_LIST(sb_project_quota), + ATTR_LIST(sb_inode_checksum), + ATTR_LIST(sb_flexible_inline_xattr), + ATTR_LIST(sb_quota_ino), + ATTR_LIST(sb_inode_crtime), + ATTR_LIST(sb_lost_found), + ATTR_LIST(sb_verity), + ATTR_LIST(sb_sb_checksum), + ATTR_LIST(sb_casefold), + ATTR_LIST(sb_compression), + ATTR_LIST(sb_readonly), + NULL, +}; +ATTRIBUTE_GROUPS(f2fs_sb_feat); + static const struct sysfs_ops f2fs_attr_ops = { .show = f2fs_attr_show, .store = f2fs_attr_store, @@ -910,6 +986,33 @@ static struct kobj_type f2fs_stat_ktype = { .release = f2fs_stat_kobj_release, }; +static ssize_t f2fs_sb_feat_attr_show(struct kobject *kobj, + struct attribute *attr, char *buf) +{ + struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, + s_feature_list_kobj); + struct f2fs_attr *a = container_of(attr, struct f2fs_attr, attr); + + return a->show ? a->show(a, sbi, buf) : 0; +} + +static void f2fs_feature_list_kobj_release(struct kobject *kobj) +{ + struct f2fs_sb_info *sbi = container_of(kobj, struct f2fs_sb_info, + s_feature_list_kobj); + complete(&sbi->s_feature_list_kobj_unregister); +} + +static const struct sysfs_ops f2fs_feature_list_attr_ops = { + .show = f2fs_sb_feat_attr_show, +}; + +static struct kobj_type f2fs_feature_list_ktype = { + .default_groups = f2fs_sb_feat_groups, + .sysfs_ops = &f2fs_feature_list_attr_ops, + .release = f2fs_feature_list_kobj_release, +}; + static int __maybe_unused segment_info_seq_show(struct seq_file *seq, void *offset) { @@ -1126,6 +1229,14 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi) if (err) goto put_stat_kobj; + sbi->s_feature_list_kobj.kset = &f2fs_kset; + init_completion(&sbi->s_feature_list_kobj_unregister); + err = kobject_init_and_add(&sbi->s_feature_list_kobj, + &f2fs_feature_list_ktype, + &sbi->s_kobj, "feature_list"); + if (err) + goto put_feature_list_kobj; + if (f2fs_proc_root) sbi->s_proc = proc_mkdir(sb->s_id, f2fs_proc_root); @@ -1140,6 +1251,9 @@ int f2fs_register_sysfs(struct f2fs_sb_info *sbi) victim_bits_seq_show, sb); } return 0; +put_feature_list_kobj: + kobject_put(&sbi->s_feature_list_kobj); + wait_for_completion(&sbi->s_feature_list_kobj_unregister); put_stat_kobj: kobject_put(&sbi->s_stat_kobj); wait_for_completion(&sbi->s_stat_kobj_unregister); @@ -1162,6 +1276,9 @@ void f2fs_unregister_sysfs(struct f2fs_sb_info *sbi) kobject_del(&sbi->s_stat_kobj); kobject_put(&sbi->s_stat_kobj); wait_for_completion(&sbi->s_stat_kobj_unregister); + kobject_del(&sbi->s_feature_list_kobj); + kobject_put(&sbi->s_feature_list_kobj); + wait_for_completion(&sbi->s_feature_list_kobj_unregister); kobject_del(&sbi->s_kobj); kobject_put(&sbi->s_kobj); diff --git a/fs/fuse/OWNERS b/fs/fuse/OWNERS deleted file mode 100644 index 6c04da7a65d5..000000000000 --- a/fs/fuse/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/fs/fuse/OWNERS diff --git a/fs/incfs/OWNERS b/fs/incfs/OWNERS deleted file mode 100644 index 17131f337364..000000000000 --- a/fs/incfs/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/fs/incfs/OWNERS diff --git a/fs/open.c b/fs/open.c index 0aabf1728fde..7b47f2b93675 100644 --- a/fs/open.c +++ b/fs/open.c @@ -34,6 +34,7 @@ #include #include "internal.h" +#include int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, struct file *filp) @@ -800,6 +801,7 @@ static int do_dentry_open(struct file *f, error = -ENODEV; goto cleanup_all; } + trace_android_vh_check_file_open(f); error = security_file_open(f); if (error) diff --git a/fs/pipe.c b/fs/pipe.c index 412b3b618994..6f5f97c0fdee 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -429,20 +429,20 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from) #endif /* - * Only wake up if the pipe started out empty, since - * otherwise there should be no readers waiting. + * Epoll nonsensically wants a wakeup whether the pipe + * was already empty or not. * * If it wasn't empty we try to merge new data into * the last buffer. * * That naturally merges small writes, but it also - * page-aligs the rest of the writes for large writes + * page-aligns the rest of the writes for large writes * spanning multiple pages. */ head = pipe->head; - was_empty = pipe_empty(head, pipe->tail); + was_empty = true; chars = total_len & (PAGE_SIZE-1); - if (chars && !was_empty) { + if (chars && !pipe_empty(head, pipe->tail)) { unsigned int mask = pipe->ring_size - 1; struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask]; int offset = buf->offset + buf->len; diff --git a/fs/proc/fd.c b/fs/proc/fd.c index 6157913911f8..6b634c0a9b6e 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -71,7 +71,7 @@ static int seq_show(struct seq_file *m, void *v) return 0; } -static int seq_fdinfo_open(struct inode *inode, struct file *file) +static int proc_fdinfo_access_allowed(struct inode *inode) { bool allowed = false; struct task_struct *task = get_proc_task(inode); @@ -85,6 +85,16 @@ static int seq_fdinfo_open(struct inode *inode, struct file *file) if (!allowed) return -EACCES; + return 0; +} + +static int seq_fdinfo_open(struct inode *inode, struct file *file) +{ + int ret = proc_fdinfo_access_allowed(inode); + + if (ret) + return ret; + return single_open(file, seq_show, inode); } @@ -365,12 +375,23 @@ static int proc_readfdinfo(struct file *file, struct dir_context *ctx) proc_fdinfo_instantiate); } +static int proc_open_fdinfo(struct inode *inode, struct file *file) +{ + int ret = proc_fdinfo_access_allowed(inode); + + if (ret) + return ret; + + return 0; +} + const struct inode_operations proc_fdinfo_inode_operations = { .lookup = proc_lookupfdinfo, .setattr = proc_setattr, }; const struct file_operations proc_fdinfo_operations = { + .open = proc_open_fdinfo, .read = generic_read_dir, .iterate_shared = proc_readfdinfo, .llseek = generic_file_llseek, diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index fefe3d391d3a..7183fe4b5f72 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "internal.h" #define RAMOOPS_KERNMSG_HDR "====" @@ -633,6 +634,7 @@ static int ramoops_parse_dt(struct platform_device *pdev, { struct device_node *of_node = pdev->dev.of_node; struct device_node *parent_node; + struct reserved_mem *rmem; struct resource *res; u32 value; int ret; @@ -641,13 +643,20 @@ static int ramoops_parse_dt(struct platform_device *pdev, res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { - dev_err(&pdev->dev, - "failed to locate DT /reserved-memory resource\n"); - return -EINVAL; + rmem = of_reserved_mem_lookup(of_node); + if (rmem) { + pdata->mem_size = rmem->size; + pdata->mem_address = rmem->base; + } else { + dev_err(&pdev->dev, + "failed to locate DT /reserved-memory resource\n"); + return -EINVAL; + } + } else { + pdata->mem_size = resource_size(res); + pdata->mem_address = res->start; } - pdata->mem_size = resource_size(res); - pdata->mem_address = res->start; /* * Setting "unbuffered" is deprecated and will be ignored if * "mem_type" is also specified. diff --git a/include/OWNERS b/include/OWNERS deleted file mode 100644 index ab8142b271b4..000000000000 --- a/include/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/include/OWNERS diff --git a/include/linux/OWNERS b/include/linux/OWNERS deleted file mode 100644 index c88808c07797..000000000000 --- a/include/linux/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/include/linux/OWNERS diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 6cc93ab5b809..55e2f02bd45a 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -17,6 +17,7 @@ #include #include #include +#include #define AMBA_NR_IRQS 9 #define AMBA_CID 0xb105f00d @@ -71,6 +72,8 @@ struct amba_device { struct amba_cs_uci_id uci; unsigned int irq[AMBA_NR_IRQS]; char *driver_override; + + ANDROID_KABI_RESERVE(1); }; struct amba_driver { @@ -79,6 +82,8 @@ struct amba_driver { void (*remove)(struct amba_device *); void (*shutdown)(struct amba_device *); const struct amba_id *id_table; + + ANDROID_KABI_RESERVE(1); }; /* diff --git a/include/linux/android_debug_symbols.h b/include/linux/android_debug_symbols.h index 3fc44fb36fb7..6a54e9116e3d 100644 --- a/include/linux/android_debug_symbols.h +++ b/include/linux/android_debug_symbols.h @@ -29,6 +29,13 @@ enum android_debug_symbol { #endif #ifdef CONFIG_SWAP ADS_NR_SWAP_PAGES, +#endif +#ifdef CONFIG_MMU + ADS_MMAP_MIN_ADDR, +#endif + ADS_STACK_GUARD_GAP, +#ifdef CONFIG_SYSCTL + ADS_SYSCTL_LEGACY_VA_LAYOUT, #endif ADS_END }; @@ -43,6 +50,9 @@ enum android_debug_per_cpu_symbol { void *android_debug_symbol(enum android_debug_symbol symbol); void *android_debug_per_cpu_symbol(enum android_debug_per_cpu_symbol symbol); +void android_debug_for_each_module(int (*fn)(const char *mod_name, void *mod_addr, void *data), + void *data); + #else /* !CONFIG_ANDROID_DEBUG_SYMBOLS */ static inline void *android_debug_symbol(enum android_debug_symbol symbol) @@ -53,6 +63,9 @@ static inline void *android_debug_per_cpu_symbol(enum android_debug_per_cpu_symb { return NULL; } + +static inline void android_debug_for_each_module(int (*fn)(const char *mod_name, void *mod_addr, + void *data), void *data) {} #endif /* CONFIG_ANDROID_DEBUG_SYMBOLS */ #endif /* _ANDROID_DEBUG_SYMBOLS_H */ diff --git a/include/linux/backing-dev-defs.h b/include/linux/backing-dev-defs.h index fff9367a6348..f3314adb6a8d 100644 --- a/include/linux/backing-dev-defs.h +++ b/include/linux/backing-dev-defs.h @@ -13,6 +13,7 @@ #include #include #include +#include struct page; struct device; @@ -160,6 +161,9 @@ struct bdi_writeback { struct rcu_head rcu; }; #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct backing_dev_info { @@ -198,6 +202,9 @@ struct backing_dev_info { #ifdef CONFIG_DEBUG_FS struct dentry *debug_dir; #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; enum { diff --git a/include/linux/bio.h b/include/linux/bio.h index c6d765382926..5d6593db3b62 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -10,6 +10,7 @@ #include /* struct bio, bio_vec and BIO_* flags are defined in blk_types.h */ #include +#include #define BIO_DEBUG @@ -325,6 +326,10 @@ struct bio_integrity_payload { struct work_struct bip_work; /* I/O completion */ struct bio_vec *bip_vec; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + struct bio_vec bip_inline_vecs[];/* embedded bvec array */ }; @@ -698,6 +703,11 @@ struct bio_set { struct bio_list rescue_list; struct work_struct rescue_work; struct workqueue_struct *rescue_workqueue; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; struct biovec_slab { diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index f8ea27423d1d..a2aa73d8437a 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -139,10 +139,6 @@ struct blk_mq_hw_ctx { * shared across request queues. */ atomic_t nr_active; - /** - * @elevator_queued: Number of queued requests on hctx. - */ - atomic_t elevator_queued; /** @cpuhp_online: List to store request if CPU is going to die */ struct hlist_node cpuhp_online; @@ -398,7 +394,13 @@ enum { BLK_MQ_F_STACKING = 1 << 2, BLK_MQ_F_TAG_HCTX_SHARED = 1 << 3, BLK_MQ_F_BLOCKING = 1 << 5, + /* Do not allow an I/O scheduler to be configured. */ BLK_MQ_F_NO_SCHED = 1 << 6, + /* + * Select 'none' during queue registration in case of a single hwq + * or shared hwqs instead of 'mq-deadline'. + */ + BLK_MQ_F_NO_SCHED_BY_DEFAULT = 1 << 7, BLK_MQ_F_ALLOC_POLICY_START_BIT = 8, BLK_MQ_F_ALLOC_POLICY_BITS = 1, diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index a42b751da268..3fb97c2af669 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -48,6 +48,11 @@ struct block_device { /* Mutex for freeze */ struct mutex bd_fsfreeze_mutex; struct super_block *bd_fsfreeze_sb; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); } __randomize_layout; /* diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 668e6a732025..78eeb317027e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -26,6 +26,8 @@ #include #include #include +#include +#include struct module; struct scsi_ioctl_command; @@ -242,6 +244,8 @@ struct request { */ rq_end_io_fn *end_io; void *end_io_data; + + ANDROID_KABI_RESERVE(1); }; static inline bool blk_op_is_scsi(unsigned int op) @@ -346,6 +350,8 @@ struct queue_limits { unsigned char discard_misaligned; unsigned char raid_partial_stripes_expensive; enum blk_zoned_model zoned; + + ANDROID_KABI_RESERVE(1); }; typedef int (*report_zones_cb)(struct blk_zone *zone, unsigned int idx, @@ -588,6 +594,12 @@ struct request_queue { #define BLK_MAX_WRITE_HINTS 5 u64 write_hints[BLK_MAX_WRITE_HINTS]; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); + ANDROID_OEM_DATA(1); }; /* Keep blk_queue_flag_name[] in sync with the definitions below */ @@ -692,18 +704,6 @@ static inline bool queue_is_mq(struct request_queue *q) return q->mq_ops; } -#ifdef CONFIG_PM -static inline enum rpm_status queue_rpm_status(struct request_queue *q) -{ - return q->rpm_status; -} -#else -static inline enum rpm_status queue_rpm_status(struct request_queue *q) -{ - return RPM_ACTIVE; -} -#endif - static inline enum blk_zoned_model blk_queue_zoned_model(struct request_queue *q) { @@ -1868,6 +1868,10 @@ struct block_device_operations { char *(*devnode)(struct gendisk *disk, umode_t *mode); struct module *owner; const struct pr_ops *pr_ops; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_OEM_DATA(1); }; #ifdef CONFIG_COMPAT diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 6460b57b4b79..62ff6b56a929 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -21,6 +21,7 @@ #include #include #include +#include struct bpf_verifier_env; struct bpf_verifier_log; @@ -132,6 +133,9 @@ struct bpf_map_ops { /* bpf_iter info used to open a seq_file */ const struct bpf_iter_seq_info *iter_seq_info; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct bpf_map_memory { @@ -218,6 +222,8 @@ struct bpf_map_dev_ops { int (*map_update_elem)(struct bpf_offloaded_map *map, void *key, void *value, u64 flags); int (*map_delete_elem)(struct bpf_offloaded_map *map, void *key); + + ANDROID_KABI_RESERVE(1); }; struct bpf_offloaded_map { @@ -459,6 +465,7 @@ struct bpf_verifier_ops { const struct btf_type *t, int off, int size, enum bpf_access_type atype, u32 *next_btf_id); + ANDROID_KABI_RESERVE(1); }; struct bpf_prog_offload_ops { @@ -474,6 +481,7 @@ struct bpf_prog_offload_ops { int (*prepare)(struct bpf_prog *prog); int (*translate)(struct bpf_prog *prog); void (*destroy)(struct bpf_prog *prog); + ANDROID_KABI_RESERVE(1); }; struct bpf_prog_offload { @@ -851,6 +859,7 @@ struct bpf_prog_aux { struct work_struct work; struct rcu_head rcu; }; + ANDROID_KABI_RESERVE(1); }; struct bpf_array_aux { diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 2739a6431b9e..b83f1dd5c719 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -7,6 +7,7 @@ #include /* for enum bpf_reg_type */ #include /* for MAX_BPF_STACK */ #include +#include /* Maximum variable offset umax_value permitted when resolving memory accesses. * In practice this is far bigger than any realistic pointer offset; this limit @@ -370,6 +371,8 @@ struct bpf_subprog_info { bool has_tail_call; bool tail_call_reachable; bool has_ld_abs; + + ANDROID_KABI_RESERVE(1); }; /* single container for all structs @@ -425,6 +428,9 @@ struct bpf_verifier_env { u32 peak_states; /* longest register parentage chain walked for liveness marking */ u32 longest_mark_read_walk; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; __printf(2, 0) void bpf_verifier_vlog(struct bpf_verifier_log *log, diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index fee0b5547cd0..8c193033604f 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h @@ -110,6 +110,7 @@ enum { CFTYPE_NO_PREFIX = (1 << 3), /* (DON'T USE FOR NEW FILES) no subsys prefix */ CFTYPE_WORLD_WRITABLE = (1 << 4), /* (DON'T USE FOR NEW FILES) S_IWUGO */ CFTYPE_DEBUG = (1 << 5), /* create when cgroup_debug */ + CFTYPE_PRESSURE = (1 << 6), /* only if pressure feature is enabled */ /* internal flags, do not use outside cgroup core proper */ __CFTYPE_ONLY_ON_DFL = (1 << 16), /* only on default hierarchy */ diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 618838c48313..67b2190b1dae 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -66,6 +67,8 @@ struct css_task_iter { struct css_set *cur_dcset; struct task_struct *cur_task; struct list_head iters_node; /* css_set->task_iters */ + + ANDROID_KABI_RESERVE(1); }; extern struct cgroup_root cgrp_dfl_root; @@ -676,6 +679,8 @@ static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) return &cgrp->psi; } +bool cgroup_psi_enabled(void); + static inline void cgroup_init_kthreadd(void) { /* @@ -735,6 +740,11 @@ static inline struct psi_group *cgroup_psi(struct cgroup *cgrp) return NULL; } +static inline bool cgroup_psi_enabled(void) +{ + return false; +} + static inline bool task_under_cgroup_hierarchy(struct task_struct *task, struct cgroup *ancestor) { diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h index 5f5730c1d324..b6c42ce7f65b 100644 --- a/include/linux/cleancache.h +++ b/include/linux/cleancache.h @@ -5,6 +5,7 @@ #include #include #include +#include #define CLEANCACHE_NO_POOL -1 #define CLEANCACHE_NO_BACKEND -2 @@ -36,6 +37,7 @@ struct cleancache_ops { void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t); void (*invalidate_inode)(int, struct cleancache_filekey); void (*invalidate_fs)(int); + ANDROID_OEM_DATA(1); }; extern int cleancache_register_ops(const struct cleancache_ops *ops); diff --git a/include/linux/cma.h b/include/linux/cma.h index d6c02d08ddbc..4f29ac17067d 100644 --- a/include/linux/cma.h +++ b/include/linux/cma.h @@ -22,6 +22,15 @@ struct cma; +struct cma_alloc_info { + unsigned long nr_migrated; + unsigned long nr_reclaimed; + unsigned long nr_mapped; + unsigned int nr_isolate_fail; + unsigned int nr_migrate_fail; + unsigned int nr_test_fail; +}; + extern unsigned long totalcma_pages; extern phys_addr_t cma_get_base(const struct cma *cma); extern unsigned long cma_get_size(const struct cma *cma); diff --git a/include/linux/compaction.h b/include/linux/compaction.h index 5734e3cf4792..f1eb9f943357 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h @@ -85,6 +85,8 @@ extern int sysctl_compact_memory; extern unsigned int sysctl_compaction_proactiveness; extern int sysctl_compaction_handler(struct ctl_table *table, int write, void *buffer, size_t *length, loff_t *ppos); +extern int compaction_proactiveness_sysctl_handler(struct ctl_table *table, + int write, void *buffer, size_t *length, loff_t *ppos); extern int sysctl_extfrag_threshold; extern int sysctl_compact_unevictable_allowed; diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 1366cfbfdc78..843bb056b8c6 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -195,6 +195,10 @@ enum cpuhp_state { CPUHP_AP_X86_KVM_CLK_ONLINE, CPUHP_AP_DTPM_CPU_ONLINE, CPUHP_AP_ACTIVE, + CPUHP_ANDROID_RESERVED_1, + CPUHP_ANDROID_RESERVED_2, + CPUHP_ANDROID_RESERVED_3, + CPUHP_ANDROID_RESERVED_4, CPUHP_ONLINE, }; diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index bd605b5585cf..4b51019dd2b8 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -14,6 +14,7 @@ #include #include #include +#include #define CPUIDLE_STATE_MAX 10 #define CPUIDLE_NAME_LEN 16 @@ -110,6 +111,8 @@ struct cpuidle_device { cpumask_t coupled_cpus; struct cpuidle_coupled *coupled; #endif + + ANDROID_KABI_RESERVE(1); }; DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); @@ -135,6 +138,8 @@ struct cpuidle_driver { /* preferred governor to switch at register time */ const char *governor; + + ANDROID_KABI_RESERVE(1); }; #ifdef CONFIG_CPU_IDLE diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 49d0b6f732f2..8836cf7c4874 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -13,6 +13,7 @@ #include #include #include +#include struct path; struct vfsmount; @@ -118,6 +119,9 @@ struct dentry { struct hlist_bl_node d_in_lookup_hash; /* only for in-lookup ones */ struct rcu_head d_rcu; } d_u; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); } __randomize_layout; /* @@ -148,6 +152,10 @@ struct dentry_operations { int (*d_manage)(const struct path *, bool); struct dentry *(*d_real)(struct dentry *, const struct inode *); void (*d_canonical_path)(const struct path *, struct path *); + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); } ____cacheline_aligned; /* diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 8858ffd6fb10..ccb909edca38 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -13,6 +13,7 @@ #include #include #include +#include struct dm_dev; struct dm_target; @@ -198,6 +199,9 @@ struct target_type { dm_dax_copy_iter_fn dax_copy_to_iter; dm_dax_zero_page_range_fn dax_zero_page_range; + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + /* For internal device-mapper use. */ struct list_head list; }; @@ -349,6 +353,9 @@ struct dm_target { * Set if we need to limit the number of in-flight bios when swapping. */ bool limit_swap_bios:1; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; void *dm_per_bio_data(struct bio *bio, size_t data_size); diff --git a/include/linux/device.h b/include/linux/device.h index 4e1e42798879..540a14f1e052 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -30,6 +30,7 @@ #include #include #include +#include #include struct device; @@ -553,6 +554,14 @@ struct device { #ifdef CONFIG_DMA_OPS_BYPASS bool dma_ops_bypass : 1; #endif + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); + ANDROID_KABI_RESERVE(5); + ANDROID_KABI_RESERVE(6); + ANDROID_KABI_RESERVE(7); + ANDROID_KABI_RESERVE(8); }; /** diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index 1ea5e1d1545b..93ed259748f8 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -112,6 +112,11 @@ struct bus_type { struct lock_class_key lock_key; bool need_parent_lock; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; extern int __must_check bus_register(struct bus_type *bus); diff --git a/include/linux/device/class.h b/include/linux/device/class.h index 04e983415c3d..9923e4835526 100644 --- a/include/linux/device/class.h +++ b/include/linux/device/class.h @@ -76,7 +76,11 @@ struct class { const struct dev_pm_ops *pm; struct subsys_private *p; + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; struct class_dev_iter { diff --git a/include/linux/device/driver.h b/include/linux/device/driver.h index ee7ba5b5417e..d5ad474e4fab 100644 --- a/include/linux/device/driver.h +++ b/include/linux/device/driver.h @@ -118,6 +118,11 @@ struct device_driver { void (*coredump) (struct device *dev); struct driver_private *p; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index f1242b50f627..63ffe57a61d5 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -21,6 +21,7 @@ #include #include #include +#include struct device; struct dma_buf; @@ -353,6 +354,9 @@ struct dma_buf_ops { * will be populated with the buffer's flags. */ int (*get_flags)(struct dma_buf *dmabuf, unsigned long *flags); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /** @@ -379,11 +383,6 @@ struct dma_buf_ops { * @cb_excl: for userspace poll support * @cb_shared: for userspace poll support * @sysfs_entry: for exposing information about this buffer in sysfs. - * The attachment_uid member of @sysfs_entry is protected by dma_resv lock - * and is incremented on each attach. - * @mmap_count: number of times buffer has been mmapped. - * @exp_vm_ops: the vm ops provided by the buffer exporter. - * @vm_ops: the overridden vm_ops used to track mmap_count of the buffer. * * This represents a shared buffer, created by calling dma_buf_export(). The * userspace representation is a normal file descriptor, which can be created by @@ -424,13 +423,11 @@ struct dma_buf { struct dma_buf_sysfs_entry { struct kobject kobj; struct dma_buf *dmabuf; - unsigned int attachment_uid; - struct kset *attach_stats_kset; } *sysfs_entry; - int mmap_count; - const struct vm_operations_struct *exp_vm_ops; - struct vm_operations_struct vm_ops; #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /** @@ -482,7 +479,6 @@ struct dma_buf_attach_ops { * @importer_priv: importer specific attachment data. * @dma_map_attrs: DMA attributes to be used when the exporter maps the buffer * through dma_buf_map_attachment. - * @sysfs_entry: For exposing information about this attachment in sysfs. * * This structure holds the attachment information between the dma_buf buffer * and its user device(s). The list contains one attachment struct per device @@ -504,13 +500,9 @@ struct dma_buf_attachment { void *importer_priv; void *priv; unsigned long dma_map_attrs; -#ifdef CONFIG_DMABUF_SYSFS_STATS - /* for sysfs stats */ - struct dma_buf_attach_sysfs_entry { - struct kobject kobj; - unsigned int map_counter; - } *sysfs_entry; -#endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /** @@ -534,6 +526,9 @@ struct dma_buf_export_info { int flags; struct dma_resv *resv; void *priv; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /** diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 493a047ed0a2..3f8dcaa83a49 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -12,6 +12,7 @@ #include #include #include +#include #include /** @@ -941,6 +942,11 @@ struct dma_device { void (*dbg_summary_show)(struct seq_file *s, struct dma_device *dev); struct dentry *dbg_dev_root; #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; static inline int dmaengine_slave_config(struct dma_chan *chan, diff --git a/include/linux/elevator.h b/include/linux/elevator.h index bc26b4e11f62..0c75ed0604aa 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -4,6 +4,7 @@ #include #include +#include #ifdef CONFIG_BLOCK @@ -50,6 +51,11 @@ struct elevator_mq_ops { struct request *(*next_request)(struct request_queue *, struct request *); void (*init_icq)(struct io_cq *); void (*exit_icq)(struct io_cq *); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define ELV_NAME_MAX (16) @@ -86,6 +92,9 @@ struct elevator_type /* managed by elevator core */ char icq_cache_name[ELV_NAME_MAX + 6]; /* elvname + "_io_cq" */ struct list_head list; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; #define ELV_HASH_BITS 6 @@ -172,6 +181,8 @@ extern struct request *elv_rb_find(struct rb_root *, sector_t); /* Supports zoned block devices sequential write constraint */ #define ELEVATOR_F_ZBD_SEQ_WRITE (1U << 0) +/* Supports scheduling on multiple hardware queues */ +#define ELEVATOR_F_MQ_AWARE (1U << 1) #endif /* CONFIG_BLOCK */ #endif diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index f93000c3a127..d445150c5350 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -34,6 +34,7 @@ #define F2FS_ROOT_INO(sbi) ((sbi)->root_ino_num) #define F2FS_NODE_INO(sbi) ((sbi)->node_ino_num) #define F2FS_META_INO(sbi) ((sbi)->meta_ino_num) +#define F2FS_COMPRESS_INO(sbi) (NM_I(sbi)->max_nid) #define F2FS_MAX_QUOTAS 3 diff --git a/include/linux/fips.h b/include/linux/fips.h index c6961e932fef..83f5d6f7c62d 100644 --- a/include/linux/fips.h +++ b/include/linux/fips.h @@ -2,7 +2,15 @@ #ifndef _FIPS_H #define _FIPS_H -#ifdef CONFIG_CRYPTO_FIPS +#ifdef BUILD_FIPS140_KO +/* + * In fips140.ko, enable the behavior that the upstream fips_enabled flag + * controls, such as the XTS weak key check. + */ +#define fips_enabled 1 +#define CONFIG_CRYPTO_FIPS 1 + +#elif defined(CONFIG_CRYPTO_FIPS) extern int fips_enabled; extern struct atomic_notifier_head fips_fail_notif_chain; diff --git a/include/linux/fs.h b/include/linux/fs.h index 342a93553eaf..090cb2938fdc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -39,9 +39,11 @@ #include #include #include +#include #include #include +#include struct backing_dev_info; struct bdi_writeback; @@ -413,6 +415,11 @@ struct address_space_operations { int (*swap_activate)(struct swap_info_struct *sis, struct file *file, sector_t *span); void (*swap_deactivate)(struct file *file); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; extern const struct address_space_operations empty_aops; @@ -468,6 +475,11 @@ struct address_space { spinlock_t private_lock; struct list_head private_list; void *private_data; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); } __attribute__((aligned(sizeof(long)))) __randomize_layout; /* * On most architectures that alignment is already the case; but @@ -718,6 +730,9 @@ struct inode { #endif void *i_private; /* fs or device private pointer */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); } __randomize_layout; struct timespec64 timestamp_truncate(struct timespec64 t, struct inode *inode); @@ -952,6 +967,10 @@ struct file { struct address_space *f_mapping; errseq_t f_wb_err; errseq_t f_sb_err; /* for syncfs */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_OEM_DATA(1); } __randomize_layout __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */ @@ -1011,6 +1030,9 @@ struct file_lock; struct file_lock_operations { void (*fl_copy_lock)(struct file_lock *, struct file_lock *); void (*fl_release_private)(struct file_lock *); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct lock_manager_operations { @@ -1022,6 +1044,9 @@ struct lock_manager_operations { int (*lm_change)(struct file_lock *, int, struct list_head *); void (*lm_setup)(struct file_lock *, void **); bool (*lm_breaker_owns_lease)(struct file_lock *); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct lock_manager { @@ -1095,6 +1120,10 @@ struct file_lock { unsigned int debug_id; } afs; } fl_u; + + struct list_head android_reserved1; /* not a macro as we might just need it as-is */ + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); } __randomize_layout; struct file_lock_context { @@ -1547,6 +1576,11 @@ struct super_block { spinlock_t s_inode_wblist_lock; struct list_head s_inodes_wb; /* writeback inodes */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); } __randomize_layout; /* Helper functions so that in most cases filesystems will @@ -1859,6 +1893,11 @@ struct file_operations { struct file *file_out, loff_t pos_out, loff_t len, unsigned int remap_flags); int (*fadvise)(struct file *, loff_t, loff_t, int); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); } __randomize_layout; struct inode_operations { @@ -1889,6 +1928,11 @@ struct inode_operations { umode_t create_mode); int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*set_acl)(struct inode *, struct posix_acl *, int); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); } ____cacheline_aligned; static inline ssize_t call_read_iter(struct file *file, struct kiocb *kio, @@ -1965,6 +2009,11 @@ struct super_operations { struct shrink_control *); long (*free_cached_objects)(struct super_block *, struct shrink_control *); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; /* @@ -2252,6 +2301,11 @@ struct file_system_type { struct lock_class_key i_lock_key; struct lock_class_key i_mutex_key; struct lock_class_key i_mutex_dir_key; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME) diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 554b219c62cd..3eb7cf0cb34d 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -70,6 +70,13 @@ struct fscrypt_operations { int (*get_num_devices)(struct super_block *sb); void (*get_devices)(struct super_block *sb, struct request_queue **devs); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); + + ANDROID_OEM_DATA_ARRAY(1, 4); }; static inline struct fscrypt_info *fscrypt_get_info(const struct inode *inode) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 918647ffa7df..fbed5dd273db 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -39,16 +39,18 @@ struct vm_area_struct; #define ___GFP_HARDWALL 0x100000u #define ___GFP_THISNODE 0x200000u #define ___GFP_ACCOUNT 0x400000u +#define ___GFP_ZEROTAGS 0x800000u +#define ___GFP_SKIP_KASAN_POISON 0x1000000u #ifdef CONFIG_CMA -#define ___GFP_CMA 0x800000u +#define ___GFP_CMA 0x2000000u #else #define ___GFP_CMA 0 #endif #ifdef CONFIG_LOCKDEP #ifdef CONFIG_CMA -#define ___GFP_NOLOCKDEP 0x1000000u +#define ___GFP_NOLOCKDEP 0x4000000u #else -#define ___GFP_NOLOCKDEP 0x800000u +#define ___GFP_NOLOCKDEP 0x2000000u #endif #else #define ___GFP_NOLOCKDEP 0 @@ -226,19 +228,28 @@ struct vm_area_struct; * %__GFP_COMP address compound page metadata. * * %__GFP_ZERO returns a zeroed page on success. + * + * %__GFP_ZEROTAGS returns a page with zeroed memory tags on success, if + * __GFP_ZERO is set. + * + * %__GFP_SKIP_KASAN_POISON returns a page which does not need to be poisoned + * on deallocation. Typically used for userspace pages. Currently only has an + * effect in HW tags mode. */ #define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN) #define __GFP_COMP ((__force gfp_t)___GFP_COMP) #define __GFP_ZERO ((__force gfp_t)___GFP_ZERO) +#define __GFP_ZEROTAGS ((__force gfp_t)___GFP_ZEROTAGS) +#define __GFP_SKIP_KASAN_POISON ((__force gfp_t)___GFP_SKIP_KASAN_POISON) /* Disable lockdep for GFP context tracking */ #define __GFP_NOLOCKDEP ((__force gfp_t)___GFP_NOLOCKDEP) /* Room for N __GFP_FOO bits */ #ifdef CONFIG_CMA -#define __GFP_BITS_SHIFT (24 + IS_ENABLED(CONFIG_LOCKDEP)) +#define __GFP_BITS_SHIFT (26 + IS_ENABLED(CONFIG_LOCKDEP)) #else -#define __GFP_BITS_SHIFT (23 + IS_ENABLED(CONFIG_LOCKDEP)) +#define __GFP_BITS_SHIFT (25 + IS_ENABLED(CONFIG_LOCKDEP)) #endif #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) @@ -320,7 +331,8 @@ struct vm_area_struct; #define GFP_DMA __GFP_DMA #define GFP_DMA32 __GFP_DMA32 #define GFP_HIGHUSER (GFP_USER | __GFP_HIGHMEM) -#define GFP_HIGHUSER_MOVABLE (GFP_HIGHUSER | __GFP_MOVABLE) +#define GFP_HIGHUSER_MOVABLE (GFP_HIGHUSER | __GFP_MOVABLE | \ + __GFP_SKIP_KASAN_POISON) #define GFP_TRANSHUGE_LIGHT ((GFP_HIGHUSER_MOVABLE | __GFP_COMP | \ __GFP_NOMEMALLOC | __GFP_NOWARN) & ~__GFP_RECLAIM) #define GFP_TRANSHUGE (GFP_TRANSHUGE_LIGHT | __GFP_DIRECT_RECLAIM) @@ -630,9 +642,24 @@ static inline bool pm_suspended_storage(void) #endif /* CONFIG_PM_SLEEP */ #ifdef CONFIG_CONTIG_ALLOC +extern unsigned long pfn_max_align_up(unsigned long pfn); + +#define ACR_ERR_ISOLATE (1 << 0) +#define ACR_ERR_MIGRATE (1 << 1) +#define ACR_ERR_TEST (1 << 2) + +struct acr_info { + unsigned long nr_mapped; + unsigned long nr_migrated; + unsigned long nr_reclaimed; + unsigned int err; + unsigned long failed_pfn; +}; + /* The below functions must be run on a range from a single zone. */ extern int alloc_contig_range(unsigned long start, unsigned long end, - unsigned migratetype, gfp_t gfp_mask); + unsigned migratetype, gfp_t gfp_mask, + struct acr_info *info); extern struct page *alloc_contig_pages(unsigned long nr_pages, gfp_t gfp_mask, int nid, nodemask_t *nodemask); #endif diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 8e144306e262..ff3e6e3eb9c1 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -10,6 +10,7 @@ #include #include #include +#include struct gpio_desc; struct of_phandle_args; @@ -266,6 +267,9 @@ struct gpio_irq_chip { * Store old irq_chip irq_mask callback */ void (*irq_mask)(struct irq_data *data); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /** @@ -469,6 +473,9 @@ struct gpio_chip { int (*of_xlate)(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags); #endif /* CONFIG_OF_GPIO */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; extern const char *gpiochip_is_requested(struct gpio_chip *gc, diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 299a6e493cfa..220e92c80095 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h @@ -265,6 +265,14 @@ static inline void clear_highpage(struct page *page) kunmap_atomic(kaddr); } +#ifndef __HAVE_ARCH_TAG_CLEAR_HIGHPAGE + +static inline void tag_clear_highpage(struct page *page) +{ +} + +#endif + static inline void zero_user_segments(struct page *page, unsigned start1, unsigned end1, unsigned start2, unsigned end2) diff --git a/include/linux/input.h b/include/linux/input.h index 56f2fd32e609..4d752cedf581 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -7,6 +7,7 @@ #include #include +#include #include /* Implementation details, userspace should not care about these */ #define ABS_MT_FIRST ABS_MT_TOUCH_MAJOR @@ -201,6 +202,11 @@ struct input_dev { bool devres_managed; ktime_t timestamp[INPUT_CLK_MAX]; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define to_input_dev(d) container_of(d, struct input_dev, dev) @@ -320,6 +326,8 @@ struct input_handler { struct list_head h_list; struct list_head node; + + ANDROID_KABI_RESERVE(1); }; /** @@ -346,6 +354,8 @@ struct input_handle { struct list_head d_node; struct list_head h_node; + + ANDROID_KABI_RESERVE(1); }; struct input_dev __must_check *input_allocate_device(void); @@ -550,6 +560,9 @@ struct ff_device { int max_effects; struct ff_effect *effects; + + ANDROID_KABI_RESERVE(1); + struct file *effect_owners[]; }; diff --git a/include/linux/iomap.h b/include/linux/iomap.h index 8a6add3abb3f..257ffd4d921f 100644 --- a/include/linux/iomap.h +++ b/include/linux/iomap.h @@ -89,6 +89,8 @@ struct iomap { void *inline_data; void *private; /* filesystem private */ const struct iomap_page_ops *page_ops; + + ANDROID_KABI_RESERVE(1); }; static inline sector_t diff --git a/include/linux/iommu.h b/include/linux/iommu.h index f94cfde78201..3b97491ed0a3 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -32,18 +32,17 @@ */ #define IOMMU_PRIV (1 << 5) /* - * Non-coherent masters can use this page protection flag to set cacheable - * memory attributes for only a transparent outer level of cache, also known as - * the last-level or system cache. + * Allow caching in a transparent outer level of cache, also known as + * the last-level or system cache, with a read/write allocation policy. + * Does not depend on IOMMU_CACHE. Incompatible with IOMMU_SYS_CACHE_NWA. */ -#define IOMMU_SYS_CACHE_ONLY (1 << 6) +#define IOMMU_SYS_CACHE (1 << 6) /* - * Non-coherent masters can use this page protection flag to set cacheable - * memory attributes with a no write allocation cache policy for only a - * transparent outer level of cache, also known as the last-level or system - * cache. + * Allow caching in a transparent outer level of cache, also known as + * the last-level or system cache, with a read allocation policy. + * Does not depend on IOMMU_CACHE. Incompatible with IOMMU_SYS_CACHE. */ -#define IOMMU_SYS_CACHE_ONLY_NWA (1 << 7) +#define IOMMU_SYS_CACHE_NWA (1 << 7) #ifdef CONFIG_NO_GKI diff --git a/include/linux/irq.h b/include/linux/irq.h index a36d35c25996..a29a6de8090d 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -72,6 +72,7 @@ enum irqchip_irq_state; * mechanism and from core side polling. * IRQ_DISABLE_UNLAZY - Disable lazy irq disable * IRQ_HIDDEN - Don't show up in /proc/interrupts + * IRQ_RAW - Skip tick management and irqtime accounting */ enum { IRQ_TYPE_NONE = 0x00000000, @@ -99,6 +100,7 @@ enum { IRQ_IS_POLLED = (1 << 18), IRQ_DISABLE_UNLAZY = (1 << 19), IRQ_HIDDEN = (1 << 20), + IRQ_RAW = (1 << 21), }; #define IRQF_MODIFY_MASK \ @@ -751,6 +753,9 @@ void irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle, void *data); +void __irq_modify_status(unsigned int irq, unsigned long clr, + unsigned long set, unsigned long mask); + void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set); static inline void irq_set_status_flags(unsigned int irq, unsigned long set) diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index ffb0a87055b1..43348c487c8e 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -693,6 +693,20 @@ int its_init(struct fwnode_handle *handle, struct rdists *rdists, struct irq_domain *domain); int mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent); +struct gic_chip_data { + struct fwnode_handle *fwnode; + void __iomem *dist_base; + struct redist_region *redist_regions; + struct rdists rdists; + struct irq_domain *domain; + u64 redist_stride; + u32 nr_redist_regions; + u64 flags; + bool has_rss; + unsigned int ppi_nr; + struct partition_desc **ppi_descs; +}; + static inline bool gic_enable_sre(void) { u32 val; diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 32809624d422..6175b3e0d220 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -113,7 +113,7 @@ struct static_key { #endif /* CONFIG_JUMP_LABEL */ #endif /* __ASSEMBLY__ */ -#ifdef CONFIG_JUMP_LABEL +#if defined(CONFIG_JUMP_LABEL) && !defined(BUILD_FIPS140_KO) #include #ifndef __ASSEMBLY__ @@ -188,7 +188,28 @@ enum jump_label_type { struct module; -#ifdef CONFIG_JUMP_LABEL +#ifdef BUILD_FIPS140_KO + +static inline int static_key_count(struct static_key *key) +{ + return atomic_read(&key->enabled); +} + +static __always_inline bool static_key_false(struct static_key *key) +{ + if (unlikely(static_key_count(key) > 0)) + return true; + return false; +} + +static __always_inline bool static_key_true(struct static_key *key) +{ + if (likely(static_key_count(key) > 0)) + return true; + return false; +} + +#elif defined(CONFIG_JUMP_LABEL) #define JUMP_TYPE_FALSE 0UL #define JUMP_TYPE_TRUE 1UL @@ -393,7 +414,7 @@ extern bool ____wrong_branch_error(void); static_key_count((struct static_key *)x) > 0; \ }) -#ifdef CONFIG_JUMP_LABEL +#if defined(CONFIG_JUMP_LABEL) && !defined(BUILD_FIPS140_KO) /* * Combine the right initial value (type) with the right branch order diff --git a/include/linux/kasan.h b/include/linux/kasan.h index b1678a61e6a7..a1c7ce5f3e4f 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -2,6 +2,7 @@ #ifndef _LINUX_KASAN_H #define _LINUX_KASAN_H +#include #include #include @@ -79,14 +80,6 @@ static inline void kasan_disable_current(void) {} #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */ -#ifdef CONFIG_KASAN - -struct kasan_cache { - int alloc_meta_offset; - int free_meta_offset; - bool is_kmalloc; -}; - #ifdef CONFIG_KASAN_HW_TAGS DECLARE_STATIC_KEY_FALSE(kasan_flag_enabled); @@ -101,11 +94,14 @@ static inline bool kasan_has_integrated_init(void) return kasan_enabled(); } +void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags); +void kasan_free_pages(struct page *page, unsigned int order); + #else /* CONFIG_KASAN_HW_TAGS */ static inline bool kasan_enabled(void) { - return true; + return IS_ENABLED(CONFIG_KASAN); } static inline bool kasan_has_integrated_init(void) @@ -113,8 +109,30 @@ static inline bool kasan_has_integrated_init(void) return false; } +static __always_inline void kasan_alloc_pages(struct page *page, + unsigned int order, gfp_t flags) +{ + /* Only available for integrated init. */ + BUILD_BUG(); +} + +static __always_inline void kasan_free_pages(struct page *page, + unsigned int order) +{ + /* Only available for integrated init. */ + BUILD_BUG(); +} + #endif /* CONFIG_KASAN_HW_TAGS */ +#ifdef CONFIG_KASAN + +struct kasan_cache { + int alloc_meta_offset; + int free_meta_offset; + bool is_kmalloc; +}; + slab_flags_t __kasan_never_merge(void); static __always_inline slab_flags_t kasan_never_merge(void) { @@ -130,20 +148,20 @@ static __always_inline void kasan_unpoison_range(const void *addr, size_t size) __kasan_unpoison_range(addr, size); } -void __kasan_alloc_pages(struct page *page, unsigned int order, bool init); -static __always_inline void kasan_alloc_pages(struct page *page, +void __kasan_poison_pages(struct page *page, unsigned int order, bool init); +static __always_inline void kasan_poison_pages(struct page *page, unsigned int order, bool init) { if (kasan_enabled()) - __kasan_alloc_pages(page, order, init); + __kasan_poison_pages(page, order, init); } -void __kasan_free_pages(struct page *page, unsigned int order, bool init); -static __always_inline void kasan_free_pages(struct page *page, - unsigned int order, bool init) +void __kasan_unpoison_pages(struct page *page, unsigned int order, bool init); +static __always_inline void kasan_unpoison_pages(struct page *page, + unsigned int order, bool init) { if (kasan_enabled()) - __kasan_free_pages(page, order, init); + __kasan_unpoison_pages(page, order, init); } void __kasan_cache_create(struct kmem_cache *cache, unsigned int *size, @@ -285,21 +303,15 @@ void kasan_restore_multi_shot(bool enabled); #else /* CONFIG_KASAN */ -static inline bool kasan_enabled(void) -{ - return false; -} -static inline bool kasan_has_integrated_init(void) -{ - return false; -} static inline slab_flags_t kasan_never_merge(void) { return 0; } static inline void kasan_unpoison_range(const void *address, size_t size) {} -static inline void kasan_alloc_pages(struct page *page, unsigned int order, bool init) {} -static inline void kasan_free_pages(struct page *page, unsigned int order, bool init) {} +static inline void kasan_poison_pages(struct page *page, unsigned int order, + bool init) {} +static inline void kasan_unpoison_pages(struct page *page, unsigned int order, + bool init) {} static inline void kasan_cache_create(struct kmem_cache *cache, unsigned int *size, slab_flags_t *flags) {} diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index c8529e9fa8de..44349791737a 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h @@ -157,6 +157,8 @@ struct kernfs_node { unsigned short flags; umode_t mode; struct kernfs_iattrs *iattr; + + ANDROID_KABI_RESERVE(1); }; /* @@ -198,6 +200,8 @@ struct kernfs_root { struct list_head supers; wait_queue_head_t deactivate_waitq; + + ANDROID_KABI_RESERVE(1); }; struct kernfs_open_file { @@ -218,6 +222,8 @@ struct kernfs_open_file { bool mmapped:1; bool released:1; const struct vm_operations_struct *vm_ops; + + ANDROID_KABI_RESERVE(1); }; struct kernfs_ops { diff --git a/include/linux/key-type.h b/include/linux/key-type.h index 2ab2d6d6aeab..5e85fe05c7b1 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h @@ -10,6 +10,7 @@ #include #include +#include #ifdef CONFIG_KEYS @@ -155,6 +156,9 @@ struct key_type { int (*asym_verify_signature)(struct kernel_pkey_params *params, const void *in, const void *in2); + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + /* internal fields */ struct list_head link; /* link in types list */ struct lock_class_key lock_class; /* key->sem lock class */ diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index c691b1ac95f8..394aff2668b9 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -331,6 +331,7 @@ struct mem_cgroup { struct deferred_split deferred_split_queue; #endif + ANDROID_OEM_DATA(1); struct mem_cgroup_per_node *nodeinfo[0]; /* WARNING: nodeinfo must be the last member here */ }; @@ -441,10 +442,31 @@ static inline bool mem_cgroup_below_min(struct mem_cgroup *memcg) page_counter_read(&memcg->memory); } -int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask); +int __mem_cgroup_charge(struct page *page, struct mm_struct *mm, + gfp_t gfp_mask); +static inline int mem_cgroup_charge(struct page *page, struct mm_struct *mm, + gfp_t gfp_mask) +{ + if (mem_cgroup_disabled()) + return 0; + return __mem_cgroup_charge(page, mm, gfp_mask); +} -void mem_cgroup_uncharge(struct page *page); -void mem_cgroup_uncharge_list(struct list_head *page_list); +void __mem_cgroup_uncharge(struct page *page); +static inline void mem_cgroup_uncharge(struct page *page) +{ + if (mem_cgroup_disabled()) + return; + __mem_cgroup_uncharge(page); +} + +void __mem_cgroup_uncharge_list(struct list_head *page_list); +static inline void mem_cgroup_uncharge_list(struct list_head *page_list) +{ + if (mem_cgroup_disabled()) + return; + __mem_cgroup_uncharge_list(page_list); +} void mem_cgroup_migrate(struct page *oldpage, struct page *newpage); diff --git a/include/linux/mm.h b/include/linux/mm.h index 6f5261b3bd47..4f3e9a10e387 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -573,6 +573,7 @@ struct vm_fault { */ unsigned long vma_flags; pgprot_t vma_page_prot; + ANDROID_OEM_DATA_ARRAY(1, 2); }; /* page entry size for vm->huge_fault() */ @@ -755,8 +756,13 @@ struct inode; */ static inline int put_page_testzero(struct page *page) { + int ret; + VM_BUG_ON_PAGE(page_ref_count(page) == 0, page); - return page_ref_dec_and_test(page); + ret = page_ref_dec_and_test(page); + page_pinner_put_page(page); + + return ret; } /* @@ -1232,8 +1238,6 @@ static inline void put_page(struct page *page) { page = compound_head(page); - page_pinner_migration_failed(page); - /* * For devmap managed pages we need to catch refcount transition from * 2 to 1, when refcount reach one it means the page is free and we @@ -3354,6 +3358,8 @@ unsigned long wp_shared_mapping_range(struct address_space *mapping, extern int sysctl_nr_trim_pages; extern bool pte_map_lock_addr(struct vm_fault *vmf, unsigned long addr); +extern int reclaim_shmem_address_space(struct address_space *mapping); +extern int reclaim_pages_from_list(struct list_head *page_list); /** * seal_check_future_write - Check for F_SEAL_FUTURE_WRITE flag and handle it diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 50648bc12864..c853f612a815 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -468,13 +468,6 @@ struct mm_struct { */ atomic_t has_pinned; - /** - * @write_protect_seq: Locked when any thread is write - * protecting pages mapped by this mm to enforce a later COW, - * for instance during page table copying for fork(). - */ - seqcount_t write_protect_seq; - #ifdef CONFIG_MMU atomic_long_t pgtables_bytes; /* PTE page table pages */ #endif @@ -483,6 +476,18 @@ struct mm_struct { spinlock_t page_table_lock; /* Protects page tables and some * counters */ + /* + * With some kernel config, the current mmap_lock's offset + * inside 'mm_struct' is at 0x120, which is very optimal, as + * its two hot fields 'count' and 'owner' sit in 2 different + * cachelines, and when mmap_lock is highly contended, both + * of the 2 fields will be accessed frequently, current layout + * will help to reduce cache bouncing. + * + * So please be careful with adding new fields before + * mmap_lock, which can easily push the 2 fields into one + * cacheline. + */ struct rw_semaphore mmap_lock; struct list_head mmlist; /* List of maybe swapped mm's. These @@ -503,7 +508,15 @@ struct mm_struct { unsigned long stack_vm; /* VM_STACK */ unsigned long def_flags; + /** + * @write_protect_seq: Locked when any thread is write + * protecting pages mapped by this mm to enforce a later COW, + * for instance during page table copying for fork(). + */ + seqcount_t write_protect_seq; + spinlock_t arg_lock; /* protect the below fields */ + unsigned long start_code, end_code, start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; @@ -585,6 +598,8 @@ struct mm_struct { #ifdef CONFIG_IOMMU_SUPPORT u32 pasid; #endif + + ANDROID_KABI_RESERVE(1); } __randomize_layout; /* diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 42df06c6b19c..bb62eae4d88a 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -9,6 +9,7 @@ #include #include +#include struct mmc_cid { unsigned int manfid; @@ -236,6 +237,8 @@ struct mmc_part { #define MMC_BLK_DATA_AREA_BOOT (1<<1) #define MMC_BLK_DATA_AREA_GP (1<<2) #define MMC_BLK_DATA_AREA_RPMB (1<<3) + + ANDROID_KABI_RESERVE(1); }; /* @@ -313,6 +316,10 @@ struct mmc_card { unsigned int bouncesz; /* Bounce buffer size */ struct workqueue_struct *complete_wq; /* Private workqueue */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_VENDOR_DATA(1); }; static inline bool mmc_large_sector(struct mmc_card *card) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 511b14d76b7c..6fa9e476e778 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -176,6 +177,9 @@ struct mmc_host_ops { */ int (*multi_io_quirk)(struct mmc_card *card, unsigned int direction, int blk_size); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct mmc_cqe_ops { @@ -220,6 +224,9 @@ struct mmc_cqe_ops { * will have zero data bytes transferred. */ void (*cqe_recovery_finish)(struct mmc_host *host); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct mmc_async_req { @@ -485,6 +492,9 @@ struct mmc_host { /* Host Software Queue support */ bool hsq_enabled; + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_VENDOR_DATA(1); ANDROID_OEM_DATA(1); unsigned long private[] ____cacheline_aligned; diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index b002e9b4abc0..08ccefa35267 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -778,11 +778,13 @@ typedef struct pglist_data { int kswapd_failures; /* Number of 'reclaimed == 0' runs */ + ANDROID_OEM_DATA(1); #ifdef CONFIG_COMPACTION int kcompactd_max_order; enum zone_type kcompactd_highest_zoneidx; wait_queue_head_t kcompactd_wait; struct task_struct *kcompactd; + bool proactive_compact_trigger; #endif /* * This is a per-node reserve of pages that are not available diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 0101747de549..a12c285222a8 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -14,6 +14,7 @@ #include #include #include +#include #include static inline int NF_DROP_GETERR(int verdict) @@ -171,6 +172,8 @@ struct nf_sockopt_ops { int (*get)(struct sock *sk, int optval, void __user *user, int *len); /* Use the module struct to lock set/get code in place */ struct module *owner; + + ANDROID_KABI_RESERVE(1); }; /* Function to register/unregister hook points. */ @@ -373,6 +376,8 @@ struct nf_nat_hook { unsigned int (*manip_pkt)(struct sk_buff *skb, struct nf_conn *ct, enum nf_nat_manip_type mtype, enum ip_conntrack_dir dir); + + ANDROID_KABI_RESERVE(1); }; extern struct nf_nat_hook __rcu *nf_nat_hook; @@ -457,6 +462,8 @@ struct nf_ct_hook { void (*destroy)(struct nf_conntrack *); bool (*get_tuple_skb)(struct nf_conntrack_tuple *, const struct sk_buff *); + + ANDROID_KABI_RESERVE(1); }; extern struct nf_ct_hook __rcu *nf_ct_hook; @@ -474,6 +481,8 @@ struct nfnl_ct_hook { u32 portid, u32 report); void (*seq_adjust)(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, s32 off); + + ANDROID_KABI_RESERVE(1); }; extern struct nfnl_ct_hook __rcu *nfnl_ct_hook; diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h index ab192720e2d6..5206d0991022 100644 --- a/include/linux/netfilter/ipset/ip_set.h +++ b/include/linux/netfilter/ipset/ip_set.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -190,6 +191,8 @@ struct ip_set_type_variant { bool (*same_set)(const struct ip_set *a, const struct ip_set *b); /* Region-locking is used */ bool region_lock; + + ANDROID_KABI_RESERVE(1); }; struct ip_set_region { @@ -228,6 +231,8 @@ struct ip_set_type { /* Set this to THIS_MODULE if you are a module, otherwise NULL */ struct module *me; + + ANDROID_KABI_RESERVE(1); }; /* register and unregister set type */ @@ -270,6 +275,8 @@ struct ip_set { size_t offset[IPSET_EXT_ID_MAX]; /* The type specific data */ void *data; + + ANDROID_KABI_RESERVE(1); }; static inline void diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index f6267e2883f2..15775bc5b174 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -22,6 +23,8 @@ struct nfnl_callback { struct netlink_ext_ack *extack); const struct nla_policy *policy; /* netlink attribute policy */ const u_int16_t attr_count; /* number of nlattr's */ + + ANDROID_KABI_RESERVE(1); }; enum nfnl_abort_action { @@ -41,6 +44,8 @@ struct nfnetlink_subsystem { enum nfnl_abort_action action); void (*cleanup)(struct net *net); bool (*valid_genid)(struct net *net, u32 genid); + + ANDROID_KABI_RESERVE(1); }; int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n); diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h index 48314ade1506..c3d17fe68426 100644 --- a/include/linux/netfilter_ipv6.h +++ b/include/linux/netfilter_ipv6.h @@ -7,6 +7,7 @@ #ifndef __LINUX_IP6_NETFILTER_H #define __LINUX_IP6_NETFILTER_H +#include #include #include @@ -65,6 +66,8 @@ struct nf_ipv6_ops { const struct nf_bridge_frag_data *data, struct sk_buff *)); #endif + + ANDROID_KABI_RESERVE(1); }; #ifdef CONFIG_NETFILTER diff --git a/include/linux/of.h b/include/linux/of.h index 4b27c9a27df3..16db9ba0a11e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -931,6 +931,11 @@ static inline int of_machine_is_compatible(const char *compat) return 0; } +static inline int of_add_property(struct device_node *np, struct property *prop) +{ + return 0; +} + static inline int of_remove_property(struct device_node *np, struct property *prop) { return 0; diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 4f6ba9379112..9f67e4653af5 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -138,6 +138,9 @@ enum pageflags { #endif #ifdef CONFIG_64BIT PG_arch_2, +#endif +#ifdef CONFIG_KASAN_HW_TAGS + PG_skip_kasan_poison, #endif __NR_PAGEFLAGS, @@ -444,6 +447,12 @@ TESTCLEARFLAG(Young, young, PF_ANY) PAGEFLAG(Idle, idle, PF_ANY) #endif +#ifdef CONFIG_KASAN_HW_TAGS +PAGEFLAG(SkipKASanPoison, skip_kasan_poison, PF_HEAD) +#else +PAGEFLAG_FALSE(SkipKASanPoison) +#endif + /* * PageReported() is used to track reported free pages within the Buddy * allocator. We can use the non-atomic version of the test and set diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h index 572458016331..ccd3ed46434f 100644 --- a/include/linux/page-isolation.h +++ b/include/linux/page-isolation.h @@ -44,7 +44,8 @@ int move_freepages_block(struct zone *zone, struct page *page, */ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, - unsigned migratetype, int flags); + unsigned migratetype, int flags, + unsigned long *failed_pfn); /* * Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE. @@ -58,7 +59,7 @@ undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, * Test all pages in [start_pfn, end_pfn) are isolated or not. */ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, - int isol_flags); + int isol_flags, unsigned long *failed_pfn); struct page *alloc_migrate_target(struct page *page, unsigned long private); diff --git a/include/linux/page_pinner.h b/include/linux/page_pinner.h index e03ff271bea5..ba14d7636dc0 100644 --- a/include/linux/page_pinner.h +++ b/include/linux/page_pinner.h @@ -39,7 +39,15 @@ static inline void dump_page_pinner(struct page *page) __dump_page_pinner(page); } -static inline void page_pinner_migration_failed(struct page *page) +static inline void page_pinner_put_page(struct page *page) +{ + if (!static_branch_unlikely(&failure_tracking)) + return; + + __page_pinner_migration_failed(page); +} + +static inline void page_pinner_failure_detect(struct page *page) { if (!static_branch_unlikely(&failure_tracking)) return; @@ -67,7 +75,10 @@ static inline void set_page_pinner(struct page *page, unsigned int order) static inline void dump_page_pinner(struct page *page) { } -static inline void page_pinner_migration_failed(struct page *page) +static inline void page_pinner_put_page(struct page *page) +{ +} +static inline void page_pinner_failure_detect(struct page *page) { } static inline void page_pinner_mark_migration_failed_pages(struct list_head *page_list) diff --git a/include/linux/pci.h b/include/linux/pci.h index cc772efa9713..76ea634f24a7 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -558,6 +558,10 @@ struct pci_host_bridge { resource_size_t start, resource_size_t size, resource_size_t align); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + unsigned long private[] ____cacheline_aligned; }; @@ -745,6 +749,8 @@ struct pci_ops { void __iomem *(*map_bus)(struct pci_bus *bus, unsigned int devfn, int where); int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); + + ANDROID_KABI_RESERVE(1); }; /* @@ -820,6 +826,8 @@ struct pci_error_handlers { /* Device driver may resume normal operations */ void (*resume)(struct pci_dev *dev); + + ANDROID_KABI_RESERVE(1); }; diff --git a/include/linux/phy.h b/include/linux/phy.h index 08725a262f32..afeda1c01e3a 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -645,6 +646,11 @@ struct phy_device { /* MACsec management functions */ const struct macsec_ops *macsec_ops; #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define to_phy_device(d) container_of(to_mdio_device(d), \ struct phy_device, mdio) @@ -875,6 +881,9 @@ struct phy_driver { int (*get_sqi)(struct phy_device *dev); /** @get_sqi_max: Get the maximum signal quality indication */ int (*get_sqi_max)(struct phy_device *dev); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; #define to_phy_driver(d) container_of(to_mdio_common_driver(d), \ struct phy_driver, mdiodrv) diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 17f9cd5626c8..72b8a954e6bb 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -11,6 +11,7 @@ #define _PLATFORM_DEVICE_H_ #include +#include #define PLATFORM_DEVID_NONE (-1) #define PLATFORM_DEVID_AUTO (-2) @@ -37,6 +38,9 @@ struct platform_device { /* arch specific additions */ struct pdev_archdata archdata; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; #define platform_get_device_id(pdev) ((pdev)->id_entry) @@ -94,6 +98,8 @@ struct platform_device_info { u64 dma_mask; const struct property_entry *properties; + + ANDROID_KABI_RESERVE(1); }; extern struct platform_device *platform_device_register_full( const struct platform_device_info *pdevinfo); @@ -206,6 +212,8 @@ struct platform_driver { struct device_driver driver; const struct platform_device_id *id_table; bool prevent_deferred_probe; + + ANDROID_KABI_RESERVE(1); }; #define to_platform_driver(drv) (container_of((drv), struct platform_driver, \ diff --git a/include/linux/pm.h b/include/linux/pm.h index 52d9724db9dc..8b174a8f9f04 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -15,6 +15,7 @@ #include #include #include +#include /* * Callbacks for platform drivers to implement. @@ -299,6 +300,8 @@ struct dev_pm_ops { int (*runtime_suspend)(struct device *dev); int (*runtime_resume)(struct device *dev); int (*runtime_idle)(struct device *dev); + + ANDROID_KABI_RESERVE(1); }; #ifdef CONFIG_PM_SLEEP @@ -621,6 +624,9 @@ struct dev_pm_info { struct pm_subsys_data *subsys_data; /* Owned by the subsystem. */ void (*set_latency_tolerance)(struct device *, s32); struct dev_pm_qos *qos; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; extern int dev_pm_get_subsys_data(struct device *dev); @@ -647,6 +653,8 @@ struct dev_pm_domain { int (*activate)(struct device *dev); void (*sync)(struct device *dev); void (*dismiss)(struct device *dev); + + ANDROID_KABI_RESERVE(1); }; /* diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 4a69d4af3ff8..200841b958c7 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -93,6 +93,7 @@ struct freq_qos_request { enum freq_qos_req_type type; struct plist_node pnode; struct freq_constraints *qos; + ANDROID_OEM_DATA_ARRAY(1, 2); }; diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index aefa0b0bc4c4..a8fa073a09b6 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -17,6 +17,7 @@ #include #include #include +#include /* * All voltages, currents, charges, energies, time and temperatures in uV, @@ -233,6 +234,8 @@ struct power_supply_config { char **supplied_to; size_t num_supplicants; + + ANDROID_KABI_RESERVE(1); }; /* Description of power supply */ @@ -274,6 +277,8 @@ struct power_supply_desc { bool no_thermal; /* For APM emulation, think legacy userspace. */ int use_for_apm; + + ANDROID_KABI_RESERVE(1); }; struct power_supply { @@ -315,6 +320,8 @@ struct power_supply { struct led_trigger *charging_blink_full_solid_trig; char *charging_blink_full_solid_trig_name; #endif + + ANDROID_KABI_RESERVE(1); }; /* @@ -382,6 +389,8 @@ struct power_supply_battery_info { int ocv_table_size[POWER_SUPPLY_OCV_TEMP_MAX]; struct power_supply_resistance_temp_table *resist_table; int resist_table_size; + + ANDROID_KABI_RESERVE(1); }; extern struct atomic_notifier_head power_supply_notifier; diff --git a/include/linux/psi_types.h b/include/linux/psi_types.h index b95f3211566a..4b73f0f19ef5 100644 --- a/include/linux/psi_types.h +++ b/include/linux/psi_types.h @@ -157,6 +157,7 @@ struct psi_group { struct timer_list poll_timer; wait_queue_head_t poll_wait; atomic_t poll_wakeup; + atomic_t poll_scheduled; /* Protects data used by the monitor */ struct mutex trigger_lock; diff --git a/include/linux/pwm.h b/include/linux/pwm.h index 9212c2e80435..b05d417dd059 100644 --- a/include/linux/pwm.h +++ b/include/linux/pwm.h @@ -5,6 +5,7 @@ #include #include #include +#include struct pwm_capture; struct seq_file; @@ -100,6 +101,8 @@ struct pwm_device { struct pwm_args args; struct pwm_state state; struct pwm_state last; + + ANDROID_KABI_RESERVE(1); }; /** @@ -301,6 +304,8 @@ struct pwm_ops { enum pwm_polarity polarity); int (*enable)(struct pwm_chip *chip, struct pwm_device *pwm); void (*disable)(struct pwm_chip *chip, struct pwm_device *pwm); + + ANDROID_KABI_RESERVE(1); }; /** @@ -327,6 +332,8 @@ struct pwm_chip { /* only used internally by the PWM framework */ struct list_head list; struct pwm_device *pwms; + + ANDROID_KABI_RESERVE(1); }; /** diff --git a/include/linux/regmap.h b/include/linux/regmap.h index e7834d98207f..751ca3869307 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -19,6 +19,7 @@ #include #include #include +#include struct module; struct clk; @@ -401,6 +402,8 @@ struct regmap_config { unsigned int hwlock_mode; bool can_sleep; + + ANDROID_KABI_RESERVE(1); }; /** @@ -438,6 +441,8 @@ struct regmap_range_cfg { /* Data window (per each page) */ unsigned int window_start; unsigned int window_len; + + ANDROID_KABI_RESERVE(1); }; struct regmap_async; @@ -514,6 +519,8 @@ struct regmap_bus { enum regmap_endian val_format_endian_default; size_t max_raw_read; size_t max_raw_write; + + ANDROID_KABI_RESERVE(1); }; /* diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index d7c77ee370f3..4d73dc580d75 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -17,6 +17,7 @@ #include #include #include +#include struct gpio_desc; struct regmap; @@ -202,6 +203,8 @@ struct regulator_ops { int (*resume)(struct regulator_dev *rdev); int (*set_pull_down) (struct regulator_dev *); + + ANDROID_KABI_RESERVE(1); }; /* @@ -381,6 +384,8 @@ struct regulator_desc { unsigned int poll_enabled_time; unsigned int (*of_map_mode)(unsigned int mode); + + ANDROID_KABI_RESERVE(1); }; /** @@ -473,6 +478,8 @@ struct regulator_dev { /* time when this regulator was disabled last time */ unsigned long last_off_jiffy; + + ANDROID_KABI_RESERVE(1); }; struct regulator_dev * diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index 04951e2b335f..25621ffdb99b 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -658,6 +658,10 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len, int rproc_boot(struct rproc *rproc); void rproc_shutdown(struct rproc *rproc); void rproc_report_crash(struct rproc *rproc, enum rproc_crash_type type); + +/* from remoteproc_coredump.c */ +void rproc_coredump_cleanup(struct rproc *rproc); +void rproc_coredump(struct rproc *rproc); void rproc_coredump_using_sections(struct rproc *rproc); int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size); int rproc_coredump_add_custom_segment(struct rproc *rproc, diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 22d1575e4991..d51770334160 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -16,6 +16,7 @@ #include #include #include +#include #include extern int rtc_month_days(unsigned int month, unsigned int year); @@ -66,6 +67,8 @@ struct rtc_class_ops { int (*alarm_irq_enable)(struct device *, unsigned int enabled); int (*read_offset)(struct device *, long *offset); int (*set_offset)(struct device *, long offset); + + ANDROID_KABI_RESERVE(1); }; struct rtc_device; @@ -140,6 +143,8 @@ struct rtc_device { unsigned int uie_task_active:1; unsigned int uie_timer_active:1; #endif + + ANDROID_KABI_RESERVE(1); }; #define to_rtc_device(d) container_of(d, struct rtc_device, dev) diff --git a/include/linux/sched/topology.h b/include/linux/sched/topology.h index 452158253764..173463340280 100644 --- a/include/linux/sched/topology.h +++ b/include/linux/sched/topology.h @@ -3,6 +3,7 @@ #define _LINUX_SCHED_TOPOLOGY_H #include +#include #include #include @@ -146,6 +147,10 @@ struct sched_domain { struct sched_domain_shared *shared; unsigned int span_weight; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + /* * Span of all CPUs in this domain. * diff --git a/include/linux/sched/user.h b/include/linux/sched/user.h index dd6a413d9565..6d63a5260130 100644 --- a/include/linux/sched/user.h +++ b/include/linux/sched/user.h @@ -6,6 +6,7 @@ #include #include #include +#include /* * Some day this will be a full-fledged user tracking system.. @@ -42,6 +43,9 @@ struct user_struct { /* Miscellaneous per-user rate limit */ struct ratelimit_state ratelimit; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); ANDROID_OEM_DATA_ARRAY(1, 2); }; diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index fb8c8f16a49b..57d23fae3781 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -12,6 +12,7 @@ #include #include #include +#include #define SCMI_MAX_STR_SIZE 16 #define SCMI_MAX_NUM_RATES 16 @@ -82,6 +83,8 @@ struct scmi_clk_proto_ops { u64 rate); int (*enable)(const struct scmi_protocol_handle *ph, u32 clk_id); int (*disable)(const struct scmi_protocol_handle *ph, u32 clk_id); + + ANDROID_KABI_RESERVE(1); }; /** @@ -125,6 +128,8 @@ struct scmi_perf_proto_ops { bool (*fast_switch_possible)(const struct scmi_protocol_handle *ph, struct device *dev); bool (*power_scale_mw_get)(const struct scmi_protocol_handle *ph); + + ANDROID_KABI_RESERVE(1); }; /** @@ -150,6 +155,8 @@ struct scmi_power_proto_ops { u32 state); int (*state_get)(const struct scmi_protocol_handle *ph, u32 domain, u32 *state); + + ANDROID_KABI_RESERVE(1); }; /** @@ -326,6 +333,8 @@ struct scmi_sensor_info { unsigned int resolution; int exponent; struct scmi_range_attrs scalar_attrs; + + ANDROID_KABI_RESERVE(1); }; /* @@ -461,6 +470,8 @@ struct scmi_sensor_proto_ops { u32 sensor_id, u32 *sensor_config); int (*config_set)(const struct scmi_protocol_handle *ph, u32 sensor_id, u32 sensor_config); + + ANDROID_KABI_RESERVE(1); }; /** @@ -481,6 +492,8 @@ struct scmi_reset_proto_ops { int (*reset)(const struct scmi_protocol_handle *ph, u32 domain); int (*assert)(const struct scmi_protocol_handle *ph, u32 domain); int (*deassert)(const struct scmi_protocol_handle *ph, u32 domain); + + ANDROID_KABI_RESERVE(1); }; /** @@ -625,6 +638,8 @@ struct scmi_handle { void (*devm_put_protocol)(struct scmi_device *sdev, u8 proto); const struct scmi_notify_ops *notify_ops; + + ANDROID_KABI_RESERVE(1); }; enum scmi_std_protocol { @@ -653,6 +668,8 @@ struct scmi_device { const char *name; struct device dev; struct scmi_handle *handle; + + ANDROID_KABI_RESERVE(1); }; #define to_scmi_dev(d) container_of(d, struct scmi_device, dev) diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index ff63c2963359..0a361d4b58de 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #ifdef CONFIG_SERIAL_CORE_CONSOLE @@ -80,6 +81,9 @@ struct uart_ops { void (*poll_put_char)(struct uart_port *, unsigned char); int (*poll_get_char)(struct uart_port *); #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; #define NO_POLL_CHAR 0x00ff0000 @@ -256,6 +260,9 @@ struct uart_port { struct gpio_desc *rs485_term_gpio; /* enable RS485 bus termination */ struct serial_iso7816 iso7816; void *private_data; /* generic platform data pointer */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; static inline int serial_port_in(struct uart_port *up, int offset) @@ -318,6 +325,8 @@ struct uart_driver { */ struct uart_state *state; struct tty_driver *tty_driver; + + ANDROID_KABI_RESERVE(1); }; void uart_write_wakeup(struct uart_port *port); diff --git a/include/linux/serio.h b/include/linux/serio.h index 6c27d413da92..25d638f584a6 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -13,6 +13,7 @@ #include #include #include +#include #include extern struct bus_type serio_bus; @@ -61,6 +62,8 @@ struct serio { * may get indigestion when exposed to concurrent access (i8042). */ struct mutex *ps2_cmd_mutex; + + ANDROID_KABI_RESERVE(1); }; #define to_serio_port(d) container_of(d, struct serio, dev) @@ -79,6 +82,8 @@ struct serio_driver { void (*cleanup)(struct serio *); struct device_driver driver; + + ANDROID_KABI_RESERVE(1); }; #define to_serio_driver(d) container_of(d, struct serio_driver, driver) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 51b1dcfb5022..1bf2615449fe 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -85,7 +85,7 @@ extern bool shmem_huge_enabled(struct vm_area_struct *vma); extern unsigned long shmem_swap_usage(struct vm_area_struct *vma); extern unsigned long shmem_partial_swap_usage(struct address_space *mapping, pgoff_t start, pgoff_t end); -extern void shmem_mark_page_lazyfree(struct page *page); +extern void shmem_mark_page_lazyfree(struct page *page, bool tail); /* Flag allocation requirements to shmem_getpage */ enum sgp_type { diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index e68a8d7fb523..aa15c390580a 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -41,6 +41,7 @@ #include #endif #include +#include /* The interface for checksum offload between the stack and networking drivers * is as follows... @@ -532,6 +533,8 @@ struct skb_shared_info { * remains valid until skb destructor */ void * destructor_arg; + ANDROID_OEM_DATA_ARRAY(1, 3); + /* must be last field, see pskb_expand_head() */ skb_frag_t frags[MAX_SKB_FRAGS]; }; diff --git a/include/linux/smp.h b/include/linux/smp.h index 04f44e0aa2e0..7ce15c3be7aa 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -127,6 +127,7 @@ int smp_call_function_any(const struct cpumask *mask, void kick_all_cpus_sync(void); void wake_up_all_idle_cpus(void); +void wake_up_all_online_idle_cpus(void); /* * Generic and arch helpers @@ -182,6 +183,7 @@ smp_call_function_any(const struct cpumask *mask, smp_call_func_t func, static inline void kick_all_cpus_sync(void) { } static inline void wake_up_all_idle_cpus(void) { } +static inline void wake_up_all_online_idle_cpus(void) { } #ifdef CONFIG_UP_LATE_INIT extern void __init up_late_init(void); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index b390fdac1587..f47b06683b36 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -14,6 +14,7 @@ #include #include #include +#include struct dma_chan; struct property_entry; @@ -197,6 +198,9 @@ struct spi_device { /* the statistics */ struct spi_statistics statistics; + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + /* * likely need more hooks for more protocol options affecting how * the controller talks to each chip, like: @@ -281,6 +285,8 @@ struct spi_driver { int (*remove)(struct spi_device *spi); void (*shutdown)(struct spi_device *spi); struct device_driver driver; + + ANDROID_KABI_RESERVE(1); }; static inline struct spi_driver *to_spi_driver(struct device_driver *drv) @@ -667,6 +673,9 @@ struct spi_controller { /* Interrupt enable state during PTP system timestamping */ unsigned long irq_flags; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; static inline void *spi_controller_get_devdata(struct spi_controller *ctlr) @@ -964,6 +973,8 @@ struct spi_transfer { #define SPI_TRANS_FAIL_NO_START BIT(0) u16 error; + + ANDROID_KABI_RESERVE(1); }; /** @@ -1030,6 +1041,8 @@ struct spi_message { /* list of spi_res reources when the spi message is processed */ struct list_head resources; + + ANDROID_KABI_RESERVE(1); }; static inline void spi_message_init_no_memset(struct spi_message *m) @@ -1468,6 +1481,8 @@ struct spi_board_info { */ u32 mode; + ANDROID_KABI_RESERVE(1); + /* ... may need additional spi_device chip config data here. * avoid stuff protocol drivers can set; but include stuff * needed to behave without being bound to a driver: diff --git a/include/linux/spmi.h b/include/linux/spmi.h index 394a3f68bad5..6744f7cfadaf 100644 --- a/include/linux/spmi.h +++ b/include/linux/spmi.h @@ -7,6 +7,7 @@ #include #include #include +#include /* Maximum slave identifier */ #define SPMI_MAX_SLAVE_ID 16 @@ -85,6 +86,7 @@ struct spmi_controller { u8 sid, u16 addr, u8 *buf, size_t len); int (*write_cmd)(struct spmi_controller *ctrl, u8 opcode, u8 sid, u16 addr, const u8 *buf, size_t len); + ANDROID_KABI_RESERVE(1); }; static inline struct spmi_controller *to_spmi_controller(struct device *d) @@ -138,6 +140,7 @@ struct spmi_driver { struct device_driver driver; int (*probe)(struct spmi_device *sdev); void (*remove)(struct spmi_device *sdev); + ANDROID_KABI_RESERVE(1); }; static inline struct spmi_driver *to_spmi_driver(struct device_driver *d) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 04b337d3a3cb..fa2ea36a7bd7 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #ifdef CONFIG_VT @@ -185,6 +186,8 @@ struct platform_suspend_ops { bool (*suspend_again)(void); void (*end)(void); void (*recover)(void); + + ANDROID_KABI_RESERVE(1); }; struct platform_s2idle_ops { @@ -195,6 +198,8 @@ struct platform_s2idle_ops { void (*restore_early)(void); void (*restore)(void); void (*end)(void); + + ANDROID_KABI_RESERVE(1); }; #ifdef CONFIG_SUSPEND @@ -426,6 +431,8 @@ struct platform_hibernation_ops { int (*pre_restore)(void); void (*restore_cleanup)(void); void (*recover)(void); + + ANDROID_KABI_RESERVE(1); }; #ifdef CONFIG_HIBERNATION diff --git a/include/linux/swap.h b/include/linux/swap.h index 8ed2f6e51ae7..beda0a50d0b9 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -342,19 +342,9 @@ extern void lru_add_page_tail(struct page *page, struct page *page_tail, struct lruvec *lruvec, struct list_head *head); extern void mark_page_accessed(struct page *); -extern atomic_t lru_disable_count; - -static inline bool lru_cache_disabled(void) -{ - return atomic_read(&lru_disable_count); -} - -static inline void lru_cache_enable(void) -{ - atomic_dec(&lru_disable_count); -} - +extern bool lru_cache_disabled(void); extern void lru_cache_disable(void); +extern void lru_cache_enable(void); extern void lru_add_drain(void); extern void lru_add_drain_cpu(int cpu); extern void lru_add_drain_cpu_zone(struct zone *zone); @@ -363,7 +353,7 @@ extern void rotate_reclaimable_page(struct page *page); extern void deactivate_file_page(struct page *page); extern void deactivate_page(struct page *page); extern void mark_page_lazyfree(struct page *page); -extern void mark_page_lazyfree_movetail(struct page *page); +extern void mark_page_lazyfree_movetail(struct page *page, bool tail); extern void swap_setup(void); extern void __lru_cache_add_inactive_or_unevictable(struct page *page, @@ -695,7 +685,13 @@ static inline int mem_cgroup_swappiness(struct mem_cgroup *mem) #endif #if defined(CONFIG_SWAP) && defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP) -extern void cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask); +extern void __cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask); +static inline void cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask) +{ + if (mem_cgroup_disabled()) + return; + __cgroup_throttle_swaprate(page, gfp_mask); +} #else static inline void cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask) { @@ -704,8 +700,22 @@ static inline void cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask) #ifdef CONFIG_MEMCG_SWAP extern void mem_cgroup_swapout(struct page *page, swp_entry_t entry); -extern int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry); -extern void mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages); +extern int __mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry); +static inline int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry) +{ + if (mem_cgroup_disabled()) + return 0; + return __mem_cgroup_try_charge_swap(page, entry); +} + +extern void __mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages); +static inline void mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages) +{ + if (mem_cgroup_disabled()) + return; + __mem_cgroup_uncharge_swap(entry, nr_pages); +} + extern long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg); extern bool mem_cgroup_swap_full(struct page *page); #else diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 2f87377e9af7..b163dbd6875c 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -412,6 +413,8 @@ struct tcp_sock { */ struct request_sock __rcu *fastopen_rsk; struct saved_syn *saved_syn; + + ANDROID_KABI_RESERVE(1); }; enum tsq_enum { diff --git a/include/linux/thermal.h b/include/linux/thermal.h index fa9c9eae22a0..a7c121d53960 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #define THERMAL_TRIPS_NONE -1 @@ -79,6 +80,7 @@ struct thermal_zone_device_ops { enum thermal_trend *); int (*notify) (struct thermal_zone_device *, int, enum thermal_trip_type); + ANDROID_KABI_RESERVE(1); }; struct thermal_cooling_device_ops { @@ -88,6 +90,8 @@ struct thermal_cooling_device_ops { int (*get_requested_power)(struct thermal_cooling_device *, u32 *); int (*state2power)(struct thermal_cooling_device *, unsigned long, u32 *); int (*power2state)(struct thermal_cooling_device *, u32, unsigned long *); + + ANDROID_KABI_RESERVE(1); }; struct thermal_cooling_device { @@ -102,6 +106,8 @@ struct thermal_cooling_device { struct mutex lock; /* protect thermal_instances list */ struct list_head thermal_instances; struct list_head node; + + ANDROID_KABI_RESERVE(1); }; /** @@ -179,6 +185,8 @@ struct thermal_zone_device { struct list_head node; struct delayed_work poll_queue; enum thermal_notify_event notify_event; + + ANDROID_KABI_RESERVE(1); }; /** @@ -199,6 +207,8 @@ struct thermal_governor { void (*unbind_from_tz)(struct thermal_zone_device *tz); int (*throttle)(struct thermal_zone_device *tz, int trip); struct list_head governor_list; + + ANDROID_KABI_RESERVE(1); }; /* Structure that holds binding parameters for a zone */ @@ -234,6 +244,8 @@ struct thermal_bind_params { unsigned long *binding_limits; int (*match) (struct thermal_zone_device *tz, struct thermal_cooling_device *cdev); + + ANDROID_KABI_RESERVE(1); }; /* Structure to define Thermal Zone parameters */ @@ -287,6 +299,8 @@ struct thermal_zone_params { * Used by thermal zone drivers (default 0). */ int offset; + + ANDROID_KABI_RESERVE(1); }; /** @@ -311,6 +325,8 @@ struct thermal_zone_of_device_ops { int (*set_trips)(void *, int, int); int (*set_emul_temp)(void *, int); int (*set_trip_temp)(void *, int, int); + + ANDROID_KABI_RESERVE(1); }; /* Function declarations */ diff --git a/include/linux/tty.h b/include/linux/tty.h index 94fa384a650b..bd76f2f1cde0 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -14,6 +14,7 @@ #include #include #include +#include /* @@ -218,6 +219,8 @@ struct tty_port_operations { int (*activate)(struct tty_port *port, struct tty_struct *tty); /* Called on the final put of a port */ void (*destruct)(struct tty_port *port); + + ANDROID_KABI_RESERVE(1); }; struct tty_port_client_operations { @@ -252,6 +255,8 @@ struct tty_port { set to size of fifo */ struct kref kref; /* Ref counter */ void *client_data; + + ANDROID_KABI_RESERVE(1); }; /* tty_port::iflags bits -- use atomic bit ops */ @@ -345,6 +350,9 @@ struct tty_struct { /* If the tty has a pending do_SAK, queue it here - akpm */ struct work_struct SAK_work; struct tty_port *port; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); } __randomize_layout; /* Each of a tty's open files has private_data pointing to tty_file_private */ diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 5d509c125171..61f29370e1c3 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -237,6 +237,7 @@ #include #include #include +#include struct tty_struct; struct tty_driver; @@ -292,6 +293,9 @@ struct tty_operations { void (*poll_put_char)(struct tty_driver *driver, int line, char ch); #endif int (*proc_show)(struct seq_file *, void *); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); } __randomize_layout; struct tty_driver { @@ -326,6 +330,9 @@ struct tty_driver { const struct tty_operations *ops; struct list_head tty_drivers; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); } __randomize_layout; extern struct list_head tty_drivers; diff --git a/include/linux/tty_ldisc.h b/include/linux/tty_ldisc.h index 572a07976116..689ba487e752 100644 --- a/include/linux/tty_ldisc.h +++ b/include/linux/tty_ldisc.h @@ -126,6 +126,7 @@ #include #include #include +#include /* * the semaphore definition @@ -211,6 +212,9 @@ struct tty_ldisc_ops { struct module *owner; int refcount; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct tty_ldisc { diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h index 54bf6b118401..77131e8fefcc 100644 --- a/include/linux/uio_driver.h +++ b/include/linux/uio_driver.h @@ -16,6 +16,7 @@ #include #include #include +#include struct module; struct uio_map; @@ -77,6 +78,8 @@ struct uio_device { struct mutex info_lock; struct kobject *map_dir; struct kobject *portio_dir; + + ANDROID_KABI_RESERVE(1); }; /** @@ -109,6 +112,7 @@ struct uio_info { int (*open)(struct uio_info *info, struct inode *inode); int (*release)(struct uio_info *info, struct inode *inode); int (*irqcontrol)(struct uio_info *info, s32 irq_on); + ANDROID_KABI_RESERVE(1); }; extern int __must_check diff --git a/include/linux/usb.h b/include/linux/usb.h index d6a41841b93e..befa27107375 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -22,6 +22,7 @@ #include /* for current && schedule_timeout */ #include /* for struct mutex */ #include /* for runtime PM */ +#include struct usb_device; struct usb_driver; @@ -257,6 +258,11 @@ struct usb_interface { struct device dev; /* interface specific device info */ struct device *usb_dev; struct work_struct reset_ws; /* for resets in atomic context */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define to_usb_interface(d) container_of(d, struct usb_interface, dev) @@ -402,6 +408,11 @@ struct usb_host_bos { struct usb_ssp_cap_descriptor *ssp_cap; struct usb_ss_container_id_descriptor *ss_id; struct usb_ptm_cap_descriptor *ptm_cap; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; int __usb_get_extra_descriptor(char *buffer, unsigned size, @@ -465,6 +476,11 @@ struct usb_bus { struct mon_bus *mon_bus; /* non-null when associated */ int monitored; /* non-zero when monitored */ #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; struct usb_dev_state; @@ -709,6 +725,11 @@ struct usb_device { u16 hub_delay; unsigned use_generic_driver:1; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define to_usb_device(d) container_of(d, struct usb_device, dev) @@ -1210,6 +1231,11 @@ struct usb_driver { unsigned int supports_autosuspend:1; unsigned int disable_hub_initiated_lpm:1; unsigned int soft_unbind:1; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define to_usb_driver(d) container_of(d, struct usb_driver, drvwrap.driver) @@ -1595,6 +1621,12 @@ struct urb { int error_count; /* (return) number of ISO errors */ void *context; /* (in) context for completion */ usb_complete_t complete; /* (in) completion routine */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); + struct usb_iso_packet_descriptor iso_frame_desc[]; /* (in) ISO ONLY */ }; diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index e0ba1f0c13e6..e5cdba2db7b2 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -123,6 +123,8 @@ struct usb_request { int status; unsigned actual; + + ANDROID_KABI_RESERVE(1); }; /*-------------------------------------------------------------------------*/ @@ -153,6 +155,8 @@ struct usb_ep_ops { int (*fifo_status) (struct usb_ep *ep); void (*fifo_flush) (struct usb_ep *ep); + + ANDROID_KABI_RESERVE(1); }; /** @@ -245,6 +249,8 @@ struct usb_ep { #if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) u8 transfer_type; #endif + + ANDROID_KABI_RESERVE(1); }; /*-------------------------------------------------------------------------*/ @@ -330,9 +336,16 @@ struct usb_gadget_ops { void (*udc_set_speed)(struct usb_gadget *, enum usb_device_speed); void (*udc_set_ssp_rate)(struct usb_gadget *gadget, enum usb_ssp_rate rate); + void (*udc_async_callbacks)(struct usb_gadget *gadget, bool enable); struct usb_ep *(*match_ep)(struct usb_gadget *, struct usb_endpoint_descriptor *, struct usb_ss_ep_comp_descriptor *); + int (*check_config)(struct usb_gadget *gadget); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; /** @@ -617,6 +630,7 @@ int usb_gadget_connect(struct usb_gadget *gadget); int usb_gadget_disconnect(struct usb_gadget *gadget); int usb_gadget_deactivate(struct usb_gadget *gadget); int usb_gadget_activate(struct usb_gadget *gadget); +int usb_gadget_check_config(struct usb_gadget *gadget); #else static inline int usb_gadget_frame_number(struct usb_gadget *gadget) { return 0; } @@ -640,6 +654,8 @@ static inline int usb_gadget_deactivate(struct usb_gadget *gadget) { return 0; } static inline int usb_gadget_activate(struct usb_gadget *gadget) { return 0; } +static inline int usb_gadget_check_config(struct usb_gadget *gadget) +{ return 0; } #endif /* CONFIG_USB_GADGET */ /*-------------------------------------------------------------------------*/ diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 3dbb42c637c1..2ffafbdcda07 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -25,6 +25,7 @@ #include #include #include +#include #define MAX_TOPO_LEVEL 6 @@ -225,6 +226,11 @@ struct usb_hcd { * (ohci 32, uhci 1024, ehci 256/512/1024). */ + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); + /* The HC driver's private data is stored at the end of * this structure. */ @@ -410,6 +416,10 @@ struct hc_driver { /* Call for power on/off the port if necessary */ int (*port_power)(struct usb_hcd *hcd, int portnum, bool enable); + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; static inline int hcd_giveback_urb_in_bh(struct usb_hcd *hcd) @@ -561,6 +571,11 @@ struct usb_tt { spinlock_t lock; struct list_head clear_list; /* of usb_tt_clear */ struct work_struct clear_work; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; struct usb_tt_clear { diff --git a/include/linux/usb/otg.h b/include/linux/usb/otg.h index 69f1b6328532..10cb3d193d77 100644 --- a/include/linux/usb/otg.h +++ b/include/linux/usb/otg.h @@ -12,6 +12,7 @@ #include #include +#include struct usb_otg { u8 default_a; @@ -40,6 +41,7 @@ struct usb_otg { /* start or continue HNP role switch */ int (*start_hnp)(struct usb_otg *otg); + ANDROID_KABI_RESERVE(1); }; /** diff --git a/include/linux/usb/phy.h b/include/linux/usb/phy.h index e4de6bc1f69b..888d2fdb662f 100644 --- a/include/linux/usb/phy.h +++ b/include/linux/usb/phy.h @@ -13,6 +13,7 @@ #include #include #include +#include #include enum usb_phy_interface { @@ -155,6 +156,8 @@ struct usb_phy { * manually detect the charger type. */ enum usb_charger_type (*charger_detect)(struct usb_phy *x); + + ANDROID_KABI_RESERVE(1); }; /* for board-specific init logic */ diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 91b4303ca305..b2e2c302caa6 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -4,6 +4,7 @@ #define __LINUX_USB_TYPEC_H #include +#include /* USB Type-C Specification releases */ #define USB_TYPEC_REV_1_0 0x100 /* 1.0 */ @@ -215,6 +216,7 @@ struct typec_operations { int (*vconn_set)(struct typec_port *port, enum typec_role role); int (*port_type_set)(struct typec_port *port, enum typec_port_type type); + ANDROID_KABI_RESERVE(1); }; enum usb_pd_svdm_ver { @@ -252,6 +254,7 @@ struct typec_capability { void *driver_data; const struct typec_operations *ops; + ANDROID_KABI_RESERVE(1); }; /* Specific to try_role(). Indicates the user want's to clear the preference. */ diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h index 65933cbe9129..60531284df7c 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -30,6 +30,7 @@ struct typec_altmode { char *desc; const struct typec_altmode_ops *ops; + ANDROID_KABI_RESERVE(1); }; #define to_typec_altmode(d) container_of(d, struct typec_altmode, dev) @@ -63,6 +64,7 @@ struct typec_altmode_ops { int (*notify)(struct typec_altmode *altmode, unsigned long conf, void *data); int (*activate)(struct typec_altmode *altmode, int activate); + ANDROID_KABI_RESERVE(1); }; int typec_altmode_enter(struct typec_altmode *altmode, u32 *vdo); diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index 2e4f7721fc4e..195512a3a0b4 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -23,6 +23,8 @@ #ifndef __LINUX_USB_USBNET_H #define __LINUX_USB_USBNET_H +#include + /* interface from usbnet core to each USB networking link we handle */ struct usbnet { /* housekeeping */ @@ -83,6 +85,11 @@ struct usbnet { # define EVENT_LINK_CHANGE 11 # define EVENT_SET_RX_MODE 12 # define EVENT_NO_IP_ALIGN 13 + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; static inline struct usb_driver *driver_of(struct usb_interface *intf) @@ -172,6 +179,9 @@ struct driver_info { int out; /* tx endpoint */ unsigned long data; /* Misc driver specific data */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /* Minidrivers are just drivers using the "usbnet" core as a powerful diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 26de0cae2a0a..e98cc6dea2b9 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -14,6 +14,7 @@ #include #include #include +#include struct workqueue_struct; @@ -106,6 +107,8 @@ struct work_struct { #ifdef CONFIG_LOCKDEP struct lockdep_map lockdep_map; #endif + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; #define WORK_DATA_INIT() ATOMIC_LONG_INIT((unsigned long)WORK_STRUCT_NO_POOL) @@ -119,6 +122,9 @@ struct delayed_work { /* target workqueue and CPU ->timer uses to queue ->work */ struct workqueue_struct *wq; int cpu; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct rcu_work { diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index ead627c00655..113d39905b8c 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -11,6 +11,7 @@ #include #include #include +#include #include /* @@ -87,6 +88,9 @@ union v4l2_ctrl_ptr { struct v4l2_area *p_area; void *p; const void *p_const; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /** @@ -119,6 +123,8 @@ struct v4l2_ctrl_ops { int (*g_volatile_ctrl)(struct v4l2_ctrl *ctrl); int (*try_ctrl)(struct v4l2_ctrl *ctrl); int (*s_ctrl)(struct v4l2_ctrl *ctrl); + + ANDROID_KABI_RESERVE(1); }; /** @@ -140,6 +146,8 @@ struct v4l2_ctrl_type_ops { void (*log)(const struct v4l2_ctrl *ctrl); int (*validate)(const struct v4l2_ctrl *ctrl, u32 idx, union v4l2_ctrl_ptr ptr); + + ANDROID_KABI_RESERVE(1); }; /** @@ -290,6 +298,8 @@ struct v4l2_ctrl { union v4l2_ctrl_ptr p_def; union v4l2_ctrl_ptr p_new; union v4l2_ctrl_ptr p_cur; + + ANDROID_KABI_RESERVE(1); }; /** @@ -329,6 +339,8 @@ struct v4l2_ctrl_ref { bool req_done; bool valid_p_req; union v4l2_ctrl_ptr p_req; + + ANDROID_KABI_RESERVE(1); }; /** @@ -379,6 +391,8 @@ struct v4l2_ctrl_handler { struct list_head requests; struct list_head requests_queued; struct media_request_object req_obj; + + ANDROID_KABI_RESERVE(1); }; /** @@ -430,6 +444,8 @@ struct v4l2_ctrl_config { const char * const *qmenu; const s64 *qmenu_int; unsigned int is_private:1; + + ANDROID_KABI_RESERVE(1); }; /** diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index ad2d41952442..3a66e78e8e3b 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -211,6 +212,8 @@ struct v4l2_file_operations { int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct file *); int (*release) (struct file *); + + ANDROID_KABI_RESERVE(1); }; /* @@ -307,6 +310,9 @@ struct video_device DECLARE_BITMAP(valid_ioctls, BASE_VIDIOC_PRIVATE); struct mutex *lock; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /** diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index c203047eb834..1c59f0951b3b 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -13,6 +13,7 @@ #define _MEDIA_VIDEOBUF2_V4L2_H #include +#include #include #if VB2_MAX_FRAME != VIDEO_MAX_FRAME @@ -51,6 +52,8 @@ struct vb2_v4l2_buffer { __s32 request_fd; bool is_held; struct vb2_plane planes[VB2_MAX_PLANES]; + + ANDROID_KABI_RESERVE(1); }; /* VB2 V4L2 flags as set in vb2_queue.subsystem_flags */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index df611c8b6b59..36a6f84c5c49 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -564,6 +565,11 @@ struct hci_dev { int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); void (*cmd_timeout)(struct hci_dev *hdev); bool (*prevent_wake)(struct hci_dev *hdev); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define HCI_PHY_HANDLE(handle) (handle & 0xff) @@ -660,6 +666,11 @@ struct hci_conn { void (*connect_cfm_cb) (struct hci_conn *conn, u8 status); void (*security_cfm_cb) (struct hci_conn *conn, u8 status); void (*disconn_cfm_cb) (struct hci_conn *conn, u8 reason); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; struct hci_chan { @@ -670,6 +681,8 @@ struct hci_chan { unsigned int sent; __u8 state; bool amp; + + ANDROID_KABI_RESERVE(1); }; struct hci_conn_params { @@ -696,6 +709,8 @@ struct hci_conn_params { struct hci_conn *conn; bool explicit_connect; u32 current_flags; + + ANDROID_KABI_RESERVE(1); }; extern struct list_head hci_dev_list; @@ -1415,6 +1430,8 @@ struct hci_cb { __u8 encrypt); void (*key_change_cfm) (struct hci_conn *conn, __u8 status); void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); + + ANDROID_KABI_RESERVE(1); }; static inline void hci_connect_cfm(struct hci_conn *conn, __u8 status) @@ -1675,6 +1692,8 @@ struct hci_mgmt_chan { size_t handler_count; const struct hci_mgmt_handler *handlers; void (*hdev_init) (struct sock *sk, struct hci_dev *hdev); + + ANDROID_KABI_RESERVE(1); }; int hci_mgmt_chan_register(struct hci_mgmt_chan *c); diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 1d1232917de7..8c99677077b6 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -29,6 +29,7 @@ #include #include +#include /* L2CAP defaults */ #define L2CAP_DEFAULT_MTU 672 @@ -643,6 +644,9 @@ struct l2cap_chan { void *data; const struct l2cap_ops *ops; struct mutex lock; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct l2cap_ops { @@ -667,6 +671,9 @@ struct l2cap_ops { unsigned long len, int nb); int (*filter) (struct l2cap_chan * chan, struct sk_buff *skb); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct l2cap_conn { @@ -702,6 +709,9 @@ struct l2cap_conn { struct mutex chan_lock; struct kref ref; struct list_head users; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; struct l2cap_user { diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 99d26879b02a..d8f4e835ede8 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -22,6 +22,7 @@ */ #include +#include #ifndef __RFCOMM_H #define __RFCOMM_H @@ -164,6 +165,8 @@ struct rfcomm_session { uint mtu; struct list_head dlcs; + + ANDROID_KABI_RESERVE(1); }; struct rfcomm_dlc { @@ -197,6 +200,9 @@ struct rfcomm_dlc { void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb); void (*state_change)(struct rfcomm_dlc *d, int err); void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; /* DLC and session flags */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index fab23df83050..81d5b2486c04 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -20,6 +20,7 @@ #include #include #include +#include #include /** @@ -1042,6 +1043,8 @@ struct cfg80211_crypto_settings { const u8 *sae_pwd; u8 sae_pwd_len; enum nl80211_sae_pwe_mechanism sae_pwe; + + ANDROID_KABI_RESERVE(1); }; /** @@ -1088,6 +1091,8 @@ struct cfg80211_beacon_data { size_t probe_resp_len; size_t lci_len; size_t civicloc_len; + + ANDROID_KABI_RESERVE(1); }; struct mac_address { @@ -1224,6 +1229,8 @@ struct cfg80211_ap_settings { struct cfg80211_he_bss_color he_bss_color; struct cfg80211_fils_discovery fils_discovery; struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp; + + ANDROID_KABI_RESERVE(1); }; /** @@ -1253,6 +1260,8 @@ struct cfg80211_csa_settings { bool radar_required; bool block_tx; u8 count; + + ANDROID_KABI_RESERVE(1); }; #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 @@ -1395,6 +1404,8 @@ struct station_parameters { u16 airtime_weight; struct sta_txpwr txpwr; const struct ieee80211_he_6ghz_capa *he_6ghz_capa; + + ANDROID_KABI_RESERVE(1); }; /** @@ -1741,6 +1752,8 @@ struct station_info { u32 airtime_link_metric; u8 connected_to_as; + + ANDROID_KABI_RESERVE(1); }; #if IS_ENABLED(CONFIG_CFG80211) @@ -1995,6 +2008,8 @@ struct mesh_config { u16 dot11MeshAwakeWindowDuration; u32 plink_timeout; bool dot11MeshNolearn; + + ANDROID_KABI_RESERVE(1); }; /** @@ -2044,6 +2059,8 @@ struct mesh_setup { struct cfg80211_bitrate_mask beacon_rate; bool userspace_handles_dfs; bool control_port_over_nl80211; + + ANDROID_KABI_RESERVE(1); }; /** @@ -2205,6 +2222,8 @@ struct cfg80211_scan_request { u32 n_6ghz_params; struct cfg80211_scan_6ghz_params *scan_6ghz_params; + ANDROID_KABI_RESERVE(1); + /* keep last */ struct ieee80211_channel *channels[]; }; @@ -2351,6 +2370,8 @@ struct cfg80211_sched_scan_request { bool nl_owner_dead; struct list_head list; + ANDROID_KABI_RESERVE(1); + /* keep last */ struct ieee80211_channel *channels[]; }; @@ -2474,6 +2495,8 @@ struct cfg80211_bss { u8 bssid_index; u8 max_bssid_indicator; + ANDROID_KABI_RESERVE(1); + u8 priv[] __aligned(sizeof(void *)); }; @@ -2600,6 +2623,8 @@ struct cfg80211_assoc_request { size_t fils_kek_len; const u8 *fils_nonces; struct ieee80211_s1g_cap s1g_capa, s1g_capa_mask; + + ANDROID_KABI_RESERVE(1); }; /** @@ -2698,6 +2723,8 @@ struct cfg80211_ibss_params { struct ieee80211_ht_cap ht_capa_mask; struct key_params *wep_keys; int wep_tx_key; + + ANDROID_KABI_RESERVE(1); }; /** @@ -2812,6 +2839,8 @@ struct cfg80211_connect_params { size_t fils_erp_rrk_len; bool want_1x; struct ieee80211_edmg edmg; + + ANDROID_KABI_RESERVE(1); }; /** @@ -3269,6 +3298,8 @@ struct cfg80211_nan_func { u8 num_rx_filters; u8 instance_id; u64 cookie; + + ANDROID_KABI_RESERVE(1); }; /** @@ -3429,6 +3460,8 @@ struct cfg80211_pmsr_ftm_result { dist_avg_valid:1, dist_variance_valid:1, dist_spread_valid:1; + + ANDROID_KABI_RESERVE(1); }; /** @@ -4265,6 +4298,10 @@ struct cfg80211_ops { struct cfg80211_tid_config *tid_conf); int (*reset_tid_config)(struct wiphy *wiphy, struct net_device *dev, const u8 *peer, u8 tids); + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; /* @@ -4628,6 +4665,8 @@ struct wiphy_vendor_command { unsigned long *storage); const struct nla_policy *policy; unsigned int maxattr; + + ANDROID_KABI_RESERVE(1); }; /** @@ -5033,6 +5072,8 @@ struct wiphy { u8 max_data_retry_count; + ANDROID_KABI_RESERVE(1); + char priv[] __aligned(NETDEV_ALIGN); }; @@ -5332,6 +5373,9 @@ struct wireless_dev { struct work_struct pmsr_free_wk; unsigned long unprot_beacon_reported; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; static inline u8 *wdev_address(struct wireless_dev *wdev) diff --git a/include/net/genetlink.h b/include/net/genetlink.h index e55ec1597ce7..d66f0f397f2e 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -3,6 +3,7 @@ #define __NET_GENERIC_NETLINK_H #include +#include #include #include @@ -67,6 +68,8 @@ struct genl_family { const struct genl_small_ops *small_ops; const struct genl_multicast_group *mcgrps; struct module *module; + + ANDROID_KABI_RESERVE(1); }; /** @@ -158,6 +161,8 @@ struct genl_ops { u8 internal_flags; u8 flags; u8 validate; + + ANDROID_KABI_RESERVE(1); }; /** diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index aa92af3dd444..8177cb94958c 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,8 @@ struct inet_connection_sock_af_ops { char __user *optval, int __user *optlen); void (*addr2sockaddr)(struct sock *sk, struct sockaddr *); void (*mtu_reduced)(struct sock *sk); + + ANDROID_KABI_RESERVE(1); }; /** inet_connection_sock - INET connection oriented sock @@ -134,6 +137,8 @@ struct inet_connection_sock { u32 icsk_probes_tstamp; u32 icsk_user_timeout; + ANDROID_KABI_RESERVE(1); + u64 icsk_ca_priv[104 / sizeof(u64)]; #define ICSK_CA_PRIV_SIZE (13 * sizeof(u64)) }; diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index ac5ff3c3afb1..bd4bfdd30e28 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,8 @@ struct fib6_config { struct nlattr *fc_encap; u16 fc_encap_type; bool fc_is_fdb; + + ANDROID_KABI_RESERVE(1); }; struct fib6_node { @@ -83,6 +86,8 @@ struct fib6_node { int fn_sernum; struct fib6_info __rcu *rr_ptr; struct rcu_head rcu; + + ANDROID_KABI_RESERVE(1); }; struct fib6_gc_args { @@ -199,6 +204,9 @@ struct fib6_info { struct rcu_head rcu; struct nexthop *nh; + + ANDROID_KABI_RESERVE(1); + struct fib6_nh fib6_nh[]; }; @@ -218,6 +226,8 @@ struct rt6_info { /* more non-fragment space at head required */ unsigned short rt6i_nfheader_len; + + ANDROID_KABI_RESERVE(1); }; struct fib6_result { diff --git a/include/net/mac80211.h b/include/net/mac80211.h index dcdba96814a2..0f701f9a8d79 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -701,6 +702,8 @@ struct ieee80211_bss_conf { u32 unsol_bcast_probe_resp_interval; bool s1g; struct cfg80211_bitrate_mask beacon_tx_rate; + + ANDROID_KABI_RESERVE(1); }; /** @@ -1097,6 +1100,9 @@ struct ieee80211_tx_info { void *rate_driver_data[ IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE / sizeof(void *)]; }; + + ANDROID_KABI_RESERVE(1); + void *driver_data[ IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)]; }; @@ -1583,6 +1589,8 @@ struct ieee80211_conf { struct cfg80211_chan_def chandef; bool radar_enabled; enum ieee80211_smps_mode smps_mode; + + ANDROID_KABI_RESERVE(1); }; /** @@ -1727,6 +1735,8 @@ struct ieee80211_vif { bool txqs_stopped[IEEE80211_NUM_ACS]; + ANDROID_KABI_RESERVE(1); + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; @@ -2112,6 +2122,8 @@ struct ieee80211_sta { struct ieee80211_txq *txq[IEEE80211_NUM_TIDS + 1]; + ANDROID_KABI_RESERVE(1); + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; @@ -2606,6 +2618,8 @@ struct ieee80211_hw { u8 tx_sk_pacing_shift; u8 weight_multiplier; u32 max_mtu; + + ANDROID_KABI_RESERVE(1); }; static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw, @@ -4192,6 +4206,11 @@ struct ieee80211_ops { struct ieee80211_vif *vif); void (*sta_set_4addr)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool enabled); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; /** @@ -6161,6 +6180,11 @@ struct rate_control_ops { struct dentry *dir); u32 (*get_expected_throughput)(void *priv_sta); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; static inline int rate_supported(struct ieee80211_sta *sta, diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 22ced1381ede..8a26efdadbbc 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -28,6 +28,7 @@ #include #include #include +#include #include /* @@ -83,6 +84,8 @@ struct neigh_parms { int reachable_time; int data[NEIGH_VAR_DATA_MAX]; DECLARE_BITMAP(data_state, NEIGH_VAR_DATA_MAX); + + ANDROID_KABI_RESERVE(1); }; static inline void neigh_var_set(struct neigh_parms *p, int index, int val) @@ -157,6 +160,9 @@ struct neighbour { struct list_head gc_list; struct rcu_head rcu; struct net_device *dev; + + ANDROID_KABI_RESERVE(1); + u8 primary_key[0]; } __randomize_layout; @@ -226,6 +232,8 @@ struct neigh_table { struct neigh_statistics __percpu *stats; struct neigh_hash_table __rcu *nht; struct pneigh_entry **phash_buckets; + + ANDROID_KABI_RESERVE(1); }; enum { diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 7a44164f147c..878d0ce81321 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -109,6 +110,8 @@ struct nf_conn { ANDROID_KABI_RESERVE(1); ANDROID_KABI_RESERVE(2); + + ANDROID_OEM_DATA(1); }; static inline struct nf_conn * diff --git a/include/net/netns/can.h b/include/net/netns/can.h index 52fbd8291a96..d075f610e647 100644 --- a/include/net/netns/can.h +++ b/include/net/netns/can.h @@ -7,6 +7,7 @@ #define __NETNS_CAN_H__ #include +#include struct can_dev_rcv_lists; struct can_pkg_stats; @@ -35,6 +36,8 @@ struct netns_can { /* CAN GW per-net gateway jobs */ struct hlist_head cgw_list; + + ANDROID_KABI_RESERVE(1); }; #endif /* __NETNS_CAN_H__ */ diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 175206956080..13b3defd5cb0 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -10,6 +10,7 @@ #include #include #include +#include struct tcpm_hash_bucket; struct ctl_table_header; @@ -228,5 +229,7 @@ struct netns_ipv4 { atomic_t rt_genid; siphash_key_t ip_id_key; + + ANDROID_KABI_RESERVE(1); }; #endif diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 5ec054473d81..213e96241e76 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -7,6 +7,7 @@ #ifndef __NETNS_IPV6_H__ #define __NETNS_IPV6_H__ +#include #include #include @@ -115,6 +116,8 @@ struct netns_ipv6 { spinlock_t lock; u32 seq; } ip6addrlbl_table; + + ANDROID_KABI_RESERVE(1); }; #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h index ca043342c0eb..fa2663747a85 100644 --- a/include/net/netns/netfilter.h +++ b/include/net/netns/netfilter.h @@ -3,6 +3,7 @@ #define __NETNS_NETFILTER_H #include +#include struct proc_dir_entry; struct nf_logger; @@ -34,5 +35,7 @@ struct netns_nf { #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) bool defrag_ipv6; #endif + + ANDROID_KABI_RESERVE(1); }; #endif diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h index 6c0806bd8d1e..ccb84b7dadce 100644 --- a/include/net/netns/nftables.h +++ b/include/net/netns/nftables.h @@ -3,6 +3,7 @@ #define _NETNS_NFTABLES_H_ #include +#include struct netns_nftables { struct list_head tables; @@ -13,6 +14,8 @@ struct netns_nftables { unsigned int base_seq; u8 gencursor; u8 validate_state; + + ANDROID_KABI_RESERVE(1); }; #endif diff --git a/include/net/netns/xfrm.h b/include/net/netns/xfrm.h index b59d73d529ba..93d74c68d87e 100644 --- a/include/net/netns/xfrm.h +++ b/include/net/netns/xfrm.h @@ -7,6 +7,7 @@ #include #include #include +#include #include struct ctl_table_header; @@ -77,6 +78,8 @@ struct netns_xfrm { spinlock_t xfrm_policy_lock; struct mutex xfrm_cfg_mutex; + + ANDROID_KABI_RESERVE(1); }; #endif diff --git a/include/net/page_pool.h b/include/net/page_pool.h index b139e7bf45fe..6c469951e589 100644 --- a/include/net/page_pool.h +++ b/include/net/page_pool.h @@ -33,6 +33,7 @@ #include /* Needed by ptr_ring */ #include #include +#include #define PP_FLAG_DMA_MAP BIT(0) /* Should page_pool do the DMA * map/unmap @@ -126,6 +127,8 @@ struct page_pool { refcount_t user_cnt; u64 destroy_cnt; + + ANDROID_KABI_RESERVE(1); }; struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 4dd2c9e34976..a33c35133840 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -114,6 +115,8 @@ struct Qdisc { bool empty; struct rcu_head rcu; + ANDROID_KABI_RESERVE(1); + /* private data */ long privdata[] ____cacheline_aligned; }; @@ -259,6 +262,8 @@ struct Qdisc_class_ops { struct sk_buff *skb, struct tcmsg*); int (*dump_stats)(struct Qdisc *, unsigned long, struct gnet_dump *); + + ANDROID_KABI_RESERVE(1); }; /* Qdisc_class_ops flag values */ @@ -302,6 +307,8 @@ struct Qdisc_ops { u32 (*egress_block_get)(struct Qdisc *sch); struct module *owner; + + ANDROID_KABI_RESERVE(1); }; diff --git a/include/net/sock.h b/include/net/sock.h index f1de3d83469d..1f0a41d79baf 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -69,6 +69,7 @@ #include #include #include +#include /* * This structure really needs to be cleaned up. @@ -530,6 +531,8 @@ struct sock { ANDROID_KABI_RESERVE(6); ANDROID_KABI_RESERVE(7); ANDROID_KABI_RESERVE(8); + + ANDROID_OEM_DATA(1); }; enum sk_pacing { diff --git a/include/net/tls.h b/include/net/tls.h index 624864c2dcfb..b0d953be977e 100644 --- a/include/net/tls.h +++ b/include/net/tls.h @@ -116,6 +116,9 @@ struct tls_rec { char aad_space[TLS_AAD_SPACE_SIZE]; u8 iv_data[MAX_IV_SIZE]; struct aead_request aead_req; + + ANDROID_KABI_RESERVE(1); + u8 aead_req_ctx[]; }; @@ -144,6 +147,8 @@ struct tls_sw_context_tx { #define BIT_TX_SCHEDULED 0 #define BIT_TX_CLOSING 1 unsigned long tx_bitmask; + + ANDROID_KABI_RESERVE(1); }; struct tls_sw_context_rx { @@ -161,6 +166,8 @@ struct tls_sw_context_rx { /* protect crypto_wait with decrypt_pending*/ spinlock_t decrypt_compl_lock; bool async_notify; + + ANDROID_KABI_RESERVE(1); }; struct tls_record_info { diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 69ade4fb71aa..b6398c9d2c5c 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -11,6 +11,7 @@ #include #include #include +#include struct Scsi_Host; struct scsi_driver; @@ -142,6 +143,11 @@ struct scsi_cmnd { unsigned char tag; /* SCSI-II queued command tag */ unsigned int extra_len; /* length of alignment and padding */ + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; /* diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 1a5c9a3df6d6..158423bcdde9 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -8,6 +8,7 @@ #include #include #include +#include struct device; struct request_queue; @@ -237,6 +238,12 @@ struct scsi_device { struct mutex state_mutex; enum scsi_device_state sdev_state; struct task_struct *quiesced_by; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); + unsigned long sdev_data[]; } __attribute__((aligned(sizeof(unsigned long)))); diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 701f178b20ae..8c0d37f389df 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -10,6 +10,7 @@ #include #include #include +#include struct block_device; struct completion; @@ -486,6 +487,11 @@ struct scsi_host_template { /* Delay for runtime autosuspend */ int rpm_autosuspend_delay; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; /* @@ -692,6 +698,8 @@ struct Scsi_Host { */ struct device *dma_dev; + ANDROID_KABI_RESERVE(1); + /* * We should ensure that this is aligned, both for better performance * and also because some compilers (m68k) don't automatically force diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h index 70cbc5095e72..82417ce70d62 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -54,6 +55,8 @@ struct snd_compr_runtime { dma_addr_t dma_addr; size_t dma_bytes; struct snd_dma_buffer *dma_buffer_p; + + ANDROID_KABI_RESERVE(1); }; /** @@ -82,6 +85,8 @@ struct snd_compr_stream { bool partial_drain; void *private_data; struct snd_dma_buffer dma_buffer; + + ANDROID_KABI_RESERVE(1); }; /** @@ -130,6 +135,8 @@ struct snd_compr_ops { struct snd_compr_caps *caps); int (*get_codec_caps) (struct snd_compr_stream *stream, struct snd_compr_codec_caps *codec); + + ANDROID_KABI_RESERVE(1); }; /** @@ -158,6 +165,7 @@ struct snd_compr { struct snd_info_entry *proc_root; struct snd_info_entry *proc_info_entry; #endif + ANDROID_KABI_RESERVE(1); }; /* compress device register APIs */ diff --git a/include/sound/core.h b/include/sound/core.h index 0462c577d7a3..b5ecbf936ffb 100644 --- a/include/sound/core.h +++ b/include/sound/core.h @@ -14,6 +14,7 @@ #include /* pm_message_t */ #include #include +#include /* number of supported soundcards */ #ifdef CONFIG_SND_DYNAMIC_MINORS @@ -61,6 +62,8 @@ struct snd_device_ops { int (*dev_free)(struct snd_device *dev); int (*dev_register)(struct snd_device *dev); int (*dev_disconnect)(struct snd_device *dev); + + ANDROID_KABI_RESERVE(1); }; struct snd_device { @@ -70,6 +73,8 @@ struct snd_device { enum snd_device_type type; /* device type */ void *device_data; /* device structure */ const struct snd_device_ops *ops; /* operations */ + + ANDROID_KABI_RESERVE(1); }; #define snd_device(n) list_entry(n, struct snd_device, list) @@ -132,6 +137,9 @@ struct snd_card { struct snd_mixer_oss *mixer_oss; int mixer_oss_change_count; #endif + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; #define dev_to_snd_card(p) container_of(p, struct snd_card, card_dev) @@ -167,6 +175,8 @@ struct snd_minor { void *private_data; /* private data for f_ops->open */ struct device *dev; /* device for sysfs */ struct snd_card *card_ptr; /* assigned card instance */ + + ANDROID_KABI_RESERVE(1); }; /* return a device pointer linked to each sound device as a parent */ diff --git a/include/sound/hwdep.h b/include/sound/hwdep.h index 8d6cdb254039..d99a53025ff0 100644 --- a/include/sound/hwdep.h +++ b/include/sound/hwdep.h @@ -9,6 +9,7 @@ #include #include +#include struct snd_hwdep; @@ -34,6 +35,8 @@ struct snd_hwdep_ops { struct snd_hwdep_dsp_status *status); int (*dsp_load)(struct snd_hwdep *hw, struct snd_hwdep_dsp_image *image); + + ANDROID_KABI_RESERVE(1); }; struct snd_hwdep { @@ -59,6 +62,8 @@ struct snd_hwdep { int used; /* reference counter */ unsigned int dsp_loaded; /* bit fields of loaded dsp indices */ unsigned int exclusive:1; /* exclusive access mode */ + + ANDROID_KABI_RESERVE(1); }; extern int snd_hwdep_new(struct snd_card *card, char *id, int device, diff --git a/include/sound/info.h b/include/sound/info.h index 7c13bf52cc81..25af5d8d1527 100644 --- a/include/sound/info.h +++ b/include/sound/info.h @@ -9,6 +9,7 @@ #include #include +#include #include /* buffer for information */ @@ -55,6 +56,8 @@ struct snd_info_entry_ops { int (*mmap)(struct snd_info_entry *entry, void *file_private_data, struct inode *inode, struct file *file, struct vm_area_struct *vma); + + ANDROID_KABI_RESERVE(1); }; struct snd_info_entry { @@ -74,6 +77,8 @@ struct snd_info_entry { struct mutex access; struct list_head children; struct list_head list; + + ANDROID_KABI_RESERVE(1); }; #if defined(CONFIG_SND_OSSEMUL) && defined(CONFIG_SND_PROC_FS) diff --git a/include/sound/jack.h b/include/sound/jack.h index 9eb2b5ec1ec4..70400b20e952 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h @@ -9,6 +9,7 @@ */ #include +#include struct input_dev; @@ -69,6 +70,8 @@ struct snd_jack { #endif /* CONFIG_SND_JACK_INPUT_DEV */ void *private_data; void (*private_free)(struct snd_jack *); + + ANDROID_KABI_RESERVE(1); }; #ifdef CONFIG_SND_JACK diff --git a/include/sound/soc.h b/include/sound/soc.h index f7fabb9d1c83..63338f68de48 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -846,6 +847,8 @@ struct snd_soc_dai_link { #ifdef CONFIG_SND_SOC_TOPOLOGY struct snd_soc_dobj dobj; /* For topology */ #endif + + ANDROID_KABI_RESERVE(1); }; #define for_each_link_codecs(link, i, codec) \ for ((i) = 0; \ @@ -1096,6 +1099,11 @@ struct snd_soc_card { unsigned int probed:1; void *drvdata; + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define for_each_card_prelinks(card, i, link) \ for ((i) = 0; \ @@ -1177,6 +1185,9 @@ struct snd_soc_pcm_runtime { unsigned int fe_compr:1; /* for Dynamic PCM */ int num_components; + + ANDROID_KABI_RESERVE(1); + struct snd_soc_component *components[]; /* CPU/Codec/Platform */ }; /* see soc_new_pcm_runtime() */ @@ -1222,6 +1233,8 @@ struct soc_mixer_control { #ifdef CONFIG_SND_SOC_TOPOLOGY struct snd_soc_dobj dobj; #endif + + ANDROID_KABI_RESERVE(1); }; struct soc_bytes { @@ -1266,6 +1279,8 @@ struct soc_enum { #ifdef CONFIG_SND_SOC_TOPOLOGY struct snd_soc_dobj dobj; #endif + + ANDROID_KABI_RESERVE(1); }; static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) diff --git a/include/sound/timer.h b/include/sound/timer.h index 760e132cc0cd..b7695e4dcca0 100644 --- a/include/sound/timer.h +++ b/include/sound/timer.h @@ -10,6 +10,7 @@ #include #include +#include #define snd_timer_chip(timer) ((timer)->private_data) @@ -52,6 +53,8 @@ struct snd_timer_hardware { int (*stop) (struct snd_timer * timer); int (*set_period) (struct snd_timer * timer, unsigned long period_num, unsigned long period_den); int (*precise_resolution) (struct snd_timer * timer, unsigned long *num, unsigned long *den); + + ANDROID_KABI_RESERVE(1); }; struct snd_timer { @@ -77,6 +80,8 @@ struct snd_timer { struct work_struct task_work; int max_instances; /* upper limit of timer instances */ int num_instances; /* current number of timer instances */ + + ANDROID_KABI_RESERVE(1); }; struct snd_timer_instance { @@ -106,6 +111,8 @@ struct snd_timer_instance { struct list_head slave_list_head; struct list_head slave_active_head; struct snd_timer_instance *master; + + ANDROID_KABI_RESERVE(1); }; /* diff --git a/include/trace/events/OWNERS b/include/trace/events/OWNERS deleted file mode 100644 index de3838b6df38..000000000000 --- a/include/trace/events/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/include/trace/events/OWNERS diff --git a/include/trace/events/cma.h b/include/trace/events/cma.h index 5cf385ae7c08..9c134325d6b2 100644 --- a/include/trace/events/cma.h +++ b/include/trace/events/cma.h @@ -91,6 +91,51 @@ TRACE_EVENT(cma_alloc_start, __entry->align) ); +TRACE_EVENT(cma_alloc_info, + + TP_PROTO(const char *name, const struct page *page, unsigned int count, unsigned int align, struct cma_alloc_info *info), + + TP_ARGS(name, page, count, align, info), + + TP_STRUCT__entry( + __string(name, name) + __field(unsigned long, pfn) + __field(unsigned int, count) + __field(unsigned int, align) + __field(unsigned long, nr_migrated) + __field(unsigned long, nr_reclaimed) + __field(unsigned long, nr_mapped) + __field(unsigned int, err_iso) + __field(unsigned int, err_mig) + __field(unsigned int, err_test) + ), + + TP_fast_assign( + __assign_str(name, name); + __entry->pfn = page ? page_to_pfn(page) : -1; + __entry->count = count; + __entry->align = align; + __entry->nr_migrated = info->nr_migrated; + __entry->nr_reclaimed = info->nr_reclaimed; + __entry->nr_mapped = info->nr_mapped; + __entry->err_iso = info->nr_isolate_fail; + __entry->err_mig = info->nr_migrate_fail; + __entry->err_test = info->nr_test_fail; + ), + + TP_printk("name=%s pfn=0x%lx count=%u align=%u nr_migrated=%lu nr_reclaimed=%lu nr_mapped=%lu err_iso=%u err_mig=%u err_test=%u", + __get_str(name), + __entry->pfn, + __entry->count, + __entry->align, + __entry->nr_migrated, + __entry->nr_reclaimed, + __entry->nr_mapped, + __entry->err_iso, + __entry->err_mig, + __entry->err_test) +); + DEFINE_EVENT(cma_alloc_class, cma_alloc_finish, TP_PROTO(const char *name, unsigned long pfn, const struct page *page, diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h index 629c7a0eaff2..390270e00a1d 100644 --- a/include/trace/events/mmflags.h +++ b/include/trace/events/mmflags.h @@ -85,6 +85,12 @@ #define IF_HAVE_PG_ARCH_2(flag,string) #endif +#ifdef CONFIG_KASAN_HW_TAGS +#define IF_HAVE_PG_SKIP_KASAN_POISON(flag,string) ,{1UL << flag, string} +#else +#define IF_HAVE_PG_SKIP_KASAN_POISON(flag,string) +#endif + #define __def_pageflag_names \ {1UL << PG_locked, "locked" }, \ {1UL << PG_waiters, "waiters" }, \ @@ -112,7 +118,8 @@ IF_HAVE_PG_UNCACHED(PG_uncached, "uncached" ) \ IF_HAVE_PG_HWPOISON(PG_hwpoison, "hwpoison" ) \ IF_HAVE_PG_IDLE(PG_young, "young" ) \ IF_HAVE_PG_IDLE(PG_idle, "idle" ) \ -IF_HAVE_PG_ARCH_2(PG_arch_2, "arch_2" ) +IF_HAVE_PG_ARCH_2(PG_arch_2, "arch_2" ) \ +IF_HAVE_PG_SKIP_KASAN_POISON(PG_skip_kasan_poison, "skip_kasan_poison") #define show_page_flags(flags) \ (flags) ? __print_flags(flags, "|", \ diff --git a/include/trace/hooks/binder.h b/include/trace/hooks/binder.h index ddeb936e8945..ffba8746e58b 100644 --- a/include/trace/hooks/binder.h +++ b/include/trace/hooks/binder.h @@ -17,10 +17,11 @@ struct binder_alloc; struct binder_proc; struct binder_thread; struct binder_transaction_data; +struct seq_file; DECLARE_HOOK(android_vh_binder_transaction_init, TP_PROTO(struct binder_transaction *t), TP_ARGS(t)); -DECLARE_HOOK(android_vh_binder_transaction_priority_skip, +DECLARE_HOOK(android_vh_binder_priority_skip, TP_PROTO(struct task_struct *task, bool *skip), TP_ARGS(task, skip)); DECLARE_HOOK(android_vh_binder_set_priority, @@ -65,6 +66,10 @@ DECLARE_HOOK(android_vh_binder_new_ref, DECLARE_HOOK(android_vh_binder_del_ref, TP_PROTO(struct task_struct *proc, uint32_t ref_desc), TP_ARGS(proc, ref_desc)); +DECLARE_HOOK(android_vh_binder_print_transaction_info, + TP_PROTO(struct seq_file *m, struct binder_proc *proc, + const char *prefix, struct binder_transaction *t), + TP_ARGS(m, proc, prefix, t)); /* macro versions of hooks are no longer required */ diff --git a/include/trace/hooks/block.h b/include/trace/hooks/block.h new file mode 100644 index 000000000000..0d9d7db39968 --- /dev/null +++ b/include/trace/hooks/block.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM block + +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_BLOCK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_BLOCK_H + +#include +#include + +struct blk_mq_tag_set; +struct blk_mq_tags; +struct blk_mq_alloc_data; + +DECLARE_HOOK(android_vh_blk_alloc_rqs, + TP_PROTO(size_t *rq_size, struct blk_mq_tag_set *set, + struct blk_mq_tags *tags), + TP_ARGS(rq_size, set, tags)); + +DECLARE_HOOK(android_vh_blk_rq_ctx_init, + TP_PROTO(struct request *rq, struct blk_mq_tags *tags, + struct blk_mq_alloc_data *data, u64 alloc_time_ns), + TP_ARGS(rq, tags, data, alloc_time_ns)); + +#endif /* _TRACE_HOOK_BLOCK_H */ + +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/cpufreq.h b/include/trace/hooks/cpufreq.h index 7208da2e7e3e..500c96ac7776 100644 --- a/include/trace/hooks/cpufreq.h +++ b/include/trace/hooks/cpufreq.h @@ -11,6 +11,10 @@ #include #include +DECLARE_RESTRICTED_HOOK(android_rvh_show_max_freq, + TP_PROTO(struct cpufreq_policy *policy, unsigned int *max_freq), + TP_ARGS(policy, max_freq), 1); + DECLARE_HOOK(android_vh_show_max_freq, TP_PROTO(struct cpufreq_policy *policy, unsigned int *max_freq), TP_ARGS(policy, max_freq)); diff --git a/include/trace/hooks/gic.h b/include/trace/hooks/gic.h index 6d51859e8f16..2f7d3cfa6d9b 100644 --- a/include/trace/hooks/gic.h +++ b/include/trace/hooks/gic.h @@ -7,15 +7,14 @@ #if !defined(_TRACE_HOOK_GIC_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_HOOK_GIC_H -#include #include #include +struct gic_chip_data; DECLARE_HOOK(android_vh_gic_resume, - TP_PROTO(struct irq_domain *domain, void __iomem *dist_base), - TP_ARGS(domain, dist_base)); - + TP_PROTO(struct gic_chip_data *gd), + TP_ARGS(gd)); /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_GIC_H */ diff --git a/include/trace/hooks/ipv4.h b/include/trace/hooks/ipv4.h new file mode 100644 index 000000000000..06fe06d675a4 --- /dev/null +++ b/include/trace/hooks/ipv4.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ipv4 +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_IPV4_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_IPV4_H +#include +#include + +DECLARE_RESTRICTED_HOOK(android_rvh_tcp_sendmsg_locked, + TP_PROTO(struct sock *sk, int size), + TP_ARGS(sk, size), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_tcp_recvmsg, + TP_PROTO(struct sock *sk), + TP_ARGS(sk), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_udp_sendmsg, + TP_PROTO(struct sock *sk), + TP_ARGS(sk), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_udp_recvmsg, + TP_PROTO(struct sock *sk), + TP_ARGS(sk), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_tcp_recvmsg_stat, + TP_PROTO(struct sock *sk, int size), + TP_ARGS(sk, size), 1); + +#endif /* _TRACE_HOOK_IPV4_H */ +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/ipv6.h b/include/trace/hooks/ipv6.h new file mode 100644 index 000000000000..c1998af0c5a0 --- /dev/null +++ b/include/trace/hooks/ipv6.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ipv6 +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_IPV6_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_IPV6_H +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ +DECLARE_HOOK(android_vh_ipv6_gen_linklocal_addr, + TP_PROTO(struct net_device *dev, bool *ret), + TP_ARGS(dev, ret)); + +/* macro versions of hooks are no longer required */ + +#endif /* _TRACE_HOOK_IPV6_H */ +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/logbuf.h b/include/trace/hooks/logbuf.h index a599bf8c2cbf..f73ad597fc64 100644 --- a/include/trace/hooks/logbuf.h +++ b/include/trace/hooks/logbuf.h @@ -10,16 +10,16 @@ #include #include -#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_ANDROID_VENDOR_HOOKS) struct printk_ringbuffer; struct printk_record; DECLARE_HOOK(android_vh_logbuf, TP_PROTO(struct printk_ringbuffer *rb, struct printk_record *r), TP_ARGS(rb, r)) -#else -#define trace_android_vh_logbuf(rb, r) -#endif + +DECLARE_HOOK(android_vh_logbuf_pr_cont, + TP_PROTO(struct printk_record *r, size_t text_len), + TP_ARGS(r, text_len)) #endif /* _TRACE_HOOK_LOGBUF_H */ /* This part must be outside protection */ diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 99655b3657ee..ac6142a6e02a 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -42,20 +42,26 @@ DECLARE_HOOK(android_vh_pagecache_get_page, TP_PROTO(struct address_space *mapping, pgoff_t index, int fgp_flags, gfp_t gfp_mask, struct page *page), TP_ARGS(mapping, index, fgp_flags, gfp_mask, page)); +DECLARE_HOOK(android_vh_filemap_fault_get_page, + TP_PROTO(struct vm_fault *vmf, struct page **page, bool *retry), + TP_ARGS(vmf, page, retry)); +DECLARE_HOOK(android_vh_filemap_fault_cache_page, + TP_PROTO(struct vm_fault *vmf, struct page *page), + TP_ARGS(vmf, page)); DECLARE_HOOK(android_vh_meminfo_proc_show, TP_PROTO(struct seq_file *m), TP_ARGS(m)); DECLARE_HOOK(android_vh_exit_mm, TP_PROTO(struct mm_struct *mm), TP_ARGS(mm)); -DECLARE_HOOK(android_vh_get_unmapped_area_from_anti_fragment_pool, +DECLARE_HOOK(android_vh_get_from_fragment_pool, TP_PROTO(struct mm_struct *mm, struct vm_unmapped_area_info *info, unsigned long *addr), TP_ARGS(mm, info, addr)); DECLARE_HOOK(android_vh_exclude_reserved_zone, TP_PROTO(struct mm_struct *mm, struct vm_unmapped_area_info *info), TP_ARGS(mm, info)); -DECLARE_HOOK(android_vh_get_unmapped_area_include_reserved_zone, +DECLARE_HOOK(android_vh_include_reserved_zone, TP_PROTO(struct mm_struct *mm, struct vm_unmapped_area_info *info, unsigned long *addr), TP_ARGS(mm, info, addr)); @@ -89,8 +95,28 @@ DECLARE_HOOK(android_vh_show_stack_hash, TP_PROTO(struct seq_file *m, struct vm_struct *v), TP_ARGS(m, v)); DECLARE_HOOK(android_vh_save_track_hash, - TP_PROTO(unsigned long p), - TP_ARGS(p)); + TP_PROTO(bool alloc, unsigned long p), + TP_ARGS(alloc, p)); +struct mem_cgroup; +DECLARE_HOOK(android_vh_vmpressure, + TP_PROTO(struct mem_cgroup *memcg, bool *bypass), + TP_ARGS(memcg, bypass)); +DECLARE_HOOK(android_vh_mem_cgroup_alloc, + TP_PROTO(struct mem_cgroup *memcg), + TP_ARGS(memcg)); +DECLARE_HOOK(android_vh_mem_cgroup_free, + TP_PROTO(struct mem_cgroup *memcg), + TP_ARGS(memcg)); +DECLARE_HOOK(android_vh_mem_cgroup_id_remove, + TP_PROTO(struct mem_cgroup *memcg), + TP_ARGS(memcg)); +struct cgroup_subsys_state; +DECLARE_HOOK(android_vh_mem_cgroup_css_online, + TP_PROTO(struct cgroup_subsys_state *css, struct mem_cgroup *memcg), + TP_ARGS(css, memcg)); +DECLARE_HOOK(android_vh_mem_cgroup_css_offline, + TP_PROTO(struct cgroup_subsys_state *css, struct mem_cgroup *memcg), + TP_ARGS(css, memcg)); /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_MM_H */ diff --git a/include/trace/hooks/net.h b/include/trace/hooks/net.h new file mode 100644 index 000000000000..6715aa4eb668 --- /dev/null +++ b/include/trace/hooks/net.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM net +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_NET_VH_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_NET_VH_H +#include +#include + +struct packet_type; +struct list_head; +struct sk_buff; +DECLARE_HOOK(android_vh_ptype_head, + TP_PROTO(const struct packet_type *pt, struct list_head *vendor_pt), + TP_ARGS(pt, vendor_pt)); +DECLARE_HOOK(android_vh_kfree_skb, + TP_PROTO(struct sk_buff *skb), TP_ARGS(skb)); + +struct nf_conn; +struct sock; +DECLARE_RESTRICTED_HOOK(android_rvh_nf_conn_alloc, + TP_PROTO(struct nf_conn *nf_conn), TP_ARGS(nf_conn), 1); +DECLARE_RESTRICTED_HOOK(android_rvh_nf_conn_free, + TP_PROTO(struct nf_conn *nf_conn), TP_ARGS(nf_conn), 1); +DECLARE_RESTRICTED_HOOK(android_rvh_sk_alloc, + TP_PROTO(struct sock *sock), TP_ARGS(sock), 1); +DECLARE_RESTRICTED_HOOK(android_rvh_sk_free, + TP_PROTO(struct sock *sock), TP_ARGS(sock), 1); + +/* macro versions of hooks are no longer required */ + +#endif /* _TRACE_HOOK_NET_VH_H */ +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/pci.h b/include/trace/hooks/pci.h new file mode 100644 index 000000000000..d9c5e4aec7d1 --- /dev/null +++ b/include/trace/hooks/pci.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM pci +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_PCI_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_PCI_H +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ + +DECLARE_RESTRICTED_HOOK(android_rvh_pci_d3_sleep, + TP_PROTO(struct pci_dev *dev, unsigned int delay, int *err), + TP_ARGS(dev, delay, err), 1); + +#endif /* _TRACE_HOOK_PCI_H */ + +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/power.h b/include/trace/hooks/power.h index 049c8995932d..149ea08580b8 100644 --- a/include/trace/hooks/power.h +++ b/include/trace/hooks/power.h @@ -20,6 +20,23 @@ DECLARE_HOOK(android_vh_try_to_freeze_todo_unfrozen, TP_PROTO(struct task_struct *p), TP_ARGS(p)); +enum freq_qos_req_type; +struct freq_qos_request; +struct freq_constraints; + +DECLARE_HOOK(android_vh_freq_qos_add_request, + TP_PROTO(struct freq_constraints *qos, struct freq_qos_request *req, + enum freq_qos_req_type type, int value, int ret), + TP_ARGS(qos, req, type, value, ret)); + +DECLARE_HOOK(android_vh_freq_qos_update_request, + TP_PROTO(struct freq_qos_request *req, int value), + TP_ARGS(req, value)); + +DECLARE_HOOK(android_vh_freq_qos_remove_request, + TP_PROTO(struct freq_qos_request *req), + TP_ARGS(req)); + /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_POWER_H */ diff --git a/include/trace/hooks/remoteproc.h b/include/trace/hooks/remoteproc.h new file mode 100644 index 000000000000..7cc5e93d2ebe --- /dev/null +++ b/include/trace/hooks/remoteproc.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM remoteproc + +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_RPROC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_RPROC_H + +#include +#include + +struct rproc; + +DECLARE_HOOK(android_vh_rproc_recovery, + TP_PROTO(struct rproc *rproc), + TP_ARGS(rproc)); + +#endif /* _TRACE_HOOK_RPROC_H */ +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index 622454f6f8c8..3b7d022c4328 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -370,13 +370,17 @@ DECLARE_RESTRICTED_HOOK(android_rvh_find_new_ilb, TP_PROTO(struct cpumask *nohz_idle_cpus_mask, int *ilb), TP_ARGS(nohz_idle_cpus_mask, ilb), 1); -DECLARE_HOOK(android_vh_force_compatible_pre, +DECLARE_RESTRICTED_HOOK(android_rvh_force_compatible_pre, TP_PROTO(void *unused), - TP_ARGS(unused)); + TP_ARGS(unused), 1); -DECLARE_HOOK(android_vh_force_compatible_post, +DECLARE_RESTRICTED_HOOK(android_rvh_force_compatible_post, TP_PROTO(void *unused), - TP_ARGS(unused)); + TP_ARGS(unused), 1); + +DECLARE_HOOK(android_vh_setscheduler_uclamp, + TP_PROTO(struct task_struct *tsk, int clamp_id, unsigned int value), + TP_ARGS(tsk, clamp_id, value)); /* macro versions of hooks are no longer required */ diff --git a/include/trace/hooks/shmem_fs.h b/include/trace/hooks/shmem_fs.h new file mode 100644 index 000000000000..08e63033070e --- /dev/null +++ b/include/trace/hooks/shmem_fs.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM shmem_fs +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH trace/hooks +#if !defined(_TRACE_HOOK_SHMEM_FS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_SHMEM_FS_H +#include +#include + +struct page; +DECLARE_HOOK(android_vh_shmem_alloc_page, + TP_PROTO(struct page **page), + TP_ARGS(page)); +#endif /* _TRACE_HOOK_SHMEM_FS_H */ +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/snd_compr.h b/include/trace/hooks/snd_compr.h new file mode 100644 index 000000000000..c42ed8d6bc30 --- /dev/null +++ b/include/trace/hooks/snd_compr.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM snd_compr + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH trace/hooks + +#if !defined(_TRACE_HOOK_SND_COMPR_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_SND_COMPR_H + +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ + +DECLARE_HOOK(android_vh_snd_compr_use_pause_in_drain, + TP_PROTO(bool *use_pause_in_drain, bool *leave_draining), + TP_ARGS(use_pause_in_drain, leave_draining)); + +#endif /* _TRACE_HOOK_SND_COMPR_H */ +/* This part must be outside protection */ +#include + diff --git a/include/trace/hooks/sound.h b/include/trace/hooks/sound.h new file mode 100644 index 000000000000..2bf018edf392 --- /dev/null +++ b/include/trace/hooks/sound.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sound +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH trace/hooks +#if !defined(_TRACE_HOOK_SOUND_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_SOUND_H +#include +#include +#include + +DECLARE_HOOK(android_vh_sound_usb_support_cpu_suspend, + TP_PROTO(struct usb_device *udev, + int direction, + bool *is_support), + TP_ARGS(udev, direction, is_support)); + +#endif /* _TRACE_HOOK_SOUND_H */ +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/syscall_check.h b/include/trace/hooks/syscall_check.h new file mode 100644 index 000000000000..d39802aa4a1e --- /dev/null +++ b/include/trace/hooks/syscall_check.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM syscall_check + +#define TRACE_INCLUDE_PATH trace/hooks +#if !defined(_TRACE_HOOK_SYSCALL_CHECK_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_SYSCALL_CHECK_H +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ +struct file; +union bpf_attr; +DECLARE_HOOK(android_vh_check_mmap_file, + TP_PROTO(const struct file *file, unsigned long prot, + unsigned long flag, unsigned long ret), + TP_ARGS(file, prot, flag, ret)); + +DECLARE_HOOK(android_vh_check_file_open, + TP_PROTO(const struct file *file), + TP_ARGS(file)); + +DECLARE_HOOK(android_vh_check_bpf_syscall, + TP_PROTO(int cmd, const union bpf_attr *attr, unsigned int size), + TP_ARGS(cmd, attr, size)); + +#endif /* _TRACE_HOOK_SYSCALL_CHECK_H */ +/* This part must be outside protection */ +#include diff --git a/include/trace/hooks/ufshcd.h b/include/trace/hooks/ufshcd.h index 6e37044eb264..ec8845a55076 100644 --- a/include/trace/hooks/ufshcd.h +++ b/include/trace/hooks/ufshcd.h @@ -19,6 +19,10 @@ DECLARE_HOOK(android_vh_ufs_fill_prdt, unsigned int segments, int *err), TP_ARGS(hba, lrbp, segments, err)); +DECLARE_RESTRICTED_HOOK(android_rvh_ufs_reprogram_all_keys, + TP_PROTO(struct ufs_hba *hba, int *err), + TP_ARGS(hba, err), 1); + DECLARE_HOOK(android_vh_ufs_prepare_command, TP_PROTO(struct ufs_hba *hba, struct request *rq, struct ufshcd_lrb *lrbp, int *err), @@ -55,6 +59,9 @@ DECLARE_HOOK(android_vh_ufs_update_sdev, TP_PROTO(struct scsi_device *sdev), TP_ARGS(sdev)); +DECLARE_HOOK(android_vh_ufs_clock_scaling, + TP_PROTO(struct ufs_hba *hba, bool *force_out, bool *force_scaling, bool *scale_up), + TP_ARGS(hba, force_out, force_scaling, scale_up)); #endif /* _TRACE_HOOK_UFSHCD_H */ /* This part must be outside protection */ #include diff --git a/include/trace/hooks/usb.h b/include/trace/hooks/usb.h new file mode 100644 index 000000000000..f8459473042e --- /dev/null +++ b/include/trace/hooks/usb.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM usb +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH trace/hooks +#if !defined(_TRACE_HOOK_USB_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_HOOK_USB_H +#include +#include +#include +/* + * Following tracepoints are not exported in tracefs and provide a + * mechanism for vendor modules to hook and extend functionality + */ + +DECLARE_HOOK(android_vh_usb_dev_suspend, + TP_PROTO(struct usb_device *udev, pm_message_t msg, int *bypass), + TP_ARGS(udev, msg, bypass)); + +DECLARE_HOOK(android_vh_usb_dev_resume, + TP_PROTO(struct usb_device *udev, pm_message_t msg, int *bypass), + TP_ARGS(udev, msg, bypass)); + +#endif /* _TRACE_HOOK_USB_H */ +/* This part must be outside protection */ +#include + diff --git a/include/trace/hooks/v4l2core.h b/include/trace/hooks/v4l2core.h index 26b49d69f13d..7207810a7e37 100644 --- a/include/trace/hooks/v4l2core.h +++ b/include/trace/hooks/v4l2core.h @@ -5,7 +5,7 @@ #define TRACE_INCLUDE_PATH trace/hooks #if !defined(_TRACE_HOOK_V4L2CORE_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_HOOK_V4L2_CORE_H +#define _TRACE_HOOK_V4L2CORE_H #include #include @@ -24,6 +24,41 @@ DECLARE_HOOK(android_vh_clear_mask_adjust, TP_PROTO(unsigned int ctrl, int *n), TP_ARGS(ctrl, n)); +struct v4l2_subdev; +struct v4l2_subdev_pad_config; +struct v4l2_subdev_selection; +DECLARE_HOOK(android_vh_v4l2subdev_set_selection, + TP_PROTO(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *pad, + struct v4l2_subdev_selection *sel, int *ret), + TP_ARGS(sd, pad, sel, ret)); + +struct v4l2_subdev_format; +DECLARE_HOOK(android_vh_v4l2subdev_set_fmt, + TP_PROTO(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *pad, + struct v4l2_subdev_format *format, int *ret), + TP_ARGS(sd, pad, format, ret)); + +struct v4l2_subdev_frame_interval; +DECLARE_HOOK(android_vh_v4l2subdev_set_frame_interval, + TP_PROTO(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *fi, + int *ret), + TP_ARGS(sd, fi, ret)); + +DECLARE_RESTRICTED_HOOK(android_rvh_v4l2subdev_set_selection, + TP_PROTO(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *pad, + struct v4l2_subdev_selection *sel, int *ret), + TP_ARGS(sd, pad, sel, ret), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_v4l2subdev_set_fmt, + TP_PROTO(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *pad, + struct v4l2_subdev_format *format, int *ret), + TP_ARGS(sd, pad, format, ret), 1); + +DECLARE_RESTRICTED_HOOK(android_rvh_v4l2subdev_set_frame_interval, + TP_PROTO(struct v4l2_subdev *sd, struct v4l2_subdev_frame_interval *fi, + int *ret), + TP_ARGS(sd, fi, ret), 1); + #endif /* _TRACE_HOOK_V4L2CORE_H */ /* This part must be outside protection */ #include diff --git a/include/trace/hooks/v4l2mc.h b/include/trace/hooks/v4l2mc.h index 8a4653bd4a4d..0f60515bb8e2 100644 --- a/include/trace/hooks/v4l2mc.h +++ b/include/trace/hooks/v4l2mc.h @@ -16,6 +16,11 @@ DECLARE_HOOK(android_vh_media_device_setup_link, TP_PROTO(struct media_link *link, struct media_link_desc *linkd, int *ret), TP_ARGS(link, linkd, ret)); +DECLARE_RESTRICTED_HOOK(android_rvh_media_device_setup_link, + TP_PROTO(struct media_link *link, + struct media_link_desc *linkd, int *ret), + TP_ARGS(link, linkd, ret), 1); + #endif /* _TRACE_HOOK_V4L2MC_H */ /* This part must be outside protection */ #include diff --git a/include/uapi/linux/OWNERS b/include/uapi/linux/OWNERS deleted file mode 100644 index 113046844b1c..000000000000 --- a/include/uapi/linux/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/include/uapi/linux/OWNERS diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h index 30f68b42eeb5..61bf4774b8f2 100644 --- a/include/uapi/linux/elf.h +++ b/include/uapi/linux/elf.h @@ -426,6 +426,7 @@ typedef struct elf64_shdr { #define NT_ARM_PACA_KEYS 0x407 /* ARM pointer authentication address keys */ #define NT_ARM_PACG_KEYS 0x408 /* ARM pointer authentication generic key */ #define NT_ARM_TAGGED_ADDR_CTRL 0x409 /* arm64 tagged address control (prctl()) */ +#define NT_ARM_PAC_ENABLED_KEYS 0x40a /* arm64 ptr auth enabled keys (prctl()) */ #define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */ #define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */ #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */ diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index c190e220ff67..58b37b12e745 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -234,14 +234,15 @@ struct prctl_mm_map { #define PR_GET_TAGGED_ADDR_CTRL 56 # define PR_TAGGED_ADDR_ENABLE (1UL << 0) /* MTE tag check fault modes */ -# define PR_MTE_TCF_SHIFT 1 -# define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT) -# define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT) -# define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT) -# define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT) +# define PR_MTE_TCF_NONE 0 +# define PR_MTE_TCF_SYNC (1UL << 1) +# define PR_MTE_TCF_ASYNC (1UL << 2) +# define PR_MTE_TCF_MASK (PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC) /* MTE tag inclusion mask */ # define PR_MTE_TAG_SHIFT 3 # define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) +/* Unused; kept only for source compatibility */ +# define PR_MTE_TCF_SHIFT 1 /* Control reclaim behavior when allocating memory */ #define PR_SET_IO_FLUSHER 57 @@ -250,4 +251,8 @@ struct prctl_mm_map { #define PR_SET_VMA 0x53564d41 # define PR_SET_VMA_ANON_NAME 0 +/* Set/get enabled arm64 pointer authentication keys */ +#define PR_PAC_SET_ENABLED_KEYS 60 +#define PR_PAC_GET_ENABLED_KEYS 61 + #endif /* _LINUX_PRCTL_H */ diff --git a/init/Kconfig b/init/Kconfig index 8d612c804584..780c32b42741 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -635,21 +635,6 @@ config PSI_DEFAULT_DISABLED Say N if unsure. -config PSI_PER_CGROUP_ACCT - bool "Enable per-cgroup pressure stall information tracking" - default n - depends on PSI - depends on CGROUPS - help - If set, pressure stall information will be tracked for each - individual cgroup. Otherwise, pressure stall information will - be tracked only at the system level under /proc/pressure/. - - This feature generates overhead that depends on the number of - cgroups in the cgroup v2 hierarchy. - - Say N if unsure. - endmenu # "CPU/Task time and stats accounting" config CPU_ISOLATION diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 9433ab9995cd..2fee91544ecb 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -32,6 +32,8 @@ #include #include +#include + #define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \ (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \ (map)->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS) @@ -4374,6 +4376,8 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz if (copy_from_user(&attr, uattr, size) != 0) return -EFAULT; + trace_android_vh_check_bpf_syscall(cmd, &attr, size); + err = security_bpf(cmd, &attr, size); if (err < 0) return err; diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 66981dfd3d7c..b320eee4aa03 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -212,6 +212,22 @@ struct cgroup_namespace init_cgroup_ns = { static struct file_system_type cgroup2_fs_type; static struct cftype cgroup_base_files[]; +/* cgroup optional features */ +enum cgroup_opt_features { +#ifdef CONFIG_PSI + OPT_FEATURE_PRESSURE, +#endif + OPT_FEATURE_COUNT +}; + +static const char *cgroup_opt_feature_names[OPT_FEATURE_COUNT] = { +#ifdef CONFIG_PSI + "pressure", +#endif +}; + +static u16 cgroup_feature_disable_mask __read_mostly; + static int cgroup_apply_control(struct cgroup *cgrp); static void cgroup_finalize_control(struct cgroup *cgrp, int ret); static void css_task_iter_skip(struct css_task_iter *it, @@ -3632,6 +3648,18 @@ static void cgroup_pressure_release(struct kernfs_open_file *of) { psi_trigger_replace(&of->priv, NULL); } + +bool cgroup_psi_enabled(void) +{ + return (cgroup_feature_disable_mask & (1 << OPT_FEATURE_PRESSURE)) == 0; +} + +#else /* CONFIG_PSI */ +bool cgroup_psi_enabled(void) +{ + return false; +} + #endif /* CONFIG_PSI */ static int cgroup_freeze_show(struct seq_file *seq, void *v) @@ -3882,6 +3910,8 @@ static int cgroup_addrm_files(struct cgroup_subsys_state *css, restart: for (cft = cfts; cft != cft_end && cft->name[0] != '\0'; cft++) { /* does cft->flags tell us to skip this file on @cgrp? */ + if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled()) + continue; if ((cft->flags & __CFTYPE_ONLY_ON_DFL) && !cgroup_on_dfl(cgrp)) continue; if ((cft->flags & __CFTYPE_NOT_ON_DFL) && cgroup_on_dfl(cgrp)) @@ -3959,6 +3989,9 @@ static int cgroup_init_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) WARN_ON(cft->ss || cft->kf_ops); + if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled()) + continue; + if (cft->seq_start) kf_ops = &cgroup_kf_ops; else @@ -4090,6 +4123,7 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts) cft->flags |= __CFTYPE_NOT_ON_DFL; return cgroup_add_cftypes(ss, cfts); } +EXPORT_SYMBOL_GPL(cgroup_add_legacy_cftypes); /** * cgroup_file_notify - generate a file modified event for a cgroup_file @@ -4895,6 +4929,7 @@ static struct cftype cgroup_base_files[] = { #ifdef CONFIG_PSI { .name = "io.pressure", + .flags = CFTYPE_PRESSURE, .seq_show = cgroup_io_pressure_show, .write = cgroup_io_pressure_write, .poll = cgroup_pressure_poll, @@ -4902,6 +4937,7 @@ static struct cftype cgroup_base_files[] = { }, { .name = "memory.pressure", + .flags = CFTYPE_PRESSURE, .seq_show = cgroup_memory_pressure_show, .write = cgroup_memory_pressure_write, .poll = cgroup_pressure_poll, @@ -4909,6 +4945,7 @@ static struct cftype cgroup_base_files[] = { }, { .name = "cpu.pressure", + .flags = CFTYPE_PRESSURE, .seq_show = cgroup_cpu_pressure_show, .write = cgroup_cpu_pressure_write, .poll = cgroup_pressure_poll, @@ -6259,6 +6296,15 @@ static int __init cgroup_disable(char *str) continue; cgroup_disable_mask |= 1 << i; } + + for (i = 0; i < OPT_FEATURE_COUNT; i++) { + if (strcmp(token, cgroup_opt_feature_names[i])) + continue; + cgroup_feature_disable_mask |= 1 << i; + pr_info("Disabling %s control group feature\n", + cgroup_opt_feature_names[i]); + break; + } } return 1; } @@ -6557,6 +6603,9 @@ static ssize_t show_delegatable_files(struct cftype *files, char *buf, if (!(cft->flags & CFTYPE_NS_DELEGATABLE)) continue; + if ((cft->flags & CFTYPE_PRESSURE) && !cgroup_psi_enabled()) + continue; + if (prefix) ret += snprintf(buf + ret, size - ret, "%s.", prefix); diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 0f61b14b0099..0ed0e1f215c7 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -667,6 +667,9 @@ void swiotlb_tbl_sync_single(struct device *hwdev, phys_addr_t tlb_addr, if (orig_addr == INVALID_PHYS_ADDR) return; + orig_addr += (tlb_addr & (IO_TLB_SIZE - 1)) - + swiotlb_align_offset(hwdev, orig_addr); + switch (target) { case SYNC_FOR_CPU: if (likely(dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)) diff --git a/kernel/fork.c b/kernel/fork.c index 0d7d98bc37fb..8f188222a41b 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -121,6 +121,8 @@ */ #define MAX_THREADS FUTEX_TID_MASK +EXPORT_TRACEPOINT_SYMBOL_GPL(task_newtask); + /* * Protected counters by write_lock_irq(&tasklist_lock) */ @@ -441,6 +443,7 @@ void put_task_stack(struct task_struct *tsk) if (refcount_dec_and_test(&tsk->stack_refcount)) release_task_stack(tsk); } +EXPORT_SYMBOL_GPL(put_task_stack); #endif void free_task(struct task_struct *tsk) diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig index 164a031cfdb6..ae9b13d5ee91 100644 --- a/kernel/irq/Kconfig +++ b/kernel/irq/Kconfig @@ -109,6 +109,9 @@ config GENERIC_IRQ_MATRIX_ALLOCATOR config GENERIC_IRQ_RESERVATION_MODE bool +config ARCH_WANTS_IRQ_RAW + bool + # Support forced irq threading config IRQ_FORCED_THREADING bool diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 9e385bd90552..37fbb3076174 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -1122,7 +1122,8 @@ irq_set_chip_and_handler_name(unsigned int irq, struct irq_chip *chip, } EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name); -void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) +void __irq_modify_status(unsigned int irq, unsigned long clr, + unsigned long set, unsigned long mask) { unsigned long flags, trigger, tmp; struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0); @@ -1136,7 +1137,9 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) */ WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN)); - irq_settings_clr_and_set(desc, clr, set); + /* Warn when trying to clear or set a bit disallowed by the mask */ + WARN_ON((clr | set) & ~mask); + __irq_settings_clr_and_set(desc, clr, set, mask); trigger = irqd_get_trigger_type(&desc->irq_data); @@ -1159,6 +1162,11 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) irq_put_desc_unlock(desc, flags); } + +void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set) +{ + __irq_modify_status(irq, clr, set, _IRQF_MODIFY_MASK); +} EXPORT_SYMBOL_GPL(irq_modify_status); /** diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c index e4cff358b437..f53475d88072 100644 --- a/kernel/irq/debugfs.c +++ b/kernel/irq/debugfs.c @@ -140,6 +140,7 @@ static const struct irq_bit_descr irqdesc_states[] = { BIT_MASK_DESCR(_IRQ_IS_POLLED), BIT_MASK_DESCR(_IRQ_DISABLE_UNLAZY), BIT_MASK_DESCR(_IRQ_HIDDEN), + BIT_MASK_DESCR(_IRQ_RAW), }; static const struct irq_bit_descr irqdesc_istates[] = { diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 86315fc9356a..aa636e19ea59 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -667,10 +667,9 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, { struct pt_regs *old_regs = set_irq_regs(regs); unsigned int irq = hwirq; + struct irq_desc *desc; int ret = 0; - irq_enter(); - #ifdef CONFIG_IRQ_DOMAIN if (lookup) irq = irq_find_mapping(domain, hwirq); @@ -680,14 +679,22 @@ int __handle_domain_irq(struct irq_domain *domain, unsigned int hwirq, * Some hardware gives randomly wrong interrupts. Rather * than crashing, do something sensible. */ - if (unlikely(!irq || irq >= nr_irqs)) { + if (unlikely(!irq || irq >= nr_irqs || !(desc = irq_to_desc(irq)))) { ack_bad_irq(irq); ret = -EINVAL; - } else { - generic_handle_irq(irq); + goto out; } - irq_exit(); + if (IS_ENABLED(CONFIG_ARCH_WANTS_IRQ_RAW) && + unlikely(irq_settings_is_raw(desc))) { + generic_handle_irq_desc(desc); + } else { + irq_enter(); + generic_handle_irq_desc(desc); + irq_exit(); + } + +out: set_irq_regs(old_regs); return ret; } diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h index 403378b9947b..0033d459fdac 100644 --- a/kernel/irq/settings.h +++ b/kernel/irq/settings.h @@ -18,6 +18,7 @@ enum { _IRQ_IS_POLLED = IRQ_IS_POLLED, _IRQ_DISABLE_UNLAZY = IRQ_DISABLE_UNLAZY, _IRQ_HIDDEN = IRQ_HIDDEN, + _IRQ_RAW = IRQ_RAW, _IRQF_MODIFY_MASK = IRQF_MODIFY_MASK, }; @@ -33,14 +34,21 @@ enum { #define IRQ_IS_POLLED GOT_YOU_MORON #define IRQ_DISABLE_UNLAZY GOT_YOU_MORON #define IRQ_HIDDEN GOT_YOU_MORON +#define IRQ_RAW GOT_YOU_MORON #undef IRQF_MODIFY_MASK #define IRQF_MODIFY_MASK GOT_YOU_MORON +static inline void +__irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set, u32 mask) +{ + desc->status_use_accessors &= ~(clr & mask); + desc->status_use_accessors |= (set & mask); +} + static inline void irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set) { - desc->status_use_accessors &= ~(clr & _IRQF_MODIFY_MASK); - desc->status_use_accessors |= (set & _IRQF_MODIFY_MASK); + __irq_settings_clr_and_set(desc, clr, set, _IRQF_MODIFY_MASK); } static inline bool irq_settings_is_per_cpu(struct irq_desc *desc) @@ -174,3 +182,16 @@ static inline bool irq_settings_is_hidden(struct irq_desc *desc) { return desc->status_use_accessors & _IRQ_HIDDEN; } + +static inline bool irq_settings_is_raw(struct irq_desc *desc) +{ + if (IS_ENABLED(CONFIG_ARCH_WANTS_IRQ_RAW)) + return desc->status_use_accessors & _IRQ_RAW; + + /* + * Using IRQ_RAW on architectures that don't expect it is + * likely to be wrong. + */ + WARN_ON_ONCE(1); + return false; +} diff --git a/kernel/module.c b/kernel/module.c index 26da85fcd877..c52adc976c01 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -4788,6 +4788,23 @@ void print_modules(void) pr_cont("\n"); } +#ifdef CONFIG_ANDROID_DEBUG_SYMBOLS +void android_debug_for_each_module(int (*fn)(const char *mod_name, void *mod_addr, void *data), + void *data) +{ + struct module *module; + + preempt_disable(); + list_for_each_entry_rcu(module, &modules, list) { + if (fn(module->name, module->core_layout.base, data)) + goto out; + } +out: + preempt_enable(); +} +EXPORT_SYMBOL_GPL(android_debug_for_each_module); +#endif + #ifdef CONFIG_MODVERSIONS /* Generate the signature for all relevant module structures here. * If these change, we don't want to try to parse the module. */ diff --git a/kernel/power/qos.c b/kernel/power/qos.c index ec7e1e85923e..8da76f9baca2 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -38,6 +38,9 @@ #include #include #include +#undef CREATE_TRACE_POINT +#include + /* * locking rule: all changes to constraints or notifiers lists @@ -546,6 +549,7 @@ int freq_qos_add_request(struct freq_constraints *qos, req->type = 0; } + trace_android_vh_freq_qos_add_request(qos, req, type, value, ret); return ret; } EXPORT_SYMBOL_GPL(freq_qos_add_request); @@ -570,6 +574,7 @@ int freq_qos_update_request(struct freq_qos_request *req, s32 new_value) "%s() called for unknown object\n", __func__)) return -EINVAL; + trace_android_vh_freq_qos_update_request(req, new_value); if (req->pnode.prio == new_value) return 0; @@ -598,6 +603,7 @@ int freq_qos_remove_request(struct freq_qos_request *req) "%s() called for unknown object\n", __func__)) return -EINVAL; + trace_android_vh_freq_qos_remove_request(req); ret = freq_qos_apply(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); req->qos = NULL; req->type = 0; diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 09b63b9aea9c..de278ccc3940 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1958,6 +1958,8 @@ static size_t log_output(int facility, int level, enum log_flags lflags, } else { prb_commit(&e); } + + trace_android_vh_logbuf_pr_cont(&r, text_len); return text_len; } } diff --git a/kernel/sched/OWNERS b/kernel/sched/OWNERS deleted file mode 100644 index fc027b64b61b..000000000000 --- a/kernel/sched/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/kernel/sched/OWNERS diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 332cfe2e5415..adac9409fb2e 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1321,6 +1321,23 @@ static inline void uclamp_rq_dec(struct rq *rq, struct task_struct *p) uclamp_rq_dec_id(rq, p, clamp_id); } +static inline void uclamp_rq_reinc_id(struct rq *rq, struct task_struct *p, + enum uclamp_id clamp_id) +{ + if (!p->uclamp[clamp_id].active) + return; + + uclamp_rq_dec_id(rq, p, clamp_id); + uclamp_rq_inc_id(rq, p, clamp_id); + + /* + * Make sure to clear the idle flag if we've transiently reached 0 + * active tasks on rq. + */ + if (clamp_id == UCLAMP_MAX && (rq->uclamp_flags & UCLAMP_FLAG_IDLE)) + rq->uclamp_flags &= ~UCLAMP_FLAG_IDLE; +} + static inline void uclamp_update_active(struct task_struct *p, enum uclamp_id clamp_id) { @@ -1343,10 +1360,7 @@ uclamp_update_active(struct task_struct *p, enum uclamp_id clamp_id) * affecting a valid clamp bucket, the next time it's enqueued, * it will already see the updated clamp bucket value. */ - if (p->uclamp[clamp_id].active) { - uclamp_rq_dec_id(rq, p, clamp_id); - uclamp_rq_inc_id(rq, p, clamp_id); - } + uclamp_rq_reinc_id(rq, p, clamp_id); task_rq_unlock(rq, p, &rf); } @@ -1545,12 +1559,14 @@ static void __setscheduler_uclamp(struct task_struct *p, attr->sched_util_min != -1) { uclamp_se_set(&p->uclamp_req[UCLAMP_MIN], attr->sched_util_min, true); + trace_android_vh_setscheduler_uclamp(p, UCLAMP_MIN, attr->sched_util_min); } if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP_MAX && attr->sched_util_max != -1) { uclamp_se_set(&p->uclamp_req[UCLAMP_MAX], attr->sched_util_max, true); + trace_android_vh_setscheduler_uclamp(p, UCLAMP_MAX, attr->sched_util_max); } } @@ -2105,7 +2121,7 @@ void force_compatible_cpus_allowed_ptr(struct task_struct *p) * offlining of the chosen destination CPU, so take the hotplug * lock to ensure that the migration succeeds. */ - trace_android_vh_force_compatible_pre(NULL); + trace_android_rvh_force_compatible_pre(NULL); cpus_read_lock(); if (!cpumask_available(new_mask)) goto out_set_mask; @@ -2130,7 +2146,7 @@ void force_compatible_cpus_allowed_ptr(struct task_struct *p) WARN_ON(set_cpus_allowed_ptr(p, override_mask)); out_free_mask: cpus_read_unlock(); - trace_android_vh_force_compatible_post(NULL); + trace_android_rvh_force_compatible_post(NULL); free_cpumask_var(new_mask); } @@ -2480,9 +2496,7 @@ static int select_fallback_rq(int cpu, struct task_struct *p) /* Look for allowed, online CPU in same node. */ for_each_cpu(dest_cpu, nodemask) { - if (!cpu_active(dest_cpu)) - continue; - if (cpumask_test_cpu(dest_cpu, p->cpus_ptr)) + if (is_cpu_allowed(p, dest_cpu)) return dest_cpu; } } @@ -4203,6 +4217,7 @@ unsigned long long task_sched_runtime(struct task_struct *p) return ns; } +EXPORT_SYMBOL_GPL(task_sched_runtime); /* * This function gets called by the timer code, with HZ frequency. @@ -5540,6 +5555,10 @@ static int __sched_setscheduler(struct task_struct *p, /* Normal users shall not reset the sched_reset_on_fork flag: */ if (p->sched_reset_on_fork && !reset_on_fork) return -EPERM; + + /* Can't change util-clamps */ + if (attr->sched_flags & SCHED_FLAG_UTIL_CLAMP) + return -EPERM; } if (user) { @@ -5887,6 +5906,16 @@ static int sched_copy_attr(struct sched_attr __user *uattr, struct sched_attr *a return -E2BIG; } +static void get_params(struct task_struct *p, struct sched_attr *attr) +{ + if (task_has_dl_policy(p)) + __getparam_dl(p, attr); + else if (task_has_rt_policy(p)) + attr->sched_priority = p->rt_priority; + else + attr->sched_nice = task_nice(p); +} + /** * sys_sched_setscheduler - set/change the scheduler policy and RT priority * @pid: the pid in question. @@ -5948,6 +5977,8 @@ SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, rcu_read_unlock(); if (likely(p)) { + if (attr.sched_flags & SCHED_FLAG_KEEP_PARAMS) + get_params(p, &attr); retval = sched_setattr(p, &attr); put_task_struct(p); } @@ -6096,12 +6127,8 @@ SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, kattr.sched_policy = p->policy; if (p->sched_reset_on_fork) kattr.sched_flags |= SCHED_FLAG_RESET_ON_FORK; - if (task_has_dl_policy(p)) - __getparam_dl(p, &kattr); - else if (task_has_rt_policy(p)) - kattr.sched_priority = p->rt_priority; - else - kattr.sched_nice = task_nice(p); + get_params(p, &kattr); + kattr.sched_flags &= SCHED_FLAG_ALL; #ifdef CONFIG_UCLAMP_TASK /* diff --git a/kernel/sched/cpufreq.c b/kernel/sched/cpufreq.c index 3d5f5a80b401..17fa9566e705 100644 --- a/kernel/sched/cpufreq.c +++ b/kernel/sched/cpufreq.c @@ -10,6 +10,7 @@ #include "sched.h" DEFINE_PER_CPU(struct update_util_data __rcu *, cpufreq_update_util_data); +EXPORT_PER_CPU_SYMBOL_GPL(cpufreq_update_util_data); /** * cpufreq_add_update_util_hook - Populate the CPU's update_util_data pointer. diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index e7525f2caa58..a09dfcdbe055 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -2704,7 +2704,7 @@ void __setparam_dl(struct task_struct *p, const struct sched_attr *attr) dl_se->dl_runtime = attr->sched_runtime; dl_se->dl_deadline = attr->sched_deadline; dl_se->dl_period = attr->sched_period ?: dl_se->dl_deadline; - dl_se->flags = attr->sched_flags; + dl_se->flags = attr->sched_flags & SCHED_DL_FLAGS; dl_se->dl_bw = to_ratio(dl_se->dl_period, dl_se->dl_runtime); dl_se->dl_density = to_ratio(dl_se->dl_deadline, dl_se->dl_runtime); } @@ -2717,7 +2717,8 @@ void __getparam_dl(struct task_struct *p, struct sched_attr *attr) attr->sched_runtime = dl_se->dl_runtime; attr->sched_deadline = dl_se->dl_deadline; attr->sched_period = dl_se->dl_period; - attr->sched_flags = dl_se->flags; + attr->sched_flags &= ~SCHED_DL_FLAGS; + attr->sched_flags |= dl_se->flags; } /* @@ -2814,7 +2815,7 @@ bool dl_param_changed(struct task_struct *p, const struct sched_attr *attr) if (dl_se->dl_runtime != attr->sched_runtime || dl_se->dl_deadline != attr->sched_deadline || dl_se->dl_period != attr->sched_period || - dl_se->flags != attr->sched_flags) + dl_se->flags != (attr->sched_flags & SCHED_DL_FLAGS)) return true; return false; diff --git a/kernel/sched/pelt.c b/kernel/sched/pelt.c index cd54fab42cf4..bbb0de2219f9 100644 --- a/kernel/sched/pelt.c +++ b/kernel/sched/pelt.c @@ -32,15 +32,16 @@ int pelt_load_avg_period = PELT32_LOAD_AVG_PERIOD; int pelt_load_avg_max = PELT32_LOAD_AVG_MAX; const u32 *pelt_runnable_avg_yN_inv = pelt32_runnable_avg_yN_inv; -static int __init set_pelt(char *str) +int get_pelt_halflife(void) { - int rc, num; + return pelt_load_avg_period; +} +EXPORT_SYMBOL_GPL(get_pelt_halflife); - rc = kstrtoint(str, 0, &num); - if (rc) { - pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); - return 0; - } +static int __set_pelt_halflife(void *data) +{ + int rc = 0; + int num = *(int *)data; switch (num) { case PELT8_LOAD_AVG_PERIOD: @@ -56,10 +57,32 @@ static int __init set_pelt(char *str) pr_info("PELT half life is set to %dms\n", num); break; default: - pr_err("Default PELT half life is 32ms\n"); + rc = -EINVAL; + pr_err("Failed to set PELT half life to %dms, the current value is %dms\n", + num, pelt_load_avg_period); } - return 0; + return rc; +} + +int set_pelt_halflife(int num) +{ + return stop_machine(__set_pelt_halflife, &num, NULL); +} +EXPORT_SYMBOL_GPL(set_pelt_halflife); + +static int __init set_pelt(char *str) +{ + int rc, num; + + rc = kstrtoint(str, 0, &num); + if (rc) { + pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc); + return 0; + } + + __set_pelt_halflife(&num); + return rc; } early_param("pelt", set_pelt); diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index ecd0618dcaad..c2bc611e6430 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -147,6 +147,7 @@ static int psi_bug __read_mostly; DEFINE_STATIC_KEY_FALSE(psi_disabled); +DEFINE_STATIC_KEY_TRUE(psi_cgroups_enabled); #ifdef CONFIG_PSI_DEFAULT_DISABLED static bool psi_enable; @@ -192,6 +193,7 @@ static void group_init(struct psi_group *group) INIT_DELAYED_WORK(&group->avgs_work, psi_avgs_work); mutex_init(&group->avgs_lock); /* Init trigger-related members */ + atomic_set(&group->poll_scheduled, 0); mutex_init(&group->trigger_lock); INIT_LIST_HEAD(&group->triggers); memset(group->nr_triggers, 0, sizeof(group->nr_triggers)); @@ -210,6 +212,9 @@ void __init psi_init(void) return; } + if (!cgroup_psi_enabled()) + static_branch_disable(&psi_cgroups_enabled); + psi_period = jiffies_to_nsecs(PSI_FREQ); group_init(&psi_system); } @@ -552,18 +557,17 @@ static u64 update_triggers(struct psi_group *group, u64 now) return now + group->poll_min_period; } -/* Schedule polling if it's not already scheduled. */ -static void psi_schedule_poll_work(struct psi_group *group, unsigned long delay) +/* Schedule polling if it's not already scheduled or forced. */ +static void psi_schedule_poll_work(struct psi_group *group, unsigned long delay, + bool force) { struct task_struct *task; /* - * Do not reschedule if already scheduled. - * Possible race with a timer scheduled after this check but before - * mod_timer below can be tolerated because group->polling_next_update - * will keep updates on schedule. + * atomic_xchg should be called even when !force to provide a + * full memory barrier (see the comment inside psi_poll_work). */ - if (timer_pending(&group->poll_timer)) + if (atomic_xchg(&group->poll_scheduled, 1) && !force) return; rcu_read_lock(); @@ -575,12 +579,15 @@ static void psi_schedule_poll_work(struct psi_group *group, unsigned long delay) */ if (likely(task)) mod_timer(&group->poll_timer, jiffies + delay); + else + atomic_set(&group->poll_scheduled, 0); rcu_read_unlock(); } static void psi_poll_work(struct psi_group *group) { + bool force_reschedule = false; u32 changed_states; u64 now; @@ -588,6 +595,43 @@ static void psi_poll_work(struct psi_group *group) now = sched_clock(); + if (now > group->polling_until) { + /* + * We are either about to start or might stop polling if no + * state change was recorded. Resetting poll_scheduled leaves + * a small window for psi_group_change to sneak in and schedule + * an immegiate poll_work before we get to rescheduling. One + * potential extra wakeup at the end of the polling window + * should be negligible and polling_next_update still keeps + * updates correctly on schedule. + */ + atomic_set(&group->poll_scheduled, 0); + /* + * A task change can race with the poll worker that is supposed to + * report on it. To avoid missing events, ensure ordering between + * poll_scheduled and the task state accesses, such that if the poll + * worker misses the state update, the task change is guaranteed to + * reschedule the poll worker: + * + * poll worker: + * atomic_set(poll_scheduled, 0) + * smp_mb() + * LOAD states + * + * task change: + * STORE states + * if atomic_xchg(poll_scheduled, 1) == 0: + * schedule poll worker + * + * The atomic_xchg() implies a full barrier. + */ + smp_mb(); + } else { + /* Polling window is not over, keep rescheduling */ + force_reschedule = true; + } + + collect_percpu_times(group, PSI_POLL, &changed_states); if (changed_states & group->poll_states) { @@ -613,7 +657,8 @@ static void psi_poll_work(struct psi_group *group) group->polling_next_update = update_triggers(group, now); psi_schedule_poll_work(group, - nsecs_to_jiffies(group->polling_next_update - now) + 1); + nsecs_to_jiffies(group->polling_next_update - now) + 1, + force_reschedule); out: mutex_unlock(&group->trigger_lock); @@ -742,7 +787,7 @@ static void psi_group_change(struct psi_group *group, int cpu, write_seqcount_end(&groupc->seq); if (state_mask & group->poll_states) - psi_schedule_poll_work(group, 1); + psi_schedule_poll_work(group, 1, false); if (wake_clock && !delayed_work_pending(&group->avgs_work)) schedule_delayed_work(&group->avgs_work, PSI_FREQ); @@ -750,23 +795,23 @@ static void psi_group_change(struct psi_group *group, int cpu, static struct psi_group *iterate_groups(struct task_struct *task, void **iter) { -#if defined CONFIG_CGROUPS && defined CONFIG_PSI_PER_CGROUP_ACCT - struct cgroup *cgroup = NULL; - - if (!*iter) - cgroup = task->cgroups->dfl_cgrp; - else if (*iter == &psi_system) + if (*iter == &psi_system) return NULL; - else - cgroup = cgroup_parent(*iter); - if (cgroup && cgroup_parent(cgroup)) { - *iter = cgroup; - return cgroup_psi(cgroup); +#ifdef CONFIG_CGROUPS + if (static_branch_likely(&psi_cgroups_enabled)) { + struct cgroup *cgroup = NULL; + + if (!*iter) + cgroup = task->cgroups->dfl_cgrp; + else + cgroup = cgroup_parent(*iter); + + if (cgroup && cgroup_parent(cgroup)) { + *iter = cgroup; + return cgroup_psi(cgroup); + } } -#else - if (*iter) - return NULL; #endif *iter = &psi_system; return &psi_system; @@ -1210,6 +1255,7 @@ static void psi_trigger_destroy(struct kref *ref) */ del_timer_sync(&group->poll_timer); kthread_stop(task_to_destroy); + atomic_set(&group->poll_scheduled, 0); } kfree(t); } diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index bcd1b1d9ebb8..d612e837764e 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -228,6 +228,8 @@ static inline void update_avg(u64 *avg, u64 sample) */ #define SCHED_FLAG_SUGOV 0x10000000 +#define SCHED_DL_FLAGS (SCHED_FLAG_RECLAIM | SCHED_FLAG_DL_OVERRUN | SCHED_FLAG_SUGOV) + static inline bool dl_entity_is_special(struct sched_dl_entity *dl_se) { #ifdef CONFIG_CPU_FREQ_GOV_SCHEDUTIL @@ -613,6 +615,8 @@ struct cfs_rq { int throttle_count; struct list_head throttled_list; #endif /* CONFIG_CFS_BANDWIDTH */ + + ANDROID_VENDOR_DATA_ARRAY(1, 16); #endif /* CONFIG_FAIR_GROUP_SCHED */ }; diff --git a/kernel/smp.c b/kernel/smp.c index b5dd54708781..d7033091bdfb 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -967,6 +967,27 @@ void wake_up_all_idle_cpus(void) } EXPORT_SYMBOL_GPL(wake_up_all_idle_cpus); +/** + * wake_up_all_online_idle_cpus - break all online cpus out of idle + * wake_up_all_online_idle_cpus try to break all online cpus which is in idle + * state even including idle polling cpus, for non-idle cpus, we will do nothing + * for them. + */ +void wake_up_all_online_idle_cpus(void) +{ + int cpu; + + preempt_disable(); + for_each_online_cpu(cpu) { + if (cpu == smp_processor_id()) + continue; + + wake_up_if_idle(cpu); + } + preempt_enable(); +} +EXPORT_SYMBOL_GPL(wake_up_all_online_idle_cpus); + /** * smp_call_on_cpu - Call a function on a specific cpu * diff --git a/kernel/sys.c b/kernel/sys.c index 452ac56bc628..e000e9b38e89 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -123,6 +123,12 @@ #ifndef PAC_RESET_KEYS # define PAC_RESET_KEYS(a, b) (-EINVAL) #endif +#ifndef PAC_SET_ENABLED_KEYS +# define PAC_SET_ENABLED_KEYS(a, b, c) (-EINVAL) +#endif +#ifndef PAC_GET_ENABLED_KEYS +# define PAC_GET_ENABLED_KEYS(a) (-EINVAL) +#endif #ifndef SET_TAGGED_ADDR_CTRL # define SET_TAGGED_ADDR_CTRL(a) (-EINVAL) #endif @@ -2651,6 +2657,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, return -EINVAL; error = PAC_RESET_KEYS(me, arg2); break; + case PR_PAC_SET_ENABLED_KEYS: + if (arg4 || arg5) + return -EINVAL; + error = PAC_SET_ENABLED_KEYS(me, arg2, arg3); + break; + case PR_PAC_GET_ENABLED_KEYS: + if (arg2 || arg3 || arg4 || arg5) + return -EINVAL; + error = PAC_GET_ENABLED_KEYS(me); + break; case PR_SET_TAGGED_ADDR_CTRL: if (arg3 || arg4 || arg5) return -EINVAL; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 20dfb9427fdf..7aed10c7dea9 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -2858,7 +2858,7 @@ static struct ctl_table vm_table[] = { .data = &sysctl_compaction_proactiveness, .maxlen = sizeof(sysctl_compaction_proactiveness), .mode = 0644, - .proc_handler = proc_dointvec_minmax, + .proc_handler = compaction_proactiveness_sysctl_handler, .extra1 = SYSCTL_ZERO, .extra2 = &one_hundred, }, diff --git a/lib/debug_locks.c b/lib/debug_locks.c index 06d3135bd184..f91b5d31f63c 100644 --- a/lib/debug_locks.c +++ b/lib/debug_locks.c @@ -38,12 +38,8 @@ EXPORT_SYMBOL_GPL(debug_locks_silent); */ noinstr int debug_locks_off(void) { - if (debug_locks && __debug_locks_off()) { - if (!debug_locks_silent) { - console_verbose(); - return 1; - } - } + if (debug_locks && __debug_locks_off() && !debug_locks_silent) + return 1; return 0; } EXPORT_SYMBOL_GPL(debug_locks_off); diff --git a/lib/show_mem.c b/lib/show_mem.c index 663e312814cb..3d8d609bbf54 100644 --- a/lib/show_mem.c +++ b/lib/show_mem.c @@ -43,3 +43,4 @@ void show_mem(unsigned int filter, nodemask_t *nodemask) #endif trace_android_vh_show_mem(filter, nodemask); } +EXPORT_SYMBOL_GPL(show_mem); diff --git a/mm/OWNERS b/mm/OWNERS deleted file mode 100644 index f89766e706e0..000000000000 --- a/mm/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/mm/OWNERS diff --git a/mm/cma.c b/mm/cma.c index 7bbc98a90e29..47538607045e 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -443,6 +443,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, int num_attempts = 0; int max_retries = 5; s64 ts; + struct cma_alloc_info cma_info = {0}; trace_android_vh_cma_alloc_start(&ts); @@ -466,6 +467,8 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, goto out; for (;;) { + struct acr_info info = {0}; + mutex_lock(&cma->lock); bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap, bitmap_maxno, start, bitmap_count, mask, @@ -474,7 +477,8 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, if ((num_attempts < max_retries) && (ret == -EBUSY)) { mutex_unlock(&cma->lock); - if (fatal_signal_pending(current)) + if (fatal_signal_pending(current) || + (gfp_mask & __GFP_NORETRY)) break; /* @@ -503,7 +507,18 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, mutex_unlock(&cma->lock); pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit); - ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, gfp_mask); + ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, gfp_mask, &info); + cma_info.nr_migrated += info.nr_migrated; + cma_info.nr_reclaimed += info.nr_reclaimed; + cma_info.nr_mapped += info.nr_mapped; + if (info.err) { + if (info.err & ACR_ERR_ISOLATE) + cma_info.nr_isolate_fail++; + if (info.err & ACR_ERR_MIGRATE) + cma_info.nr_migrate_fail++; + if (info.err & ACR_ERR_TEST) + cma_info.nr_test_fail++; + } if (ret == 0) { page = pfn_to_page(pfn); break; @@ -518,11 +533,20 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, trace_cma_alloc_busy_retry(cma->name, pfn, pfn_to_page(pfn), count, align); - /* try again with a bit different memory target */ - start = bitmap_no + mask + 1; + + if (info.failed_pfn && gfp_mask & __GFP_NORETRY) { + /* try again from following failed page */ + start = (pfn_max_align_up(info.failed_pfn + 1) - + cma->base_pfn) >> cma->order_per_bit; + + } else { + /* try again with a bit different memory target */ + start = bitmap_no + mask + 1; + } } trace_cma_alloc_finish(cma->name, pfn, page, count, align); + trace_cma_alloc_info(cma->name, page, count, align, &cma_info); /* * CMA can allocate multiple page blocks, which results in different diff --git a/mm/compaction.c b/mm/compaction.c index 8f28896cfc6c..822e6221b0a9 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1914,20 +1914,28 @@ static bool kswapd_is_running(pg_data_t *pgdat) /* * A zone's fragmentation score is the external fragmentation wrt to the - * COMPACTION_HPAGE_ORDER scaled by the zone's size. It returns a value - * in the range [0, 100]. + * COMPACTION_HPAGE_ORDER. It returns a value in the range [0, 100]. + */ +static unsigned int fragmentation_score_zone(struct zone *zone) +{ + return extfrag_for_order(zone, COMPACTION_HPAGE_ORDER); +} + +/* + * A weighted zone's fragmentation score is the external fragmentation + * wrt to the COMPACTION_HPAGE_ORDER scaled by the zone's size. It + * returns a value in the range [0, 100]. * * The scaling factor ensures that proactive compaction focuses on larger * zones like ZONE_NORMAL, rather than smaller, specialized zones like * ZONE_DMA32. For smaller zones, the score value remains close to zero, * and thus never exceeds the high threshold for proactive compaction. */ -static unsigned int fragmentation_score_zone(struct zone *zone) +static unsigned int fragmentation_score_zone_weighted(struct zone *zone) { unsigned long score; - score = zone->present_pages * - extfrag_for_order(zone, COMPACTION_HPAGE_ORDER); + score = zone->present_pages * fragmentation_score_zone(zone); return div64_ul(score, zone->zone_pgdat->node_present_pages + 1); } @@ -1947,7 +1955,7 @@ static unsigned int fragmentation_score_node(pg_data_t *pgdat) struct zone *zone; zone = &pgdat->node_zones[zoneid]; - score += fragmentation_score_zone(zone); + score += fragmentation_score_zone_weighted(zone); } return score; @@ -2650,6 +2658,30 @@ int sysctl_compact_memory; */ unsigned int __read_mostly sysctl_compaction_proactiveness = 20; +int compaction_proactiveness_sysctl_handler(struct ctl_table *table, int write, + void *buffer, size_t *length, loff_t *ppos) +{ + int rc, nid; + + rc = proc_dointvec_minmax(table, write, buffer, length, ppos); + if (rc) + return rc; + + if (write && sysctl_compaction_proactiveness) { + for_each_online_node(nid) { + pg_data_t *pgdat = NODE_DATA(nid); + + if (pgdat->proactive_compact_trigger) + continue; + + pgdat->proactive_compact_trigger = true; + wake_up_interruptible(&pgdat->kcompactd_wait); + } + } + + return 0; +} + /* * This is the entry point for compacting all nodes via * /proc/sys/vm/compact_memory @@ -2694,7 +2726,8 @@ void compaction_unregister_node(struct node *node) static inline bool kcompactd_work_requested(pg_data_t *pgdat) { - return pgdat->kcompactd_max_order > 0 || kthread_should_stop(); + return pgdat->kcompactd_max_order > 0 || kthread_should_stop() || + pgdat->proactive_compact_trigger; } static bool kcompactd_node_suitable(pg_data_t *pgdat) @@ -2843,11 +2876,15 @@ static int kcompactd(void *p) while (!kthread_should_stop()) { unsigned long pflags; + long timeout; + timeout = sysctl_compaction_proactiveness ? + msecs_to_jiffies(HPAGE_FRAG_CHECK_INTERVAL_MSEC) : + MAX_SCHEDULE_TIMEOUT; trace_mm_compaction_kcompactd_sleep(pgdat->node_id); if (wait_event_freezable_timeout(pgdat->kcompactd_wait, - kcompactd_work_requested(pgdat), - msecs_to_jiffies(HPAGE_FRAG_CHECK_INTERVAL_MSEC))) { + kcompactd_work_requested(pgdat), timeout) && + !pgdat->proactive_compact_trigger) { psi_memstall_enter(&pflags); kcompactd_do_work(pgdat); @@ -2859,10 +2896,20 @@ static int kcompactd(void *p) if (should_proactive_compact_node(pgdat)) { unsigned int prev_score, score; - if (proactive_defer) { + /* + * On wakeup of proactive compaction by sysctl + * write, ignore the accumulated defer score. + * Anyway, if the proactive compaction didn't + * make any progress for the new value, it will + * be further deferred by 2^COMPACT_MAX_DEFER_SHIFT + * times. + */ + if (proactive_defer && + !pgdat->proactive_compact_trigger) { proactive_defer--; continue; } + prev_score = fragmentation_score_node(pgdat); proactive_compact_node(pgdat); score = fragmentation_score_node(pgdat); @@ -2873,6 +2920,8 @@ static int kcompactd(void *p) proactive_defer = score < prev_score ? 0 : 1 << COMPACT_MAX_DEFER_SHIFT; } + if (pgdat->proactive_compact_trigger) + pgdat->proactive_compact_trigger = false; } return 0; diff --git a/mm/filemap.c b/mm/filemap.c index ae831c96b5fc..d60dd67000fb 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2728,13 +2728,20 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) struct inode *inode = mapping->host; pgoff_t offset = vmf->pgoff; pgoff_t max_off; - struct page *page; + struct page *page = NULL; vm_fault_t ret = 0; + bool retry = false; max_off = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); if (unlikely(offset >= max_off)) return VM_FAULT_SIGBUS; + trace_android_vh_filemap_fault_get_page(vmf, &page, &retry); + if (unlikely(retry)) + goto out_retry; + if (unlikely(page)) + goto page_ok; + /* * Do we have something in the page cache already? */ @@ -2790,6 +2797,7 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) goto out_retry; } +page_ok: /* * Found the page and have a reference on it. * We must recheck i_size under page lock. @@ -2835,8 +2843,10 @@ vm_fault_t filemap_fault(struct vm_fault *vmf) * re-find the vma and come back and find our hopefully still populated * page. */ - if (page) + if (page) { + trace_android_vh_filemap_fault_cache_page(vmf, page); put_page(page); + } if (fpin) fput(fpin); return ret | VM_FAULT_RETRY; diff --git a/mm/kasan/common.c b/mm/kasan/common.c index 6bb87f2acd4e..0ecd293af344 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -97,7 +97,7 @@ slab_flags_t __kasan_never_merge(void) return 0; } -void __kasan_alloc_pages(struct page *page, unsigned int order, bool init) +void __kasan_unpoison_pages(struct page *page, unsigned int order, bool init) { u8 tag; unsigned long i; @@ -111,7 +111,7 @@ void __kasan_alloc_pages(struct page *page, unsigned int order, bool init) kasan_unpoison(page_address(page), PAGE_SIZE << order, init); } -void __kasan_free_pages(struct page *page, unsigned int order, bool init) +void __kasan_poison_pages(struct page *page, unsigned int order, bool init) { if (likely(!PageHighMem(page))) kasan_poison(page_address(page), PAGE_SIZE << order, diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index 4004388b4e4b..ed5e5b833d61 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -238,6 +238,38 @@ struct kasan_track *kasan_get_free_track(struct kmem_cache *cache, return &alloc_meta->free_track[0]; } +void kasan_alloc_pages(struct page *page, unsigned int order, gfp_t flags) +{ + /* + * This condition should match the one in post_alloc_hook() in + * page_alloc.c. + */ + bool init = !want_init_on_free() && want_init_on_alloc(flags); + + if (flags & __GFP_SKIP_KASAN_POISON) + SetPageSkipKASanPoison(page); + + if (flags & __GFP_ZEROTAGS) { + int i; + + for (i = 0; i != 1 << order; ++i) + tag_clear_highpage(page + i); + } else { + kasan_unpoison_pages(page, order, init); + } +} + +void kasan_free_pages(struct page *page, unsigned int order) +{ + /* + * This condition should match the one in free_pages_prepare() in + * page_alloc.c. + */ + bool init = want_init_on_free(); + + kasan_poison_pages(page, order, init); +} + #if IS_ENABLED(CONFIG_KASAN_KUNIT_TEST) void kasan_set_tagging_report_once(bool state) diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 3820ca54743b..ed9c45a63f9a 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -9,6 +9,7 @@ #ifdef CONFIG_KASAN_HW_TAGS #include +#include "../slab.h" DECLARE_STATIC_KEY_FALSE(kasan_flag_stacktrace); extern bool kasan_flag_async __ro_after_init; @@ -387,6 +388,17 @@ static inline void kasan_unpoison(const void *addr, size_t size, bool init) if (WARN_ON((unsigned long)addr & KASAN_GRANULE_MASK)) return; + /* + * Explicitly initialize the memory with the precise object size to + * avoid overwriting the SLAB redzone. This disables initialization in + * the arch code and may thus lead to performance penalty. The penalty + * is accepted since SLAB redzones aren't enabled in production builds. + */ + if (__slub_debug_enabled() && + init && ((unsigned long)size & KASAN_GRANULE_MASK)) { + init = false; + memzero_explicit((void *)addr, size); + } size = round_up(size, KASAN_GRANULE_SIZE); hw_set_mem_tag_range((void *)addr, size, tag, init); diff --git a/mm/kfence/core.c b/mm/kfence/core.c index a6d255148902..e4302fac68ab 100644 --- a/mm/kfence/core.c +++ b/mm/kfence/core.c @@ -733,6 +733,22 @@ void kfence_shutdown_cache(struct kmem_cache *s) void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) { + /* + * Perform size check before switching kfence_allocation_gate, so that + * we don't disable KFENCE without making an allocation. + */ + if (size > PAGE_SIZE) + return NULL; + + /* + * Skip allocations from non-default zones, including DMA. We cannot + * guarantee that pages in the KFENCE pool will have the requested + * properties (e.g. reside in DMAable memory). + */ + if ((flags & GFP_ZONEMASK) || + (s->flags & (SLAB_CACHE_DMA | SLAB_CACHE_DMA32))) + return NULL; + /* * allocation_gate only needs to become non-zero, so it doesn't make * sense to continue writing to it and pay the associated contention @@ -757,9 +773,6 @@ void *__kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags) if (!READ_ONCE(kfence_enabled)) return NULL; - if (size > PAGE_SIZE) - return NULL; - return kfence_guarded_alloc(s, size, flags); } diff --git a/mm/madvise.c b/mm/madvise.c index 9ec5037bf297..e865ae74a5bf 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -996,6 +996,7 @@ process_madvise_behavior_valid(int behavior) switch (behavior) { case MADV_COLD: case MADV_PAGEOUT: + case MADV_WILLNEED: return true; default: return false; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 8d9f5fa4c6d3..a1569684c484 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -67,6 +67,7 @@ #include #include +#include struct cgroup_subsys memory_cgrp_subsys __read_mostly; EXPORT_SYMBOL(memory_cgrp_subsys); @@ -5148,6 +5149,7 @@ static DEFINE_IDR(mem_cgroup_idr); static void mem_cgroup_id_remove(struct mem_cgroup *memcg) { if (memcg->id.id > 0) { + trace_android_vh_mem_cgroup_id_remove(memcg); idr_remove(&mem_cgroup_idr, memcg->id.id); memcg->id.id = 0; } @@ -5185,6 +5187,7 @@ struct mem_cgroup *mem_cgroup_from_id(unsigned short id) WARN_ON_ONCE(!rcu_read_lock_held()); return idr_find(&mem_cgroup_idr, id); } +EXPORT_SYMBOL_GPL(mem_cgroup_from_id); static int alloc_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node) { @@ -5244,6 +5247,7 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg) { int node; + trace_android_vh_mem_cgroup_free(memcg); for_each_node(node) free_mem_cgroup_per_node_info(memcg, node); free_percpu(memcg->vmstats_percpu); @@ -5327,6 +5331,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void) memcg->deferred_split_queue.split_queue_len = 0; #endif idr_replace(&mem_cgroup_idr, memcg, memcg->id.id); + trace_android_vh_mem_cgroup_alloc(memcg); return memcg; fail: mem_cgroup_id_remove(memcg); @@ -5416,6 +5421,7 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css) /* Online state pins memcg ID, memcg ID pins CSS */ refcount_set(&memcg->id.ref, 1); css_get(css); + trace_android_vh_mem_cgroup_css_online(css, memcg); return 0; } @@ -5424,6 +5430,7 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css) struct mem_cgroup *memcg = mem_cgroup_from_css(css); struct mem_cgroup_event *event, *tmp; + trace_android_vh_mem_cgroup_css_offline(css, memcg); /* * Unregister events and notify userspace. * Notify userspace about cgroup removing only after rmdir of cgroup @@ -6754,7 +6761,7 @@ void mem_cgroup_calculate_protection(struct mem_cgroup *root, } /** - * mem_cgroup_charge - charge a newly allocated page to a cgroup + * __mem_cgroup_charge - charge a newly allocated page to a cgroup * @page: page to charge * @mm: mm context of the victim * @gfp_mask: reclaim mode @@ -6764,15 +6771,13 @@ void mem_cgroup_calculate_protection(struct mem_cgroup *root, * * Returns 0 on success. Otherwise, an error code is returned. */ -int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask) +int __mem_cgroup_charge(struct page *page, struct mm_struct *mm, + gfp_t gfp_mask) { unsigned int nr_pages = thp_nr_pages(page); struct mem_cgroup *memcg = NULL; int ret = 0; - if (mem_cgroup_disabled()) - goto out; - if (PageSwapCache(page)) { swp_entry_t ent = { .val = page_private(page), }; unsigned short id; @@ -6942,18 +6947,15 @@ static void uncharge_list(struct list_head *page_list) } /** - * mem_cgroup_uncharge - uncharge a page + * __mem_cgroup_uncharge - uncharge a page * @page: page to uncharge * - * Uncharge a page previously charged with mem_cgroup_charge(). + * Uncharge a page previously charged with __mem_cgroup_charge(). */ -void mem_cgroup_uncharge(struct page *page) +void __mem_cgroup_uncharge(struct page *page) { struct uncharge_gather ug; - if (mem_cgroup_disabled()) - return; - /* Don't touch page->lru of any random page, pre-check: */ if (!page->mem_cgroup) return; @@ -6964,17 +6966,14 @@ void mem_cgroup_uncharge(struct page *page) } /** - * mem_cgroup_uncharge_list - uncharge a list of page + * __mem_cgroup_uncharge_list - uncharge a list of page * @page_list: list of pages to uncharge * * Uncharge a list of pages previously charged with - * mem_cgroup_charge(). + * __mem_cgroup_charge(). */ -void mem_cgroup_uncharge_list(struct list_head *page_list) +void __mem_cgroup_uncharge_list(struct list_head *page_list) { - if (mem_cgroup_disabled()) - return; - if (!list_empty(page_list)) uncharge_list(page_list); } @@ -7201,6 +7200,9 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) VM_BUG_ON_PAGE(PageLRU(page), page); VM_BUG_ON_PAGE(page_count(page), page); + if (mem_cgroup_disabled()) + return; + if (cgroup_subsys_on_dfl(memory_cgrp_subsys)) return; @@ -7250,7 +7252,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) } /** - * mem_cgroup_try_charge_swap - try charging swap space for a page + * __mem_cgroup_try_charge_swap - try charging swap space for a page * @page: page being added to swap * @entry: swap entry to charge * @@ -7258,7 +7260,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry) * * Returns 0 on success, -ENOMEM on failure. */ -int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry) +int __mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry) { unsigned int nr_pages = thp_nr_pages(page); struct page_counter *counter; @@ -7300,11 +7302,11 @@ int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry) } /** - * mem_cgroup_uncharge_swap - uncharge swap space + * __mem_cgroup_uncharge_swap - uncharge swap space * @entry: swap entry to uncharge * @nr_pages: the amount of swap space to uncharge */ -void mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages) +void __mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages) { struct mem_cgroup *memcg; unsigned short id; diff --git a/mm/memory.c b/mm/memory.c index 3e76655b279b..20cb1473431e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1302,7 +1302,8 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, page_remove_rmap(page, false); if (unlikely(page_mapcount(page) < 0)) print_bad_pte(vma, addr, ptent, page); - if (unlikely(__tlb_remove_page(tlb, page))) { + if (unlikely(__tlb_remove_page(tlb, page)) || + lru_cache_disabled()) { force_flush = 1; addr += PAGE_SIZE; break; diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index f1b193096ffa..41ac69bc0299 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1541,12 +1541,14 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages) /* set above range as isolated */ ret = start_isolate_page_range(start_pfn, end_pfn, MIGRATE_MOVABLE, - MEMORY_OFFLINE | REPORT_FAILURE); + MEMORY_OFFLINE | REPORT_FAILURE, NULL); if (ret) { reason = "failure to isolate range"; goto failed_removal; } + drain_all_pages(zone); + arg.start_pfn = start_pfn; arg.nr_pages = nr_pages; node_states_check_changes_offline(nr_pages, zone, &arg); @@ -1596,18 +1598,17 @@ int __ref offline_pages(unsigned long start_pfn, unsigned long nr_pages) } /* - * per-cpu pages are drained in start_isolate_page_range, but if - * there are still pages that are not free, make sure that we - * drain again, because when we isolated range we might - * have raced with another thread that was adding pages to pcp - * list. + * per-cpu pages are drained after start_isolate_page_range, but + * if there are still pages that are not free, make sure that we + * drain again, because when we isolated range we might have + * raced with another thread that was adding pages to pcp list. * * Forward progress should be still guaranteed because * pages on the pcp list can only belong to MOVABLE_ZONE * because has_unmovable_pages explicitly checks for * PageBuddy on freed pages on other zones. */ - ret = test_pages_isolated(start_pfn, end_pfn, MEMORY_OFFLINE); + ret = test_pages_isolated(start_pfn, end_pfn, MEMORY_OFFLINE, NULL); if (ret) drain_all_pages(zone); } while (ret); diff --git a/mm/mempool.c b/mm/mempool.c index fe19d290a301..a69bc087fc65 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -106,7 +106,8 @@ static __always_inline void kasan_poison_element(mempool_t *pool, void *element) if (pool->alloc == mempool_alloc_slab || pool->alloc == mempool_kmalloc) kasan_slab_free_mempool(element); else if (pool->alloc == mempool_alloc_pages) - kasan_free_pages(element, (unsigned long)pool->pool_data, false); + kasan_poison_pages(element, (unsigned long)pool->pool_data, + false); } static void kasan_unpoison_element(mempool_t *pool, void *element) @@ -114,7 +115,8 @@ static void kasan_unpoison_element(mempool_t *pool, void *element) if (pool->alloc == mempool_alloc_slab || pool->alloc == mempool_kmalloc) kasan_unpoison_range(element, __ksize(element)); else if (pool->alloc == mempool_alloc_pages) - kasan_alloc_pages(element, (unsigned long)pool->pool_data, false); + kasan_unpoison_pages(element, (unsigned long)pool->pool_data, + false); } static __always_inline void add_element(mempool_t *pool, void *element) diff --git a/mm/mmap.c b/mm/mmap.c index fbebd65565ce..b1ca729a11f2 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2101,7 +2101,7 @@ static unsigned long unmapped_area_topdown(struct vm_unmapped_area_info *info) if (length < info->length) return -ENOMEM; - trace_android_vh_get_unmapped_area_from_anti_fragment_pool(mm, info, &addr); + trace_android_vh_get_from_fragment_pool(mm, info, &addr); if (addr) return addr; @@ -2214,6 +2214,7 @@ unsigned long vm_unmapped_area(struct vm_unmapped_area_info *info) trace_vm_unmapped_area(addr, info); return addr; } +EXPORT_SYMBOL_GPL(vm_unmapped_area); #ifndef arch_get_mmap_end #define arch_get_mmap_end(addr) (TASK_SIZE) @@ -2324,7 +2325,7 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, addr = vm_unmapped_area(&info); } - trace_android_vh_get_unmapped_area_include_reserved_zone(mm, &info, &addr); + trace_android_vh_include_reserved_zone(mm, &info, &addr); return addr; } diff --git a/mm/mprotect.c b/mm/mprotect.c index d95115a57283..05073d7abff4 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -35,6 +35,51 @@ #include "internal.h" +/* Determine whether we can avoid taking write faults for known dirty pages. */ +static bool may_avoid_write_fault(pte_t pte, struct vm_area_struct *vma, + unsigned long cp_flags) +{ + /* + * The dirty accountable bit indicates that we can always make the page + * writable regardless of the number of references. + */ + if (!(cp_flags & MM_CP_DIRTY_ACCT)) { + /* Otherwise, we must have exclusive access to the page. */ + if (!(vma_is_anonymous(vma) && (vma->vm_flags & VM_WRITE))) + return false; + + if (page_count(pte_page(pte)) != 1) + return false; + } + + /* + * Don't do this optimization for clean pages as we need to be notified + * of the transition from clean to dirty. + */ + if (!pte_dirty(pte)) + return false; + + /* Same for softdirty. */ + if (!pte_soft_dirty(pte) && (vma->vm_flags & VM_SOFTDIRTY)) + return false; + + /* + * For userfaultfd the user program needs to monitor write faults so we + * can't do this optimization. + */ + if (pte_uffd_wp(pte)) + return false; + + /* + * It is unclear whether this optimization can be done safely for NUMA + * pages. + */ + if (cp_flags & MM_CP_PROT_NUMA) + return false; + + return true; +} + static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, unsigned long addr, unsigned long end, pgprot_t newprot, unsigned long cp_flags) @@ -43,7 +88,6 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, spinlock_t *ptl; unsigned long pages = 0; int target_node = NUMA_NO_NODE; - bool dirty_accountable = cp_flags & MM_CP_DIRTY_ACCT; bool prot_numa = cp_flags & MM_CP_PROT_NUMA; bool uffd_wp = cp_flags & MM_CP_UFFD_WP; bool uffd_wp_resolve = cp_flags & MM_CP_UFFD_WP_RESOLVE; @@ -131,12 +175,8 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd, ptent = pte_clear_uffd_wp(ptent); } - /* Avoid taking write faults for known dirty pages */ - if (dirty_accountable && pte_dirty(ptent) && - (pte_soft_dirty(ptent) || - !(vma->vm_flags & VM_SOFTDIRTY))) { + if (may_avoid_write_fault(ptent, vma, cp_flags)) ptent = pte_mkwrite(ptent); - } ptep_modify_prot_commit(vma, addr, pte, oldpte, ptent); pages++; } else if (is_swap_pte(oldpte)) { diff --git a/mm/mremap.c b/mm/mremap.c index 45e8e7617b38..12ca03d66311 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -439,7 +439,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma, if (!new_pud) break; if (move_pgt_entry(NORMAL_PUD, vma, old_addr, new_addr, - old_pud, new_pud, need_rmap_locks)) + old_pud, new_pud, true)) continue; } @@ -466,7 +466,7 @@ unsigned long move_page_tables(struct vm_area_struct *vma, * moving at the PMD level if possible. */ if (move_pgt_entry(NORMAL_PMD, vma, old_addr, new_addr, - old_pmd, new_pmd, need_rmap_locks)) + old_pmd, new_pmd, true)) continue; } diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8171fbeb71b8..644959a7afb8 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -395,7 +395,7 @@ int page_group_by_mobility_disabled __read_mostly; static DEFINE_STATIC_KEY_TRUE(deferred_pages); /* - * Calling kasan_free_pages() only after deferred memory initialization + * Calling kasan_poison_pages() only after deferred memory initialization * has completed. Poisoning pages during deferred memory init will greatly * lengthen the process and cause problem in large memory systems as the * deferred pages initialization is done with interrupt disabled. @@ -407,15 +407,12 @@ static DEFINE_STATIC_KEY_TRUE(deferred_pages); * on-demand allocation and then freed again before the deferred pages * initialization is done, but this is not likely to happen. */ -static inline void kasan_free_nondeferred_pages(struct page *page, int order, - bool init, fpi_t fpi_flags) +static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags) { - if (static_branch_unlikely(&deferred_pages)) - return; - if (!IS_ENABLED(CONFIG_KASAN_GENERIC) && - (fpi_flags & FPI_SKIP_KASAN_POISON)) - return; - kasan_free_pages(page, order, init); + return static_branch_unlikely(&deferred_pages) || + (!IS_ENABLED(CONFIG_KASAN_GENERIC) && + (fpi_flags & FPI_SKIP_KASAN_POISON)) || + PageSkipKASanPoison(page); } /* Returns true if the struct page for the pfn is uninitialised */ @@ -466,13 +463,11 @@ defer_init(int nid, unsigned long pfn, unsigned long end_pfn) return false; } #else -static inline void kasan_free_nondeferred_pages(struct page *page, int order, - bool init, fpi_t fpi_flags) +static inline bool should_skip_kasan_poison(struct page *page, fpi_t fpi_flags) { - if (!IS_ENABLED(CONFIG_KASAN_GENERIC) && - (fpi_flags & FPI_SKIP_KASAN_POISON)) - return; - kasan_free_pages(page, order, init); + return (!IS_ENABLED(CONFIG_KASAN_GENERIC) && + (fpi_flags & FPI_SKIP_KASAN_POISON)) || + PageSkipKASanPoison(page); } static inline bool early_page_uninitialised(unsigned long pfn) @@ -1257,10 +1252,16 @@ static int free_tail_pages_check(struct page *head_page, struct page *page) return ret; } -static void kernel_init_free_pages(struct page *page, int numpages) +static void kernel_init_free_pages(struct page *page, int numpages, bool zero_tags) { int i; + if (zero_tags) { + for (i = 0; i < numpages; i++) + tag_clear_highpage(page + i); + return; + } + /* s390's use of memset() could override KASAN redzones. */ kasan_disable_current(); for (i = 0; i < numpages; i++) { @@ -1276,7 +1277,7 @@ static __always_inline bool free_pages_prepare(struct page *page, unsigned int order, bool check_free, fpi_t fpi_flags) { int bad = 0; - bool init; + bool skip_kasan_poison = should_skip_kasan_poison(page, fpi_flags); VM_BUG_ON_PAGE(PageTail(page), page); @@ -1347,10 +1348,17 @@ static __always_inline bool free_pages_prepare(struct page *page, * With hardware tag-based KASAN, memory tags must be set before the * page becomes unavailable via debug_pagealloc or arch_free_page. */ - init = want_init_on_free(); - if (init && !kasan_has_integrated_init()) - kernel_init_free_pages(page, 1 << order); - kasan_free_nondeferred_pages(page, order, init, fpi_flags); + if (kasan_has_integrated_init()) { + if (!skip_kasan_poison) + kasan_free_pages(page, order); + } else { + bool init = want_init_on_free(); + + if (init) + kernel_init_free_pages(page, 1 << order, false); + if (!skip_kasan_poison) + kasan_poison_pages(page, order, init); + } /* * arch_free_page() can make the page's contents inaccessible. s390 @@ -2351,25 +2359,35 @@ static bool check_new_pages(struct page *page, unsigned int order) inline void post_alloc_hook(struct page *page, unsigned int order, gfp_t gfp_flags) { - bool init; - set_page_private(page, 0); set_page_refcounted(page); arch_alloc_page(page, order); debug_pagealloc_map_pages(page, 1 << order); + /* + * Page unpoisoning must happen before memory initialization. + * Otherwise, the poison pattern will be overwritten for __GFP_ZERO + * allocations and the page unpoisoning code will complain. + */ + kernel_unpoison_pages(page, 1 << order); + /* * As memory initialization might be integrated into KASAN, * kasan_alloc_pages and kernel_init_free_pages must be * kept together to avoid discrepancies in behavior. */ - init = !want_init_on_free() && want_init_on_alloc(gfp_flags); - kasan_alloc_pages(page, order, init); - if (init && !kasan_has_integrated_init()) - kernel_init_free_pages(page, 1 << order); + if (kasan_has_integrated_init()) { + kasan_alloc_pages(page, order, gfp_flags); + } else { + bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags); + + kasan_unpoison_pages(page, order, init); + if (init) + kernel_init_free_pages(page, 1 << order, + gfp_flags & __GFP_ZEROTAGS); + } - kernel_unpoison_pages(page, 1 << order); set_page_owner(page, order, gfp_flags); } @@ -8546,7 +8564,7 @@ static unsigned long pfn_max_align_down(unsigned long pfn) pageblock_nr_pages) - 1); } -static unsigned long pfn_max_align_up(unsigned long pfn) +unsigned long pfn_max_align_up(unsigned long pfn) { return ALIGN(pfn, max_t(unsigned long, MAX_ORDER_NR_PAGES, pageblock_nr_pages)); @@ -8585,7 +8603,8 @@ static inline void alloc_contig_dump_pages(struct list_head *page_list) /* [start, end) must belong to a single zone. */ static int __alloc_contig_migrate_range(struct compact_control *cc, - unsigned long start, unsigned long end) + unsigned long start, unsigned long end, + struct acr_info *info) { /* This function is based on compact_zone() from compaction.c. */ unsigned int nr_reclaimed; @@ -8593,6 +8612,7 @@ static int __alloc_contig_migrate_range(struct compact_control *cc, unsigned int tries = 0; unsigned int max_tries = 5; int ret = 0; + struct page *page; struct migration_target_control mtc = { .nid = zone_to_nid(cc->zone), .gfp_mask = GFP_USER | __GFP_MOVABLE | __GFP_RETRY_MAYFAIL, @@ -8624,10 +8644,16 @@ static int __alloc_contig_migrate_range(struct compact_control *cc, nr_reclaimed = reclaim_clean_pages_from_list(cc->zone, &cc->migratepages); + info->nr_reclaimed += nr_reclaimed; cc->nr_migratepages -= nr_reclaimed; + list_for_each_entry(page, &cc->migratepages, lru) + info->nr_mapped += page_mapcount(page); + ret = migrate_pages(&cc->migratepages, alloc_migration_target, NULL, (unsigned long)&mtc, cc->mode, MR_CONTIG_RANGE); + if (!ret) + info->nr_migrated += cc->nr_migratepages; } lru_cache_enable(); @@ -8636,7 +8662,14 @@ static int __alloc_contig_migrate_range(struct compact_control *cc, alloc_contig_dump_pages(&cc->migratepages); page_pinner_mark_migration_failed_pages(&cc->migratepages); } + + if (!list_empty(&cc->migratepages)) { + page = list_first_entry(&cc->migratepages, struct page , lru); + info->failed_pfn = page_to_pfn(page); + } + putback_movable_pages(&cc->migratepages); + info->err |= ACR_ERR_MIGRATE; return ret; } return 0; @@ -8664,7 +8697,8 @@ static int __alloc_contig_migrate_range(struct compact_control *cc, * need to be freed with free_contig_range(). */ int alloc_contig_range(unsigned long start, unsigned long end, - unsigned migratetype, gfp_t gfp_mask) + unsigned migratetype, gfp_t gfp_mask, + struct acr_info *info) { unsigned long outer_start, outer_end; unsigned int order; @@ -8707,9 +8741,14 @@ int alloc_contig_range(unsigned long start, unsigned long end, */ ret = start_isolate_page_range(pfn_max_align_down(start), - pfn_max_align_up(end), migratetype, 0); - if (ret) + pfn_max_align_up(end), migratetype, 0, + &info->failed_pfn); + if (ret) { + info->err |= ACR_ERR_ISOLATE; return ret; + } + + drain_all_pages(cc.zone); /* * In case of -EBUSY, we'd like to know which page causes problem. @@ -8721,8 +8760,8 @@ int alloc_contig_range(unsigned long start, unsigned long end, * allocated. So, if we fall through be sure to clear ret so that * -EBUSY is not accidentally used or returned to caller. */ - ret = __alloc_contig_migrate_range(&cc, start, end); - if (ret && ret != -EBUSY) + ret = __alloc_contig_migrate_range(&cc, start, end, info); + if (ret && (ret != -EBUSY || (gfp_mask & __GFP_NORETRY))) goto done; ret =0; @@ -8767,10 +8806,11 @@ int alloc_contig_range(unsigned long start, unsigned long end, } /* Make sure the range is really isolated. */ - if (test_pages_isolated(outer_start, end, 0)) { + if (test_pages_isolated(outer_start, end, 0, &info->failed_pfn)) { pr_info_ratelimited("%s: [%lx, %lx) PFNs busy\n", __func__, outer_start, end); ret = -EBUSY; + info->err |= ACR_ERR_TEST; goto done; } @@ -8797,10 +8837,11 @@ EXPORT_SYMBOL(alloc_contig_range); static int __alloc_contig_pages(unsigned long start_pfn, unsigned long nr_pages, gfp_t gfp_mask) { + struct acr_info dummy; unsigned long end_pfn = start_pfn + nr_pages; return alloc_contig_range(start_pfn, end_pfn, MIGRATE_MOVABLE, - gfp_mask); + gfp_mask, &dummy); } static bool pfn_range_valid_contig(struct zone *z, unsigned long start_pfn, diff --git a/mm/page_isolation.c b/mm/page_isolation.c index abbf42214485..b391091bfd5c 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c @@ -49,7 +49,6 @@ static int set_migratetype_isolate(struct page *page, int migratetype, int isol_ __mod_zone_freepage_state(zone, -nr_pages, mt); spin_unlock_irqrestore(&zone->lock, flags); - drain_all_pages(zone); return 0; } @@ -172,16 +171,18 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages) * * Please note that there is no strong synchronization with the page allocator * either. Pages might be freed while their page blocks are marked ISOLATED. - * In some cases pages might still end up on pcp lists and that would allow + * A call to drain_all_pages() after isolation can flush most of them. However + * in some cases pages might still end up on pcp lists and that would allow * for their allocation even when they are in fact isolated already. Depending - * on how strong of a guarantee the caller needs drain_all_pages might be needed - * (e.g. __offline_pages will need to call it after check for isolated range for - * a next retry). + * on how strong of a guarantee the caller needs, further drain_all_pages() + * might be needed (e.g. __offline_pages will need to call it after check for + * isolated range for a next retry). * * Return: 0 on success and -EBUSY if any part of range cannot be isolated. */ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, - unsigned migratetype, int flags) + unsigned migratetype, int flags, + unsigned long *failed_pfn) { unsigned long pfn; unsigned long undo_pfn; @@ -197,6 +198,8 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, if (page) { if (set_migratetype_isolate(page, migratetype, flags)) { undo_pfn = pfn; + if (failed_pfn) + *failed_pfn = page_to_pfn(page); goto undo; } } @@ -282,7 +285,7 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn, /* Caller should ensure that requested range is in a single zone */ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, - int isol_flags) + int isol_flags, unsigned long *failed_pfn) { unsigned long pfn, flags; struct page *page; @@ -308,6 +311,12 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn, spin_unlock_irqrestore(&zone->lock, flags); trace_test_pages_isolated(start_pfn, end_pfn, pfn); + if (pfn < end_pfn) { + page_pinner_failure_detect(pfn_to_page(pfn)); + if (failed_pfn) + *failed_pfn = pfn; + return -EBUSY; + } - return pfn < end_pfn ? -EBUSY : 0; + return 0; } diff --git a/mm/page_pinner.c b/mm/page_pinner.c index 5bd7364b4a91..3f5c48af3135 100644 --- a/mm/page_pinner.c +++ b/mm/page_pinner.c @@ -15,7 +15,7 @@ #include "internal.h" #define PAGE_PINNER_STACK_DEPTH 16 -#define LONTERM_PIN_BUCKETS 4096 +#define LONGTERM_PIN_BUCKETS 4096 struct page_pinner { depot_stack_handle_t handle; @@ -25,16 +25,23 @@ struct page_pinner { struct captured_pinner { depot_stack_handle_t handle; - s64 ts_usec; - int page_mt; - unsigned long page_flags; + union { + s64 ts_usec; + s64 elapsed; + }; + + /* struct page fields */ unsigned long pfn; + int count; + int mapcount; + struct address_space *mapping; + unsigned long flags; }; struct longterm_pinner { spinlock_t lock; unsigned int index; - struct captured_pinner pinner[LONTERM_PIN_BUCKETS]; + struct captured_pinner pinner[LONGTERM_PIN_BUCKETS]; }; static struct longterm_pinner lt_pinner = { @@ -52,7 +59,7 @@ static bool page_pinner_enabled; DEFINE_STATIC_KEY_FALSE(page_pinner_inited); DEFINE_STATIC_KEY_TRUE(failure_tracking); -EXPORT_SYMBOL(failure_tracking); +EXPORT_SYMBOL_GPL(failure_tracking); static depot_stack_handle_t failure_handle; @@ -111,12 +118,23 @@ static noinline depot_stack_handle_t save_stack(gfp_t flags) return handle; } -static void check_lonterm_pin(struct page_pinner *page_pinner, +static void capture_page_state(struct page *page, + struct captured_pinner *record) +{ + record->flags = page->flags; + record->mapping = page_mapping(page); + record->pfn = page_to_pfn(page); + record->count = page_count(page); + record->mapcount = page_mapcount(page); +} + +static void check_longterm_pin(struct page_pinner *page_pinner, struct page *page) { s64 now, delta = 0; unsigned long flags; unsigned int idx; + struct captured_pinner record; now = ktime_to_us(ktime_get_boottime()); @@ -127,17 +145,15 @@ static void check_lonterm_pin(struct page_pinner *page_pinner, if (delta <= threshold_usec) return; + record.handle = page_pinner->handle; + record.elapsed = delta; + capture_page_state(page, &record); + spin_lock_irqsave(<_pinner.lock, flags); idx = lt_pinner.index++; - lt_pinner.index %= LONTERM_PIN_BUCKETS; - - lt_pinner.pinner[idx].handle = page_pinner->handle; - lt_pinner.pinner[idx].ts_usec = delta; - lt_pinner.pinner[idx].page_flags = page->flags; - lt_pinner.pinner[idx].page_mt = get_pageblock_migratetype(page); - lt_pinner.pinner[idx].pfn = page_to_pfn(page); + lt_pinner.index %= LONGTERM_PIN_BUCKETS; + lt_pinner.pinner[idx] = record; spin_unlock_irqrestore(<_pinner.lock, flags); - } void __reset_page_pinner(struct page *page, unsigned int order, bool free) @@ -151,18 +167,19 @@ void __reset_page_pinner(struct page *page, unsigned int order, bool free) return; for (i = 0; i < (1 << order); i++) { - if (!test_bit(PAGE_EXT_GET, &page_ext->flags)) + if (!test_bit(PAGE_EXT_GET, &page_ext->flags) && + !test_bit(PAGE_EXT_PINNER_MIGRATION_FAILED, + &page_ext->flags)) continue; page_pinner = get_page_pinner(page_ext); if (free) { - WARN_ON_ONCE(atomic_read(&page_pinner->count)); + /* record page free call path */ + __page_pinner_migration_failed(page); atomic_set(&page_pinner->count, 0); __clear_bit(PAGE_EXT_PINNER_MIGRATION_FAILED, &page_ext->flags); } else { - WARN_ON_ONCE(atomic_dec_if_positive( - &page_pinner->count) < 0); - check_lonterm_pin(page_pinner, page); + check_longterm_pin(page_pinner, page); } clear_bit(PAGE_EXT_GET, &page_ext->flags); page_ext = page_ext_next(page_ext); @@ -200,9 +217,7 @@ noinline void __set_page_pinner(struct page *page, unsigned int order) } static ssize_t -print_page_pinner(char __user *buf, size_t count, unsigned long pfn, - int pageblock_mt, unsigned long page_flags, s64 ts_usec, - depot_stack_handle_t handle, int shared_count) +print_page_pinner(bool longterm, char __user *buf, size_t count, struct captured_pinner *record) { int ret; unsigned long *entries; @@ -214,25 +229,34 @@ print_page_pinner(char __user *buf, size_t count, unsigned long pfn, if (!kbuf) return -ENOMEM; - ret = snprintf(kbuf, count, - "Page pinned ts %lld us count %d\n", - ts_usec, shared_count); + if (longterm) { + ret = snprintf(kbuf, count, "Page pinned for %lld us\n", + record->elapsed); + } else { + s64 ts_usec = record->ts_usec; + unsigned long rem_usec = do_div(ts_usec, 1000000); + + ret = snprintf(kbuf, count, + "Page pinned ts [%5lu.%06lu]\n", + (unsigned long)ts_usec, rem_usec); + } if (ret >= count) goto err; /* Print information relevant to grouping pages by mobility */ ret += snprintf(kbuf + ret, count - ret, - "PFN %lu Block %lu type %s Flags %#lx(%pGp)\n", - pfn, - pfn >> pageblock_order, - migratetype_names[pageblock_mt], - page_flags, &page_flags); + "PFN 0x%lx Block %lu count %d mapcount %d mapping %pS Flags %#lx(%pGp)\n", + record->pfn, + record->pfn >> pageblock_order, + record->count, record->mapcount, + record->mapping, + record->flags, &record->flags); if (ret >= count) goto err; - nr_entries = stack_depot_fetch(handle, &entries); + nr_entries = stack_depot_fetch(record->handle, &entries); ret += stack_trace_snprint(kbuf + ret, count - ret, entries, nr_entries, 0); if (ret >= count) @@ -263,6 +287,8 @@ void __dump_page_pinner(struct page *page) int pageblock_mt; unsigned long pfn; int count; + unsigned long rem_usec; + s64 ts_usec; if (unlikely(!page_ext)) { pr_alert("There is not page extension available.\n"); @@ -278,9 +304,10 @@ void __dump_page_pinner(struct page *page) } pfn = page_to_pfn(page); - pr_alert("page last pinned ts %lld count %d\n", - page_pinner->ts_usec, - count); + ts_usec = page_pinner->ts_usec; + rem_usec = do_div(ts_usec, 1000000); + pr_alert("page last pinned %5lu.%06lu] count %d\n", + (unsigned long)ts_usec, rem_usec, count); pageblock_mt = get_pageblock_migratetype(page); pr_alert("PFN %lu Block %lu type %s Flags %#lx(%pGp)\n", @@ -302,7 +329,7 @@ void __page_pinner_migration_failed(struct page *page) { struct page_ext *page_ext = lookup_page_ext(page); struct page_pinner *page_pinner; - depot_stack_handle_t handle; + struct captured_pinner record; unsigned long flags; unsigned int idx; @@ -313,20 +340,17 @@ void __page_pinner_migration_failed(struct page *page) if (!test_bit(PAGE_EXT_PINNER_MIGRATION_FAILED, &page_ext->flags)) return; - handle = save_stack(GFP_NOWAIT|__GFP_NOWARN); + record.handle = save_stack(GFP_NOWAIT|__GFP_NOWARN); + record.ts_usec = ktime_to_us(ktime_get_boottime()); + capture_page_state(page, &record); spin_lock_irqsave(&acf_pinner.lock, flags); idx = acf_pinner.index++; - acf_pinner.index %= LONTERM_PIN_BUCKETS; - - acf_pinner.pinner[idx].handle = handle; - acf_pinner.pinner[idx].ts_usec = ktime_to_us(ktime_get_boottime()); - acf_pinner.pinner[idx].page_flags = page->flags; - acf_pinner.pinner[idx].page_mt = get_pageblock_migratetype(page); - acf_pinner.pinner[idx].pfn = page_to_pfn(page); + acf_pinner.index %= LONGTERM_PIN_BUCKETS; + acf_pinner.pinner[idx] = record; spin_unlock_irqrestore(&acf_pinner.lock, flags); } -EXPORT_SYMBOL(__page_pinner_migration_failed); +EXPORT_SYMBOL_GPL(__page_pinner_migration_failed); void __page_pinner_mark_migration_failed_pages(struct list_head *page_list) { @@ -341,6 +365,7 @@ void __page_pinner_mark_migration_failed_pages(struct list_head *page_list) if (unlikely(!page_ext)) continue; __set_bit(PAGE_EXT_PINNER_MIGRATION_FAILED, &page_ext->flags); + __page_pinner_migration_failed(page); } } @@ -355,7 +380,7 @@ read_longterm_page_pinner(struct file *file, char __user *buf, size_t count, if (!static_branch_unlikely(&page_pinner_inited)) return -EINVAL; - if (*ppos >= LONTERM_PIN_BUCKETS) + if (*ppos >= LONGTERM_PIN_BUCKETS) return 0; i = *ppos; @@ -365,17 +390,15 @@ read_longterm_page_pinner(struct file *file, char __user *buf, size_t count, * reading the records in the reverse order with newest one * being read first followed by older ones */ - idx = (lt_pinner.index - 1 - i + LONTERM_PIN_BUCKETS) % - LONTERM_PIN_BUCKETS; + idx = (lt_pinner.index - 1 - i + LONGTERM_PIN_BUCKETS) % + LONGTERM_PIN_BUCKETS; spin_lock_irqsave(<_pinner.lock, flags); record = lt_pinner.pinner[idx]; spin_unlock_irqrestore(<_pinner.lock, flags); if (!record.handle) return 0; - return print_page_pinner(buf, count, record.pfn, record.page_mt, - record.page_flags, record.ts_usec, - record.handle, 0); + return print_page_pinner(true, buf, count, &record); } static const struct file_operations proc_longterm_pinner_operations = { @@ -392,7 +415,7 @@ static ssize_t read_alloc_contig_failed(struct file *file, char __user *buf, if (!static_branch_unlikely(&failure_tracking)) return -EINVAL; - if (*ppos >= LONTERM_PIN_BUCKETS) + if (*ppos >= LONGTERM_PIN_BUCKETS) return 0; i = *ppos; @@ -402,8 +425,8 @@ static ssize_t read_alloc_contig_failed(struct file *file, char __user *buf, * reading the records in the reverse order with newest one * being read first followed by older ones */ - idx = (acf_pinner.index - 1 - i + LONTERM_PIN_BUCKETS) % - LONTERM_PIN_BUCKETS; + idx = (acf_pinner.index - 1 - i + LONGTERM_PIN_BUCKETS) % + LONGTERM_PIN_BUCKETS; spin_lock_irqsave(&acf_pinner.lock, flags); record = acf_pinner.pinner[idx]; @@ -411,9 +434,7 @@ static ssize_t read_alloc_contig_failed(struct file *file, char __user *buf, if (!record.handle) return 0; - return print_page_pinner(buf, count, record.pfn, record.page_mt, - record.page_flags, record.ts_usec, - record.handle, 0); + return print_page_pinner(false, buf, count, &record); } static const struct file_operations proc_alloc_contig_failed_operations = { @@ -428,7 +449,7 @@ static int pp_threshold_set(void *data, unsigned long long val) spin_lock_irqsave(<_pinner.lock, flags); memset(lt_pinner.pinner, 0, - sizeof(struct captured_pinner) * LONTERM_PIN_BUCKETS); + sizeof(struct captured_pinner) * LONGTERM_PIN_BUCKETS); lt_pinner.index = 0; spin_unlock_irqrestore(<_pinner.lock, flags); return 0; @@ -475,17 +496,17 @@ static int __init page_pinner_init(void) pp_debugfs_root = debugfs_create_dir("page_pinner", NULL); - debugfs_create_file("longterm_pinner", 0400, pp_debugfs_root, NULL, + debugfs_create_file("longterm_pinner", 0444, pp_debugfs_root, NULL, &proc_longterm_pinner_operations); - debugfs_create_file("threshold", 0444, pp_debugfs_root, NULL, + debugfs_create_file("threshold", 0644, pp_debugfs_root, NULL, &pp_threshold_fops); - debugfs_create_file("alloc_contig_failed", 0400, + debugfs_create_file("alloc_contig_failed", 0444, pp_debugfs_root, NULL, &proc_alloc_contig_failed_operations); - debugfs_create_file("failure_tracking", 0444, + debugfs_create_file("failure_tracking", 0644, pp_debugfs_root, NULL, &failure_tracking_fops); return 0; diff --git a/mm/page_poison.c b/mm/page_poison.c index 65cdf844c8ad..655dc5895604 100644 --- a/mm/page_poison.c +++ b/mm/page_poison.c @@ -77,12 +77,14 @@ static void unpoison_page(struct page *page) void *addr; addr = kmap_atomic(page); + kasan_disable_current(); /* * Page poisoning when enabled poisons each and every page * that is freed to buddy. Thus no extra check is done to * see if a page was poisoned. */ - check_poison_mem(addr, PAGE_SIZE); + check_poison_mem(kasan_reset_tag(addr), PAGE_SIZE); + kasan_enable_current(); kunmap_atomic(addr); } diff --git a/mm/shmem.c b/mm/shmem.c index a4b5012b1267..604c6d89d243 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -38,9 +38,15 @@ #include #include #include +#include #include /* for arch/microblaze update_mmu_cache() */ +#include "internal.h" + +#undef CREATE_TRACE_POINTS +#include + static struct vfsmount *shm_mnt; #ifdef CONFIG_SHMEM @@ -1559,7 +1565,11 @@ static struct page *shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info, pgoff_t index) { struct vm_area_struct pvma; - struct page *page; + struct page *page = NULL; + + trace_android_vh_shmem_alloc_page(&page); + if (page) + return page; shmem_pseudo_vma_init(&pvma, info, index); page = alloc_page_vma(gfp, &pvma, 0); @@ -4285,8 +4295,46 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, } EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp); -void shmem_mark_page_lazyfree(struct page *page) +void shmem_mark_page_lazyfree(struct page *page, bool tail) { - mark_page_lazyfree_movetail(page); + mark_page_lazyfree_movetail(page, tail); } EXPORT_SYMBOL_GPL(shmem_mark_page_lazyfree); + +int reclaim_shmem_address_space(struct address_space *mapping) +{ + pgoff_t start = 0; + struct page *page; + LIST_HEAD(page_list); + int reclaimed; + XA_STATE(xas, &mapping->i_pages, start); + + if (!shmem_mapping(mapping)) + return -EINVAL; + + lru_add_drain(); + + rcu_read_lock(); + xas_for_each(&xas, page, ULONG_MAX) { + if (xas_retry(&xas, page)) + continue; + if (xa_is_value(page)) + continue; + if (isolate_lru_page(page)) + continue; + + list_add(&page->lru, &page_list); + inc_node_page_state(page, NR_ISOLATED_ANON + + page_is_file_lru(page)); + + if (need_resched()) { + xas_pause(&xas); + cond_resched_rcu(); + } + } + rcu_read_unlock(); + reclaimed = reclaim_pages_from_list(&page_list); + + return reclaimed; +} +EXPORT_SYMBOL_GPL(reclaim_shmem_address_space); diff --git a/mm/slab.h b/mm/slab.h index 29300d7f042e..5274d6af7e58 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -242,10 +242,18 @@ extern unsigned long get_each_object_track(struct kmem_cache *s, int (*fn)(const struct kmem_cache *, const void *, const struct track *, void *), void *private); extern slab_flags_t slub_debug; +static inline bool __slub_debug_enabled(void) +{ + return static_branch_unlikely(&slub_debug_enabled); +} #else static inline void print_tracking(struct kmem_cache *s, void *object) { } +static inline bool __slub_debug_enabled(void) +{ + return false; +} #ifdef CONFIG_SLUB static inline unsigned long get_each_object_track(struct kmem_cache *s, struct page *page, enum track_item alloc, @@ -264,11 +272,10 @@ static inline unsigned long get_each_object_track(struct kmem_cache *s, */ static inline bool kmem_cache_debug_flags(struct kmem_cache *s, slab_flags_t flags) { -#ifdef CONFIG_SLUB_DEBUG - VM_WARN_ON_ONCE(!(flags & SLAB_DEBUG_FLAGS)); - if (static_branch_unlikely(&slub_debug_enabled)) + if (IS_ENABLED(CONFIG_SLUB_DEBUG)) + VM_WARN_ON_ONCE(!(flags & SLAB_DEBUG_FLAGS)); + if (__slub_debug_enabled()) return s->flags & flags; -#endif return false; } diff --git a/mm/slub.c b/mm/slub.c index 478da8d2f27a..0d32e869a64a 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -618,7 +618,8 @@ static void set_track(struct kmem_cache *s, void *object, if (nr_entries < TRACK_ADDRS_COUNT) p->addrs[nr_entries] = 0; - trace_android_vh_save_track_hash((unsigned long)p); + trace_android_vh_save_track_hash(alloc == TRACK_ALLOC, + (unsigned long)p); #endif p->addr = addr; p->cpu = smp_processor_id(); @@ -685,8 +686,6 @@ static void slab_bug(struct kmem_cache *s, char *fmt, ...) pr_err("=============================================================================\n"); pr_err("BUG %s (%s): %pV\n", s->name, print_tainted(), &vaf); pr_err("-----------------------------------------------------------------------------\n\n"); - - add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); va_end(args); } @@ -760,6 +759,7 @@ void object_err(struct kmem_cache *s, struct page *page, { slab_bug(s, "%s", reason); print_trailer(s, page, object); + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); } static __printf(3, 4) void slab_err(struct kmem_cache *s, struct page *page, @@ -774,6 +774,7 @@ static __printf(3, 4) void slab_err(struct kmem_cache *s, struct page *page, slab_bug(s, "%s", buf); print_page_info(page); dump_stack(); + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); } static void init_object(struct kmem_cache *s, void *object, u8 val) @@ -822,6 +823,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page, fault, end - 1, fault - addr, fault[0], value); print_trailer(s, page, object); + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); restore_bytes(s, what, value, fault, end); return 0; @@ -1376,12 +1378,13 @@ parse_slub_debug_flags(char *str, slab_flags_t *flags, char **slabs, bool init) static int __init setup_slub_debug(char *str) { slab_flags_t flags; + slab_flags_t global_flags; char *saved_str; char *slab_list; bool global_slub_debug_changed = false; bool slab_list_specified = false; - slub_debug = DEBUG_DEFAULT_FLAGS; + global_flags = DEBUG_DEFAULT_FLAGS; if (*str++ != '=' || !*str) /* * No options specified. Switch on full debugging. @@ -1393,7 +1396,7 @@ static int __init setup_slub_debug(char *str) str = parse_slub_debug_flags(str, &flags, &slab_list, true); if (!slab_list) { - slub_debug = flags; + global_flags = flags; global_slub_debug_changed = true; } else { slab_list_specified = true; @@ -1402,16 +1405,18 @@ static int __init setup_slub_debug(char *str) /* * For backwards compatibility, a single list of flags with list of - * slabs means debugging is only enabled for those slabs, so the global - * slub_debug should be 0. We can extended that to multiple lists as + * slabs means debugging is only changed for those slabs, so the global + * slub_debug should be unchanged (0 or DEBUG_DEFAULT_FLAGS, depending + * on CONFIG_SLUB_DEBUG_ON). We can extended that to multiple lists as * long as there is no option specifying flags without a slab list. */ if (slab_list_specified) { if (!global_slub_debug_changed) - slub_debug = 0; + global_flags = slub_debug; slub_debug_string = saved_str; } out: + slub_debug = global_flags; if (slub_debug != 0 || slub_debug_string) static_branch_enable(&slub_debug_enabled); if ((static_branch_unlikely(&init_on_alloc) || @@ -5748,31 +5753,23 @@ static int slab_debugfs_show(struct seq_file *seq, void *v) static void slab_debugfs_stop(struct seq_file *seq, void *v) { - kfree(v); } static void *slab_debugfs_next(struct seq_file *seq, void *v, loff_t *ppos) { - loff_t *spos = v; struct loc_track *t = seq->private; - if (*ppos < t->count) { - *ppos = ++*spos; - return spos; - } - *ppos = ++*spos; + v = ppos; + ++*ppos; + if (*ppos <= t->count) + return v; + return NULL; } static void *slab_debugfs_start(struct seq_file *seq, loff_t *ppos) { - loff_t *spos = kmalloc(sizeof(loff_t), GFP_KERNEL); - - if (!spos) - return NULL; - - *spos = *ppos; - return spos; + return ppos; } static const struct seq_operations slab_debugfs_sops = { diff --git a/mm/swap.c b/mm/swap.c index 171213a64202..8d5c61de5a6e 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -634,6 +634,8 @@ static void lru_lazyfree_fn(struct page *page, struct lruvec *lruvec, static void lru_lazyfree_movetail_fn(struct page *page, struct lruvec *lruvec, void *arg) { + bool *add_to_tail = (bool *)arg; + if (PageLRU(page) && !PageUnevictable(page) && PageSwapBacked(page) && !PageSwapCache(page)) { bool active = PageActive(page); @@ -642,7 +644,10 @@ static void lru_lazyfree_movetail_fn(struct page *page, struct lruvec *lruvec, LRU_INACTIVE_ANON + active); ClearPageActive(page); ClearPageReferenced(page); - add_page_to_lru_list_tail(page, lruvec, LRU_INACTIVE_FILE); + if (add_to_tail && *add_to_tail) + add_page_to_lru_list_tail(page, lruvec, LRU_INACTIVE_FILE); + else + add_page_to_lru_list(page, lruvec, LRU_INACTIVE_FILE); } } @@ -769,7 +774,7 @@ void mark_page_lazyfree(struct page *page) * mark_page_lazyfree_movetail() moves @page to the tail of inactive file list. * This is done to accelerate the reclaim of @page. */ -void mark_page_lazyfree_movetail(struct page *page) +void mark_page_lazyfree_movetail(struct page *page, bool tail) { if (PageLRU(page) && !PageUnevictable(page) && PageSwapBacked(page) && !PageSwapCache(page)) { @@ -780,7 +785,7 @@ void mark_page_lazyfree_movetail(struct page *page) get_page(page); if (pagevec_add_and_need_flush(pvec, page)) pagevec_lru_move_fn(pvec, - lru_lazyfree_movetail_fn, NULL); + lru_lazyfree_movetail_fn, &tail); local_unlock(&lru_pvecs.lock); } } @@ -924,7 +929,18 @@ void lru_add_drain_all(void) } #endif /* CONFIG_SMP */ -atomic_t lru_disable_count = ATOMIC_INIT(0); +static atomic_t lru_disable_count = ATOMIC_INIT(0); + +bool lru_cache_disabled(void) +{ + return atomic_read(&lru_disable_count) != 0; +} + +void lru_cache_enable(void) +{ + atomic_dec(&lru_disable_count); +} +EXPORT_SYMBOL_GPL(lru_cache_enable); /* * lru_cache_disable() needs to be called before we start compiling @@ -936,7 +952,12 @@ atomic_t lru_disable_count = ATOMIC_INIT(0); */ void lru_cache_disable(void) { - atomic_inc(&lru_disable_count); + /* + * If someone is already disabled lru_cache, just return with + * increasing the lru_disable_count. + */ + if (atomic_inc_not_zero(&lru_disable_count)) + return; #ifdef CONFIG_SMP /* * lru_add_drain_all in the force mode will schedule draining on @@ -950,7 +971,9 @@ void lru_cache_disable(void) #else lru_add_drain(); #endif + atomic_inc(&lru_disable_count); } +EXPORT_SYMBOL_GPL(lru_cache_disable); /** * release_pages - batched put_page() diff --git a/mm/swapfile.c b/mm/swapfile.c index 1d1e1c25aa8e..5b63553efc2c 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -3813,7 +3813,7 @@ static void free_swap_count_continuations(struct swap_info_struct *si) } #if defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP) -void cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask) +void __cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask) { struct swap_info_struct *si, *next; int nid = page_to_nid(page); diff --git a/mm/util.c b/mm/util.c index 4ddb6e186dd5..f8fc6a1ee176 100644 --- a/mm/util.c +++ b/mm/util.c @@ -27,6 +27,9 @@ #include #include "internal.h" +#ifndef __GENKSYMS__ +#include +#endif /** * kfree_const - conditionally free memory @@ -354,6 +357,7 @@ unsigned long arch_mmap_rnd(void) return rnd << PAGE_SHIFT; } +EXPORT_SYMBOL_GPL(arch_mmap_rnd); static int mmap_is_legacy(struct rlimit *rlim_stack) { @@ -511,6 +515,7 @@ unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr, if (populate) mm_populate(ret, populate); } + trace_android_vh_check_mmap_file(file, prot, flag, ret); return ret; } diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 6699fb404d78..0d1e0b97d1c9 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -327,6 +327,7 @@ int map_kernel_range(unsigned long start, unsigned long size, pgprot_t prot, flush_cache_vmap(start, start + size); return ret; } +EXPORT_SYMBOL_GPL(map_kernel_range); int is_vmalloc_or_module_addr(const void *x) { @@ -2100,6 +2101,7 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags, return __get_vm_area_node(size, 1, flags, start, end, NUMA_NO_NODE, GFP_KERNEL, caller); } +EXPORT_SYMBOL_GPL(__get_vm_area_caller); /** * get_vm_area - reserve a contiguous kernel virtual area diff --git a/mm/vmpressure.c b/mm/vmpressure.c index d69019fc3789..632b88e9d49b 100644 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c @@ -21,6 +21,8 @@ #include #include +#include + /* * The window size (vmpressure_win) is the number of scanned pages before * we try to analyze scanned/reclaimed ratio. So the window is used as a @@ -240,7 +242,17 @@ static void vmpressure_work_fn(struct work_struct *work) void vmpressure(gfp_t gfp, struct mem_cgroup *memcg, bool tree, unsigned long scanned, unsigned long reclaimed) { - struct vmpressure *vmpr = memcg_to_vmpressure(memcg); + struct vmpressure *vmpr; + bool bypass = false; + + if (mem_cgroup_disabled()) + return; + + vmpr = memcg_to_vmpressure(memcg); + + trace_android_vh_vmpressure(memcg, &bypass); + if (unlikely(bypass)) + return; /* * Here we only want to account pressure that userland is able to diff --git a/mm/vmscan.c b/mm/vmscan.c index d23a602e7d15..b8ea9031f8bc 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -66,6 +66,9 @@ #undef CREATE_TRACE_POINTS #include +EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_direct_reclaim_begin); +EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_direct_reclaim_end); + struct scan_control { /* How many pages shrink_list() should reclaim */ unsigned long nr_to_reclaim; @@ -1559,6 +1562,36 @@ unsigned int reclaim_clean_pages_from_list(struct zone *zone, return nr_reclaimed; } +int reclaim_pages_from_list(struct list_head *page_list) +{ + struct scan_control sc = { + .gfp_mask = GFP_KERNEL, + .priority = DEF_PRIORITY, + .may_writepage = 1, + .may_unmap = 1, + .may_swap = 1, + }; + unsigned long nr_reclaimed; + struct reclaim_stat dummy_stat; + struct page *page; + + list_for_each_entry(page, page_list, lru) + ClearPageActive(page); + + nr_reclaimed = shrink_page_list(page_list, NULL, &sc, + &dummy_stat, false); + while (!list_empty(page_list)) { + + page = lru_to_page(page_list); + list_del(&page->lru); + dec_node_page_state(page, NR_ISOLATED_ANON + + page_is_file_lru(page)); + putback_lru_page(page); + } + + return nr_reclaimed; +} + /* * Attempt to remove the specified page from its LRU. Only take this page * if it is of the appropriate PageActive status. Pages which are being @@ -3386,6 +3419,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg, return nr_reclaimed; } +EXPORT_SYMBOL_GPL(try_to_free_mem_cgroup_pages); #endif static void age_active_anon(struct pglist_data *pgdat, diff --git a/net/OWNERS b/net/OWNERS deleted file mode 100644 index ddb7653770ec..000000000000 --- a/net/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/net/OWNERS diff --git a/net/core/dev.c b/net/core/dev.c index 0c9ce36afc8c..03667ef59534 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -146,6 +146,7 @@ #include #include #include +#include #include "net-sysfs.h" @@ -510,6 +511,12 @@ static inline void netdev_set_addr_lockdep_class(struct net_device *dev) static inline struct list_head *ptype_head(const struct packet_type *pt) { + struct list_head vendor_pt = { .next = NULL, }; + + trace_android_vh_ptype_head(pt, &vendor_pt); + if (vendor_pt.next) + return vendor_pt.next; + if (pt->type == htons(ETH_P_ALL)) return pt->dev ? &pt->dev->ptype_all : &ptype_all; else diff --git a/net/core/filter.c b/net/core/filter.c index ef6bdbb63ecb..035d66227ae2 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3244,9 +3244,6 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) u32 off = skb_mac_header_len(skb); int ret; - if (skb_is_gso(skb) && !skb_is_gso_tcp(skb)) - return -ENOTSUPP; - ret = skb_cow(skb, len_diff); if (unlikely(ret < 0)) return ret; @@ -3258,19 +3255,11 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) if (skb_is_gso(skb)) { struct skb_shared_info *shinfo = skb_shinfo(skb); - /* SKB_GSO_TCPV4 needs to be changed into - * SKB_GSO_TCPV6. - */ + /* SKB_GSO_TCPV4 needs to be changed into SKB_GSO_TCPV6. */ if (shinfo->gso_type & SKB_GSO_TCPV4) { shinfo->gso_type &= ~SKB_GSO_TCPV4; shinfo->gso_type |= SKB_GSO_TCPV6; } - - /* Due to IPv6 header, MSS needs to be downgraded. */ - skb_decrease_gso_size(shinfo, len_diff); - /* Header must be checked, and gso_segs recomputed. */ - shinfo->gso_type |= SKB_GSO_DODGY; - shinfo->gso_segs = 0; } skb->protocol = htons(ETH_P_IPV6); @@ -3285,9 +3274,6 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) u32 off = skb_mac_header_len(skb); int ret; - if (skb_is_gso(skb) && !skb_is_gso_tcp(skb)) - return -ENOTSUPP; - ret = skb_unclone(skb, GFP_ATOMIC); if (unlikely(ret < 0)) return ret; @@ -3299,19 +3285,11 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) if (skb_is_gso(skb)) { struct skb_shared_info *shinfo = skb_shinfo(skb); - /* SKB_GSO_TCPV6 needs to be changed into - * SKB_GSO_TCPV4. - */ + /* SKB_GSO_TCPV6 needs to be changed into SKB_GSO_TCPV4. */ if (shinfo->gso_type & SKB_GSO_TCPV6) { shinfo->gso_type &= ~SKB_GSO_TCPV6; shinfo->gso_type |= SKB_GSO_TCPV4; } - - /* Due to IPv4 header, MSS can be upgraded. */ - skb_increase_gso_size(shinfo, len_diff); - /* Header must be checked, and gso_segs recomputed. */ - shinfo->gso_type |= SKB_GSO_DODGY; - shinfo->gso_segs = 0; } skb->protocol = htons(ETH_P_IP); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1301ea694b94..5f681c384284 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -76,6 +76,7 @@ #include #include #include +#include #include "datagram.h" @@ -701,6 +702,7 @@ void kfree_skb(struct sk_buff *skb) if (!skb_unref(skb)) return; + trace_android_vh_kfree_skb(skb); trace_kfree_skb(skb, __builtin_return_address(0)); __kfree_skb(skb); } diff --git a/net/core/sock.c b/net/core/sock.c index e640a68f34ba..ffc1e1e8ec73 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -136,6 +136,7 @@ #include #include +#include #include #include @@ -1678,6 +1679,8 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, if (security_sk_alloc(sk, family, priority)) goto out_free; + trace_android_rvh_sk_alloc(sk); + if (!try_module_get(prot->owner)) goto out_free_sec; sk_tx_queue_clear(sk); @@ -1687,6 +1690,7 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, out_free_sec: security_sk_free(sk); + trace_android_rvh_sk_free(sk); out_free: if (slab != NULL) kmem_cache_free(slab, sk); @@ -1706,6 +1710,7 @@ static void sk_prot_free(struct proto *prot, struct sock *sk) cgroup_sk_free(&sk->sk_cgrp_data); mem_cgroup_sk_free(sk); security_sk_free(sk); + trace_android_rvh_sk_free(sk); if (slab != NULL) kmem_cache_free(slab, sk); else diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 2384ac048bea..6cb60f7c916e 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -280,6 +280,7 @@ #include #include +#include struct percpu_counter tcp_orphan_count; EXPORT_SYMBOL_GPL(tcp_orphan_count); @@ -1198,6 +1199,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) bool zc = false; long timeo; + trace_android_rvh_tcp_sendmsg_locked(sk, size); flags = msg->msg_flags; if (flags & MSG_ZEROCOPY && size && sock_flag(sk, SOCK_ZEROCOPY)) { @@ -2031,6 +2033,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, if (unlikely(flags & MSG_ERRQUEUE)) return inet_recv_error(sk, msg, len, addr_len); + trace_android_rvh_tcp_recvmsg(sk); if (sk_can_busy_loop(sk) && skb_queue_empty_lockless(&sk->sk_receive_queue) && (sk->sk_state == TCP_ESTABLISHED)) @@ -2243,6 +2246,7 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock, break; } while (len > 0); + trace_android_rvh_tcp_recvmsg_stat(sk, copied); /* According to UNIX98, msg_name/msg_namelen are ignored * on connected socket. I was just happy when found this 8) --ANK */ diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index fac5c1469cee..d4c464df9ff3 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -80,6 +80,7 @@ #include #include #include +#include int sysctl_tcp_max_orphans __read_mostly = NR_FILE; @@ -4618,6 +4619,7 @@ static bool tcp_ooo_try_coalesce(struct sock *sk, static void tcp_drop(struct sock *sk, struct sk_buff *skb) { + trace_android_vh_kfree_skb(skb); sk_drops_add(sk, skb); __kfree_skb(skb); } diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 9d28b2778e8f..d8dbe8045c0a 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -116,6 +116,7 @@ #if IS_ENABLED(CONFIG_IPV6) #include #endif +#include struct udp_table udp_table __read_mostly; EXPORT_SYMBOL(udp_table); @@ -1049,6 +1050,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */ return -EOPNOTSUPP; + trace_android_rvh_udp_sendmsg(sk); getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; @@ -1801,6 +1803,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, skb = __skb_recv_udp(sk, flags, noblock, &off, &err); if (!skb) return err; + trace_android_rvh_udp_recvmsg(sk); ulen = udp_skb_len(skb); copied = len; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d6e7a77ca123..812b79192b7e 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -90,6 +90,8 @@ #include #include +#include + #define INFINITY_LIFE_TIME 0xFFFFFFFF #define IPV6_MAX_STRLEN \ @@ -3344,6 +3346,7 @@ static void addrconf_addr_gen(struct inet6_dev *idev, bool prefix_route) static void addrconf_dev_config(struct net_device *dev) { struct inet6_dev *idev; + bool ret = false; ASSERT_RTNL(); @@ -3371,6 +3374,10 @@ static void addrconf_dev_config(struct net_device *dev) if (IS_ERR(idev)) return; + trace_android_vh_ipv6_gen_linklocal_addr(dev, &ret); + if (ret) + return; + /* this device type has no EUI support */ if (dev->type == ARPHRD_NONE && idev->cnf.addr_gen_mode == IN6_ADDR_GEN_MODE_EUI64) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index ff0168736f6e..573e0b817d05 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1514,6 +1515,8 @@ __nf_conntrack_alloc(struct net *net, nf_ct_zone_add(ct, zone); + trace_android_rvh_nf_conn_alloc(ct); + /* Because we use RCU lookups, we set ct_general.use to zero before * this is inserted in any list. */ @@ -1546,6 +1549,7 @@ void nf_conntrack_free(struct nf_conn *ct) nf_ct_ext_destroy(ct); kmem_cache_free(nf_conntrack_cachep, ct); smp_mb__before_atomic(); + trace_android_rvh_nf_conn_free(ct); atomic_dec(&net->ct.count); } EXPORT_SYMBOL_GPL(nf_conntrack_free); diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index 3720825e5db4..90579d0ee9f7 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -112,7 +112,7 @@ static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer) res = snprintf(iface_msg, NLMSG_MAX_SIZE, "INTERFACE=%s", iface); if (NLMSG_MAX_SIZE <= res) { - pr_err("message too long (%d)", res); + pr_err("message too long (%d)\n", res); return; } @@ -122,25 +122,25 @@ static void notify_netlink_uevent(const char *iface, struct idletimer_tg *timer) state ? "active" : "inactive"); if (NLMSG_MAX_SIZE <= res) { - pr_err("message too long (%d)", res); + pr_err("message too long (%d)\n", res); return; } if (state) { res = snprintf(uid_msg, NLMSG_MAX_SIZE, "UID=%u", timer->uid); if (NLMSG_MAX_SIZE <= res) - pr_err("message too long (%d)", res); + pr_err("message too long (%d)\n", res); } else { res = snprintf(uid_msg, NLMSG_MAX_SIZE, "UID="); if (NLMSG_MAX_SIZE <= res) - pr_err("message too long (%d)", res); + pr_err("message too long (%d)\n", res); } time_ns = timespec64_to_ns(&ts); res = snprintf(timestamp_msg, NLMSG_MAX_SIZE, "TIME_NS=%llu", time_ns); if (NLMSG_MAX_SIZE <= res) { timestamp_msg[0] = '\0'; - pr_err("message too long (%d)", res); + pr_err("message too long (%d)\n", res); } pr_debug("putting nlmsg: <%s> <%s> <%s> <%s>\n", iface_msg, state_msg, @@ -323,12 +323,12 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr); if (ret < 0) { - pr_debug("couldn't add file to sysfs"); + pr_debug("couldn't add file to sysfs\n"); goto out_free_attr; } list_add(&info->timer->entry, &idletimer_tg_list); - pr_debug("timer type value is 0."); + pr_debug("timer type value is 0.\n"); info->timer->timer_type = 0; info->timer->refcnt = 1; info->timer->send_nl_msg = false; @@ -389,7 +389,7 @@ static int idletimer_tg_create_v1(struct idletimer_tg_info_v1 *info) ret = sysfs_create_file(idletimer_tg_kobj, &info->timer->attr.attr); if (ret < 0) { - pr_debug("couldn't add file to sysfs"); + pr_debug("couldn't add file to sysfs\n"); goto out_free_attr; } @@ -397,7 +397,7 @@ static int idletimer_tg_create_v1(struct idletimer_tg_info_v1 *info) kobject_uevent(idletimer_tg_kobj,KOBJ_ADD); list_add(&info->timer->entry, &idletimer_tg_list); - pr_debug("timer type value is %u", info->timer_type); + pr_debug("timer type value is %u\n", info->timer_type); info->timer->timer_type = info->timer_type; info->timer->refcnt = 1; info->timer->send_nl_msg = (info->send_nl_msg != 0); diff --git a/scripts/mkcompile_h b/scripts/mkcompile_h index 4ae735039daf..a72b154de7b0 100755 --- a/scripts/mkcompile_h +++ b/scripts/mkcompile_h @@ -70,15 +70,23 @@ UTS_VERSION="$(echo $UTS_VERSION $CONFIG_FLAGS $TIMESTAMP | cut -b -$UTS_LEN)" # Only replace the real compile.h if the new one is different, # in order to preserve the timestamp and avoid unnecessary # recompilations. -# We don't consider the file changed if only the date/time changed. +# We don't consider the file changed if only the date/time changed, +# unless KBUILD_BUILD_TIMESTAMP was explicitly set (e.g. for +# reproducible builds with that value referring to a commit timestamp). # A kernel config change will increase the generation number, thus # causing compile.h to be updated (including date/time) due to the # changed comment in the # first line. +if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then + IGNORE_PATTERN="UTS_VERSION" +else + IGNORE_PATTERN="NOT_A_PATTERN_TO_BE_MATCHED" +fi + if [ -r $TARGET ] && \ - grep -v 'UTS_VERSION' $TARGET > .tmpver.1 && \ - grep -v 'UTS_VERSION' .tmpcompile > .tmpver.2 && \ + grep -v $IGNORE_PATTERN $TARGET > .tmpver.1 && \ + grep -v $IGNORE_PATTERN .tmpcompile > .tmpver.2 && \ cmp -s .tmpver.1 .tmpver.2; then rm -f .tmpcompile else diff --git a/security/selinux/avc.c b/security/selinux/avc.c index a6719fd24d20..e1efe744c6a5 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -300,26 +300,27 @@ static struct avc_xperms_decision_node struct avc_xperms_decision_node *xpd_node; struct extended_perms_decision *xpd; - xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, GFP_NOWAIT); + xpd_node = kmem_cache_zalloc(avc_xperms_decision_cachep, + GFP_NOWAIT | __GFP_NOWARN); if (!xpd_node) return NULL; xpd = &xpd_node->xpd; if (which & XPERMS_ALLOWED) { xpd->allowed = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_NOWAIT); + GFP_NOWAIT | __GFP_NOWARN); if (!xpd->allowed) goto error; } if (which & XPERMS_AUDITALLOW) { xpd->auditallow = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_NOWAIT); + GFP_NOWAIT | __GFP_NOWARN); if (!xpd->auditallow) goto error; } if (which & XPERMS_DONTAUDIT) { xpd->dontaudit = kmem_cache_zalloc(avc_xperms_data_cachep, - GFP_NOWAIT); + GFP_NOWAIT | __GFP_NOWARN); if (!xpd->dontaudit) goto error; } @@ -347,7 +348,7 @@ static struct avc_xperms_node *avc_xperms_alloc(void) { struct avc_xperms_node *xp_node; - xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT); + xp_node = kmem_cache_zalloc(avc_xperms_cachep, GFP_NOWAIT | __GFP_NOWARN); if (!xp_node) return xp_node; INIT_LIST_HEAD(&xp_node->xpd_head); @@ -505,7 +506,7 @@ static struct avc_node *avc_alloc_node(struct selinux_avc *avc) { struct avc_node *node; - node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT); + node = kmem_cache_zalloc(avc_node_cachep, GFP_NOWAIT | __GFP_NOWARN); if (!node) goto out; diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index f3ad0a7facfa..955e8c8389cd 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -117,7 +117,8 @@ struct security_class_mapping secclass_map[] = { { COMMON_IPC_PERMS, NULL } }, { "netlink_route_socket", { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", "nlmsg_readpriv", NULL } }, + "nlmsg_read", "nlmsg_write", "nlmsg_readpriv", "nlmsg_getneigh", + NULL } }, { "netlink_tcpdiag_socket", { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", NULL } }, diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 0f7e1aeaba11..a2c0cf6293ca 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -98,6 +98,7 @@ struct selinux_state { bool initialized; bool policycap[__POLICYDB_CAPABILITY_MAX]; bool android_netlink_route; + bool android_netlink_getneigh; struct page *status_page; struct mutex status_lock; @@ -227,6 +228,13 @@ static inline bool selinux_android_nlroute_getlink(void) return state->android_netlink_route; } +static inline bool selinux_android_nlroute_getneigh(void) +{ + struct selinux_state *state = &selinux_state; + + return state->android_netlink_getneigh; +} + struct selinux_policy_convert_data; struct selinux_load_state { diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 7968c2e45e39..9ad6f9b893f5 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -212,12 +212,12 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) return err; } -static void nlmsg_set_getlink_perm(u32 perm) +static void nlmsg_set_perm_for_type(u32 perm, u16 type) { int i; for (i = 0; i < ARRAY_SIZE(nlmsg_route_perms); i++) { - if (nlmsg_route_perms[i].nlmsg_type == RTM_GETLINK) { + if (nlmsg_route_perms[i].nlmsg_type == type) { nlmsg_route_perms[i].perm = perm; break; } @@ -227,11 +227,27 @@ static void nlmsg_set_getlink_perm(u32 perm) /** * Use nlmsg_readpriv as the permission for RTM_GETLINK messages if the * netlink_route_getlink policy capability is set. Otherwise use nlmsg_read. + * Similarly, use nlmsg_getneigh for RTM_GETNEIGH and RTM_GETNEIGHTBL if the + * netlink_route_getneigh policy capability is set. Otherwise use nlmsg_read. */ void selinux_nlmsg_init(void) { if (selinux_android_nlroute_getlink()) - nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV); + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV, + RTM_GETLINK); else - nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READ); + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ, + RTM_GETLINK); + + if (selinux_android_nlroute_getneigh()) { + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_GETNEIGH, + RTM_GETNEIGH); + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_GETNEIGH, + RTM_GETNEIGHTBL); + } else { + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ, + RTM_GETNEIGH); + nlmsg_set_perm_for_type(NETLINK_ROUTE_SOCKET__NLMSG_READ, + RTM_GETNEIGHTBL); + } } diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index ff5cc4b3f3c0..572370c71af5 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -2497,6 +2497,10 @@ int policydb_read(struct policydb *p, void *fp) p->android_netlink_route = 1; } + if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH)) { + p->android_netlink_getneigh = 1; + } + if (p->policyvers >= POLICYDB_VERSION_POLCAP) { rc = ebitmap_read(&p->policycaps, fp); if (rc) diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 6bedec43aa0b..be9988ebfa1b 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -239,6 +239,7 @@ struct genfs { struct policydb { int mls_enabled; int android_netlink_route; + int android_netlink_getneigh; /* symbol tables */ struct symtab symtab[SYM_NUM]; @@ -336,6 +337,7 @@ extern struct role_trans_datum *policydb_roletr_search( #define POLICYDB_CONFIG_MLS 1 #define POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE (1 << 31) +#define POLICYDB_CONFIG_ANDROID_NETLINK_GETNEIGH (1 << 30) /* the config flags related to unknown classes/perms are bits 2 and 3 */ #define REJECT_UNKNOWN 0x00000002 diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b70abc68aa19..a2fcde88ce0f 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -2162,6 +2162,7 @@ static void security_load_policycaps(struct selinux_state *state, } state->android_netlink_route = p->android_netlink_route; + state->android_netlink_getneigh = p->android_netlink_getneigh; selinux_nlmsg_init(); } diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index c1fec932c49d..f43a1dce3bd2 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -33,6 +33,10 @@ #include #include +#ifndef __GENKSYMS__ +#include +#endif + /* struct snd_compr_codec_caps overflows the ioctl bit size for some * architectures, so we need to disable the relevant ioctls. */ @@ -708,6 +712,20 @@ snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) static int snd_compr_pause(struct snd_compr_stream *stream) { int retval; + bool use_pause_in_drain = false; + bool leave_draining_state = false; + + trace_android_vh_snd_compr_use_pause_in_drain(&use_pause_in_drain, + &leave_draining_state); + + if (use_pause_in_drain && stream->runtime->state == SNDRV_PCM_STATE_DRAINING) { + retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_PUSH); + if (!retval && leave_draining_state) { + stream->runtime->state = SNDRV_PCM_STATE_PAUSED; + wake_up(&stream->runtime->sleep); + } + return retval; + } if (stream->runtime->state != SNDRV_PCM_STATE_RUNNING) return -EPERM; @@ -720,6 +738,14 @@ static int snd_compr_pause(struct snd_compr_stream *stream) static int snd_compr_resume(struct snd_compr_stream *stream) { int retval; + bool use_pause_in_drain = false; + bool leave_draining_state = false; + + trace_android_vh_snd_compr_use_pause_in_drain(&use_pause_in_drain, + &leave_draining_state); + + if (use_pause_in_drain && stream->runtime->state == SNDRV_PCM_STATE_DRAINING) + return stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_PAUSE_RELEASE); if (stream->runtime->state != SNDRV_PCM_STATE_PAUSED) return -EPERM; diff --git a/sound/usb/card.h b/sound/usb/card.h index e3a59455f71c..3683f10ff542 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -178,6 +178,8 @@ struct snd_usb_substream { bool trigger_tstamp_pending_update; /* trigger timestamp being updated from initial estimate */ struct media_ctl *media_ctl; + + ANDROID_KABI_RESERVE(1); }; struct snd_usb_stream { diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 0b90a4d04d7d..9e93a43ab353 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -14,6 +14,8 @@ #include #include +#include + #include "usbaudio.h" #include "card.h" #include "quirks.h" @@ -1508,6 +1510,7 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_usb_substream *subs = &as->substream[direction]; int ret; + bool is_support = false; ret = snd_vendor_set_pcm_connection(subs->dev, SOUND_PCM_OPEN, direction); @@ -1532,6 +1535,11 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream) if (ret) snd_usb_autosuspend(subs->stream->chip); } + + trace_android_vh_sound_usb_support_cpu_suspend(subs->dev, direction, &is_support); + if (!ret && is_support) + snd_usb_autosuspend(subs->stream->chip); + return ret; } @@ -1541,12 +1549,17 @@ static int snd_usb_pcm_close(struct snd_pcm_substream *substream) struct snd_usb_stream *as = snd_pcm_substream_chip(substream); struct snd_usb_substream *subs = &as->substream[direction]; int ret; + bool is_support = false; ret = snd_vendor_set_pcm_connection(subs->dev, SOUND_PCM_CLOSE, direction); if (ret) return ret; + trace_android_vh_sound_usb_support_cpu_suspend(subs->dev, direction, &is_support); + if (!ret && is_support) + snd_usb_autoresume(subs->stream->chip); + snd_media_stop_pipeline(subs); if (!as->chip->keep_iface && diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 47f56e0354cc..6d40b46c3c13 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -12,6 +12,8 @@ #define USB_ID_VENDOR(id) ((id) >> 16) #define USB_ID_PRODUCT(id) ((u16)(id)) +#include + /* * */ @@ -64,6 +66,11 @@ struct snd_usb_audio { struct mutex dev_lock; /* to protect any race with disconnect */ int card_num; /* cache pcm card number to use upon disconnect */ void (*disconnect_cb)(struct snd_usb_audio *chip); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); + ANDROID_KABI_RESERVE(3); + ANDROID_KABI_RESERVE(4); }; #define USB_AUDIO_IFACE_UNUSED ((void *)-1L) @@ -176,6 +183,9 @@ struct snd_usb_audio_vendor_ops { struct audioformat *found, int *cur_attr, int *attr); int (*usb_add_ctls)(struct snd_usb_audio *chip); + + ANDROID_KABI_RESERVE(1); + ANDROID_KABI_RESERVE(2); }; #endif /* __USBAUDIO_H */ diff --git a/tools/crypto/gen_fips140_testvecs.py b/tools/crypto/gen_fips140_testvecs.py new file mode 100755 index 000000000000..25164d83389c --- /dev/null +++ b/tools/crypto/gen_fips140_testvecs.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright 2021 Google LLC +# +# Generate most of the test vectors for the FIPS 140 cryptographic self-tests. +# +# Usage: +# tools/crypto/gen_fips140_testvecs.py > crypto/fips140-generated-testvecs.h +# +# Prerequisites: +# Debian: apt-get install python3-pycryptodome python3-cryptography +# Arch Linux: pacman -S python-pycryptodomex python-cryptography + +import hashlib +import hmac +import os + +import Cryptodome.Cipher.AES +import Cryptodome.Util.Counter + +import cryptography.hazmat.primitives.ciphers +import cryptography.hazmat.primitives.ciphers.algorithms +import cryptography.hazmat.primitives.ciphers.modes + +scriptname = os.path.basename(__file__) + +message = bytes('This is a 32-byte test message.\0', 'ascii') +aes_key = bytes('128-bit AES key\0', 'ascii') +aes_xts_key = bytes('This is an AES-128-XTS key.\0\0\0\0\0', 'ascii') +aes_iv = bytes('ABCDEFGHIJKL\0\0\0\0', 'ascii') +assoc = bytes('associated data string', 'ascii') +hmac_key = bytes('128-bit HMAC key', 'ascii') + +def warn_generated(): + print(f'''/* + * This header was automatically generated by {scriptname}. + * Don't edit it directly. + */''') + +def is_string_value(value): + return (value.isascii() and + all(c == '\x00' or c.isprintable() for c in str(value, 'ascii'))) + +def format_value(value, is_string): + if is_string: + return value + hexstr = '' + for byte in value: + hexstr += f'\\x{byte:02x}' + return hexstr + +def print_value(name, value): + is_string = is_string_value(value) + hdr = f'static const u8 fips_{name}[{len(value)}] __initconst =' + print(hdr, end='') + if is_string: + value = str(value, 'ascii').rstrip('\x00') + chars_per_byte = 1 + else: + chars_per_byte = 4 + bytes_per_line = 64 // chars_per_byte + + if len(hdr) + (chars_per_byte * len(value)) + 4 <= 80: + print(f' "{format_value(value, is_string)}"', end='') + else: + for chunk in [value[i:i+bytes_per_line] + for i in range(0, len(value), bytes_per_line)]: + print(f'\n\t"{format_value(chunk, is_string)}"', end='') + print(';') + print('') + +def generate_aes_testvecs(): + print_value('aes_key', aes_key) + print_value('aes_iv', aes_iv) + + cbc = Cryptodome.Cipher.AES.new(aes_key, Cryptodome.Cipher.AES.MODE_CBC, + iv=aes_iv) + print_value('aes_cbc_ciphertext', cbc.encrypt(message)) + + ecb = Cryptodome.Cipher.AES.new(aes_key, Cryptodome.Cipher.AES.MODE_ECB) + print_value('aes_ecb_ciphertext', ecb.encrypt(message)) + + ctr = Cryptodome.Cipher.AES.new(aes_key, Cryptodome.Cipher.AES.MODE_CTR, + nonce=aes_iv[:12]) + print_value('aes_ctr_ciphertext', ctr.encrypt(message)) + + print_value('aes_gcm_assoc', assoc) + gcm = Cryptodome.Cipher.AES.new(aes_key, Cryptodome.Cipher.AES.MODE_GCM, + nonce=aes_iv[:12], mac_len=16) + gcm.update(assoc) + raw_ciphertext, tag = gcm.encrypt_and_digest(message) + print_value('aes_gcm_ciphertext', raw_ciphertext + tag) + + # Unfortunately, pycryptodome doesn't support XTS, so for it we need to use + # a different Python package (the "cryptography" package). + print_value('aes_xts_key', aes_xts_key) + xts = cryptography.hazmat.primitives.ciphers.Cipher( + cryptography.hazmat.primitives.ciphers.algorithms.AES(aes_xts_key), + cryptography.hazmat.primitives.ciphers.modes.XTS(aes_iv)).encryptor() + ciphertext = xts.update(message) + xts.finalize() + print_value('aes_xts_ciphertext', ciphertext) + +def generate_sha_testvecs(): + print_value('hmac_key', hmac_key) + for alg in ['sha1', 'sha256', 'hmac_sha256', 'sha512']: + if alg.startswith('hmac_'): + h = hmac.new(hmac_key, message, alg.removeprefix('hmac_')) + else: + h = hashlib.new(alg, message) + print_value(f'{alg}_digest', h.digest()) + +print('/* SPDX-License-Identifier: GPL-2.0-only */') +print('/* Copyright 2021 Google LLC */') +print('') +warn_generated() +print('') +print_value('message', message) +generate_aes_testvecs() +generate_sha_testvecs() +warn_generated() diff --git a/tools/testing/selftests/filesystems/incfs/OWNERS b/tools/testing/selftests/filesystems/incfs/OWNERS deleted file mode 100644 index 5eb371e1a5a3..000000000000 --- a/tools/testing/selftests/filesystems/incfs/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# include OWNERS from the authoritative android-mainline branch -include kernel/common:android-mainline:/tools/testing/selftests/filesystems/incfs/OWNERS