diff options
| -rw-r--r-- | Documentation/devicetree/bindings/arm/msm/bcl.txt | 27 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi | 14 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm-smb138x.dtsi | 17 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msm8998-pm.dtsi | 3 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmfalcon.dtsi | 2 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmtriton-coresight.dtsi | 77 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmtriton.dtsi | 23 | ||||
| -rw-r--r-- | drivers/clk/msm/clock-osm.c | 7 | ||||
| -rw-r--r-- | drivers/power/qcom-charger/battery_current_limit.c | 37 | ||||
| -rw-r--r-- | include/linux/mm.h | 1 | ||||
| -rw-r--r-- | kernel/sched/core.c | 87 | ||||
| -rw-r--r-- | kernel/sched/rt.c | 8 | ||||
| -rw-r--r-- | mm/gup.c | 14 | ||||
| -rw-r--r-- | sound/usb/usb_audio_qmi_svc.c | 6 |
14 files changed, 258 insertions, 65 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/bcl.txt b/Documentation/devicetree/bindings/arm/msm/bcl.txt index 42acaa49c2a5..710c70a57840 100644 --- a/Documentation/devicetree/bindings/arm/msm/bcl.txt +++ b/Documentation/devicetree/bindings/arm/msm/bcl.txt @@ -38,17 +38,19 @@ Optional parameters: - qcom,bcl-framework-interface: If this property is defined, then the BCL uses the BCL framework for monitoring battery voltage and current. When this property is defined, the 'qcom,high-threshold-uamp', - 'qcom,low-threshold-uamp', 'qcom,mitigation-freq-khz', - 'qcom,vph-high-threshold-uv', 'qcom,vph-low-threshold-uv' and - 'qcom,thermal-handle' properties should be defined in the - 'qcom,ibat-monitor' node. + 'qcom,low-threshold-uamp', 'qcom,vph-high-threshold-uv', + 'qcom,vph-low-threshold-uv' and 'qcom,thermal-handle' properties + should be defined in the 'qcom,ibat-monitor' node. - qcom,bcl-hotplug-list = <hotplug-phandle-list>: List of phandles to the cores that are to be hotplugged, when battery current limit condition is reached. - qcom,bcl-soc-hotplug-list: List of phandles to the cores that are to be hotplugged, when battery SOC limit condition is reached. -- qcom,bcl-freq-control-list: List of phandles to the cores that are to be frequency - mitigated when BCL condition is reached. +- qcom,bcl-freq-control-list: This optional property takes list of phandles to the + cores that are to be frequency mitigated when BCL condition is + reached. When this property is defined, 'qcom,mitigation-freq-khz' + and 'qcom,thermal-handle' should be defined in the + 'qcom,ibat-monitor' node. - qcom,bcl-no-bms: This is an optional node for BCL IAVAIL monitor mode. If this property is defined, BCL IAVAIL monitor gets rbat value from power supply battery module instead of bms module. @@ -65,10 +67,12 @@ Optional nodes: which the BCL driver should cap the maximum frequency. * qcom,low-threshold-uamp: The battery current, in microampere, below which the BCL driver should clear the CPU frequency mitigation. - * qcom,mitigation-freq-khz: The maximum frequency value the BCL driver - should mitigate the CPUS's with. This frequency shouldn't be - less than the minimum frequency request that the kernel thermal - monitor driver places during vdd restriction. + * qcom,mitigation-freq-khz: This optional property defines the maximum + frequency value the BCL driver should mitigate the CPUS's with. + This property is valid only if 'qcom,bcl-freq-control-list' is + defined in bcl parent node. This frequency shouldn't be less than + the minimum frequency request that the kernel thermal monitor + driver places during vdd restriction. * qcom,ibat-channel: The ADC hardware's Ibat channel number. * qcom,uv-to-ua-numerator: The conversion parameter required for converting the voltage measure from ADC hardware to current value. @@ -92,7 +96,8 @@ Optional nodes: used by BCL driver to get the minimum frequency request that the thermal driver places during vdd restriction. This frequency value will be the lowest max frequency value the BCL driver can - request. + request. This property is valid only if 'qcom,bcl-freq-control-list' + is defined in bcl parent node. * qcom,soc-low-threshold: The battery SOC percentage threshold below which mitigation needs to be applied. diff --git a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi index 9af9ba7e4537..1cc31380604b 100644 --- a/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmfalcon.dtsi @@ -550,6 +550,20 @@ "dma-grant"; }; }; + + bcl@4200 { + compatible = "qcom,msm-bcl-lmh"; + reg = <0x4200 0xff>, + <0x4300 0xff>; + reg-names = "fg_user_adc", + "fg_lmh"; + interrupts = <0x0 0x42 0x0 IRQ_TYPE_NONE>, + <0x0 0x42 0x2 IRQ_TYPE_NONE>; + interrupt-names = "bcl-high-ibat-int", + "bcl-low-vbat-int"; + qcom,vbat-polling-delay-ms = <100>; + qcom,ibat-polling-delay-ms = <100>; + }; }; qcom,pmfalcon@1 { diff --git a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi index b8c721e64ca7..e6e04f19d7ea 100644 --- a/arch/arm/boot/dts/qcom/msm-smb138x.dtsi +++ b/arch/arm/boot/dts/qcom/msm-smb138x.dtsi @@ -14,11 +14,11 @@ &i2c_7 { status = "okay"; - qcom,smb138x@8 { + smb138x: qcom,smb138x@8 { compatible = "qcom,i2c-pmic"; reg = <0x8>; - #address-cells = <2>; - #size-cells = <0>; + #address-cells = <1>; + #size-cells = <1>; interrupt-parent = <&spmi_bus>; interrupts = <0x0 0xd1 0x0 IRQ_TYPE_LEVEL_LOW>; interrupt_names = "smb138x"; @@ -37,6 +37,7 @@ #address-cells = <1>; #size-cells = <0>; #io-channel-cells = <1>; + interrupt-parent = <&smb138x>; interrupts = <0x36 0x0 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "eoc"; @@ -91,13 +92,21 @@ compatible = "qcom,smb138x-parallel-slave"; qcom,pmic-revid = <&smb138x_revid>; reg = <0x1000 0x700>; - + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&smb138x>; io-channels = <&smb138x_tadc 2>, <&smb138x_tadc 12>, <&smb138x_tadc 3>; io-channel-names = "charger_temp", "charger_temp_max", "batt_i"; + + qcom,chgr-misc@1600 { + reg = <0x1600 0x100>; + interrupts = <0x16 0x1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog-bark"; + }; }; }; }; diff --git a/arch/arm/boot/dts/qcom/msm8998-pm.dtsi b/arch/arm/boot/dts/qcom/msm8998-pm.dtsi index c6d7defbf35c..8fd75c369c53 100644 --- a/arch/arm/boot/dts/qcom/msm8998-pm.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-pm.dtsi @@ -343,7 +343,8 @@ <0x2 216>, /* tsens1_upper_lower_int */ <0x34 275>, /* qmp_usb3_lfps_rxterm_irq_cx */ <0x57 358>, /* spmi_periph_irq[0] */ - <0x4f 379>, /* usb2phy_intr */ + <0x4f 379>, /* usb2phy_intr: qusb2phy_dmse_hv */ + <0x51 379>, /* usb2phy_intr: qusb2phy_dpse_hv */ <0x50 384>, /* sp_rmb_sp2soc_irq */ <0xff 16>, /* APC0_qgicQTmrHypPhysIrptReq */ <0xff 17>, /* APC3_qgicQTmrSecPhysIrptReq */ diff --git a/arch/arm/boot/dts/qcom/msmfalcon.dtsi b/arch/arm/boot/dts/qcom/msmfalcon.dtsi index 2623a65a4bc2..572a896ad795 100644 --- a/arch/arm/boot/dts/qcom/msmfalcon.dtsi +++ b/arch/arm/boot/dts/qcom/msmfalcon.dtsi @@ -1007,7 +1007,7 @@ <0x10b4000 0x800>; reg-names = "dcc-base", "dcc-ram-base"; - clocks = <&clock_rpmcc GCC_DCC_AHB_CLK>; + clocks = <&clock_gcc GCC_DCC_AHB_CLK>; clock-names = "dcc_clk"; }; diff --git a/arch/arm/boot/dts/qcom/msmtriton-coresight.dtsi b/arch/arm/boot/dts/qcom/msmtriton-coresight.dtsi new file mode 100644 index 000000000000..017483c36866 --- /dev/null +++ b/arch/arm/boot/dts/qcom/msmtriton-coresight.dtsi @@ -0,0 +1,77 @@ +/* Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "msmfalcon-coresight.dtsi" + +&etm0 { + cpu = <&CPU4>; +}; + +&etm1 { + cpu = <&CPU5>; +}; + +&etm2 { + cpu = <&CPU6>; +}; + +&etm3 { + cpu = <&CPU7>; +}; + +&etm4 { + cpu = <&CPU0>; +}; + +&etm5 { + cpu = <&CPU1>; +}; + +&etm6 { + cpu = <&CPU2>; +}; + +&etm7 { + cpu = <&CPU3>; +}; + +&cti_cpu0 { + cpu = <&CPU4>; +}; + +&cti_cpu1 { + cpu = <&CPU5>; +}; + +&cti_cpu2 { + cpu = <&CPU6>; +}; + +&cti_cpu3 { + cpu = <&CPU7>; +}; + +&cti_cpu4 { + cpu = <&CPU0>; +}; + +&cti_cpu5 { + cpu = <&CPU1>; +}; + +&cti_cpu6 { + cpu = <&CPU2>; +}; + +&cti_cpu7 { + cpu = <&CPU3>; +}; diff --git a/arch/arm/boot/dts/qcom/msmtriton.dtsi b/arch/arm/boot/dts/qcom/msmtriton.dtsi index 2551d7f0f849..dfa592c16643 100644 --- a/arch/arm/boot/dts/qcom/msmtriton.dtsi +++ b/arch/arm/boot/dts/qcom/msmtriton.dtsi @@ -304,6 +304,7 @@ }; #include "msmtriton-smp2p.dtsi" +#include "msmtriton-coresight.dtsi" &soc { #address-cells = <1>; #size-cells = <1>; @@ -448,6 +449,18 @@ qcom,sensors = <12>; }; + wdog: qcom,wdt@17817000 { + status = "disabled"; + compatible = "qcom,msm-watchdog"; + reg = <0x17817000 0x1000>; + reg-names = "wdt-base"; + interrupts = <0 3 0>, <0 4 0>; + qcom,bark-time = <11000>; + qcom,pet-time = <10000>; + qcom,ipi-ping; + qcom,wakeup-enable; + }; + uartblsp1dm1: serial@0c170000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0xc170000 0x1000>; @@ -603,6 +616,16 @@ qcom,mpu-enabled; }; + dcc: dcc@10b3000 { + compatible = "qcom,dcc"; + reg = <0x10b3000 0x1000>, + <0x10b4000 0x800>; + reg-names = "dcc-base", "dcc-ram-base"; + + clocks = <&clock_gcc GCC_DCC_AHB_CLK>; + clock-names = "dcc_clk"; + }; + qcom,glink-smem-native-xprt-modem@86000000 { compatible = "qcom,glink-smem-native-xprt"; reg = <0x86000000 0x200000>, diff --git a/drivers/clk/msm/clock-osm.c b/drivers/clk/msm/clock-osm.c index 3b526c0db659..7094fb4d40af 100644 --- a/drivers/clk/msm/clock-osm.c +++ b/drivers/clk/msm/clock-osm.c @@ -81,7 +81,6 @@ enum clk_osm_trace_packet_id { #define MEM_ACC_SEQ_REG_VAL_START(n) (SEQ_REG(60 + (n))) #define SEQ_REG1_MSM8998_V2 0x1048 #define VERSION_REG 0x0 -#define VERSION_1P1 0x00010100 #define OSM_TABLE_SIZE 40 #define MAX_CLUSTER_CNT 2 @@ -353,7 +352,6 @@ struct clk_osm { unsigned long pbases[NUM_BASES]; spinlock_t lock; - u32 version; u32 cpu_reg_mask; u32 num_entries; u32 cluster_num; @@ -2569,7 +2567,7 @@ static int debugfs_set_wdog_trace(void *data, u64 val) struct clk_osm *c = data; int regval; - if (c->version >= VERSION_1P1) { + if (msm8998_v2) { regval = clk_osm_read_reg(c, TRACE_CTRL); regval = val ? regval | TRACE_CTRL_ENABLE_WDOG_STATUS : regval & ~TRACE_CTRL_ENABLE_WDOG_STATUS; @@ -3360,9 +3358,6 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev) goto exit2; } - pwrcl_clk.version = clk_osm_read_reg(&pwrcl_clk, VERSION_REG); - perfcl_clk.version = clk_osm_read_reg(&perfcl_clk, VERSION_REG); - populate_opp_table(pdev); populate_debugfs_dir(&pwrcl_clk); populate_debugfs_dir(&perfcl_clk); diff --git a/drivers/power/qcom-charger/battery_current_limit.c b/drivers/power/qcom-charger/battery_current_limit.c index 951d0544efa0..d2c25bfbf66c 100644 --- a/drivers/power/qcom-charger/battery_current_limit.c +++ b/drivers/power/qcom-charger/battery_current_limit.c @@ -1495,10 +1495,7 @@ static int probe_bcl_periph_prop(struct bcl_context *bcl) bcl->ibat_high_thresh.trip_value); if (ret) goto ibat_probe_exit; - BCL_FETCH_DT_U32(ibat_node, key, "qcom,mitigation-freq-khz", ret, - bcl->bcl_p_freq_max); - if (ret) - goto ibat_probe_exit; + BCL_FETCH_DT_U32(ibat_node, key, "qcom,vph-high-threshold-uv", ret, bcl->vbat_high_thresh.trip_value); if (ret) @@ -1520,7 +1517,18 @@ static int probe_bcl_periph_prop(struct bcl_context *bcl) = bcl->ibat_low_thresh.trip_notify = bcl_periph_ibat_notify; bcl->ibat_high_thresh.trip_data = bcl->ibat_low_thresh.trip_data = (void *) bcl; - get_vdd_rstr_freq(bcl, ibat_node); + + if (bcl_frequency_mask) { + BCL_FETCH_DT_U32(ibat_node, key, "qcom,mitigation-freq-khz", + ret, bcl->bcl_p_freq_max); + if (ret) + goto ibat_probe_exit; + get_vdd_rstr_freq(bcl, ibat_node); + } else { + bcl->bcl_p_freq_max = UINT_MAX; + bcl->thermal_freq_limit = 0; + } + bcl->bcl_p_freq_max = max(bcl->bcl_p_freq_max, bcl->thermal_freq_limit); bcl->btm_mode = BCL_MONITOR_DISABLED; @@ -1574,11 +1582,6 @@ static int probe_btm_properties(struct bcl_context *bcl) goto btm_probe_exit; bcl->btm_high_threshold_uv = current_to_voltage(bcl, curr_ua); - key = "qcom,mitigation-freq-khz"; - ret = of_property_read_u32(ibat_node, key, &bcl->btm_freq_max); - if (ret < 0) - goto btm_probe_exit; - key = "qcom,ibat-channel"; ret = of_property_read_u32(ibat_node, key, &bcl->btm_ibat_chan); if (ret < 0) @@ -1618,7 +1621,17 @@ static int probe_btm_properties(struct bcl_context *bcl) ret = PTR_ERR(bcl->btm_vadc_dev); goto btm_probe_exit; } - get_vdd_rstr_freq(bcl, ibat_node); + + if (bcl_frequency_mask) { + key = "qcom,mitigation-freq-khz"; + ret = of_property_read_u32(ibat_node, key, &bcl->btm_freq_max); + if (ret < 0) + goto btm_probe_exit; + get_vdd_rstr_freq(bcl, ibat_node); + } else { + bcl->btm_freq_max = UINT_MAX; + bcl->thermal_freq_limit = 0; + } bcl->btm_freq_max = max(bcl->btm_freq_max, bcl->thermal_freq_limit); bcl->btm_mode = BCL_MONITOR_DISABLED; @@ -1738,6 +1751,8 @@ static int bcl_probe(struct platform_device *pdev) } } for_each_possible_cpu(cpu) { + if (!(bcl_frequency_mask & BIT(cpu))) + continue; snprintf(cpu_str, MAX_CPU_NAME, "cpu%d", cpu); bcl->cpufreq_handle[cpu] = devmgr_register_mitigation_client( &pdev->dev, cpu_str, NULL); diff --git a/include/linux/mm.h b/include/linux/mm.h index 6c1ea7f327c4..0c4178e5b656 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2128,6 +2128,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma, #define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */ #define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */ #define FOLL_MLOCK 0x1000 /* lock present pages */ +#define FOLL_COW 0x4000 /* internal GUP flag */ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr, void *data); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d7846edd7a79..ee708909dc17 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1248,15 +1248,16 @@ static int __set_cpus_allowed_ptr(struct task_struct *p, goto out; cpumask_andnot(&allowed_mask, new_mask, cpu_isolated_mask); + cpumask_and(&allowed_mask, &allowed_mask, cpu_active_mask); - dest_cpu = cpumask_any_and(cpu_active_mask, &allowed_mask); + dest_cpu = cpumask_any(&allowed_mask); if (dest_cpu >= nr_cpu_ids) { - dest_cpu = cpumask_any_and(cpu_active_mask, new_mask); + cpumask_and(&allowed_mask, cpu_active_mask, new_mask); + dest_cpu = cpumask_any(&allowed_mask); if (dest_cpu >= nr_cpu_ids) { ret = -EINVAL; goto out; } - cpumask_copy(&allowed_mask, new_mask); } do_set_cpus_allowed(p, new_mask); @@ -4635,6 +4636,8 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) cpumask_var_t cpus_allowed, new_mask; struct task_struct *p; int retval; + int dest_cpu; + cpumask_t allowed_mask; rcu_read_lock(); @@ -4696,20 +4699,26 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask) } #endif again: - retval = __set_cpus_allowed_ptr(p, new_mask, true); - - if (!retval) { - cpuset_cpus_allowed(p, cpus_allowed); - if (!cpumask_subset(new_mask, cpus_allowed)) { - /* - * We must have raced with a concurrent cpuset - * update. Just reset the cpus_allowed to the - * cpuset's cpus_allowed - */ - cpumask_copy(new_mask, cpus_allowed); - goto again; + cpumask_andnot(&allowed_mask, new_mask, cpu_isolated_mask); + dest_cpu = cpumask_any_and(cpu_active_mask, &allowed_mask); + if (dest_cpu < nr_cpu_ids) { + retval = __set_cpus_allowed_ptr(p, new_mask, true); + if (!retval) { + cpuset_cpus_allowed(p, cpus_allowed); + if (!cpumask_subset(new_mask, cpus_allowed)) { + /* + * We must have raced with a concurrent cpuset + * update. Just reset the cpus_allowed to the + * cpuset's cpus_allowed + */ + cpumask_copy(new_mask, cpus_allowed); + goto again; + } } + } else { + retval = -EINVAL; } + out_free_new_mask: free_cpumask_var(new_mask); out_free_cpus_allowed: @@ -5455,6 +5464,37 @@ static struct task_struct fake_task = { }; /* + * Remove a task from the runqueue and pretend that it's migrating. This + * should prevent migrations for the detached task and disallow further + * changes to tsk_cpus_allowed. + */ +static void +detach_one_task(struct task_struct *p, struct rq *rq, struct list_head *tasks) +{ + lockdep_assert_held(&rq->lock); + + p->on_rq = TASK_ON_RQ_MIGRATING; + deactivate_task(rq, p, 0); + list_add(&p->se.group_node, tasks); +} + +static void attach_tasks(struct list_head *tasks, struct rq *rq) +{ + struct task_struct *p; + + lockdep_assert_held(&rq->lock); + + while (!list_empty(tasks)) { + p = list_first_entry(tasks, struct task_struct, se.group_node); + list_del_init(&p->se.group_node); + + BUG_ON(task_rq(p) != rq); + activate_task(rq, p, 0); + p->on_rq = TASK_ON_RQ_QUEUED; + } +} + +/* * Migrate all tasks (not pinned if pinned argument say so) from the rq, * sleeping tasks will be migrated by try_to_wake_up()->select_task_rq(). * @@ -5468,6 +5508,7 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks) struct task_struct *next, *stop = rq->stop; int dest_cpu; unsigned int num_pinned_kthreads = 1; /* this thread */ + LIST_HEAD(tasks); cpumask_t avail_cpus; cpumask_andnot(&avail_cpus, cpu_online_mask, cpu_isolated_mask); @@ -5492,12 +5533,10 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks) for (;;) { /* - * There's this thread running + pinned threads, bail when - * that's the only remaining threads. + * There's this thread running, bail when that's the only + * remaining thread. */ - if ((migrate_pinned_tasks && rq->nr_running == 1) || - (!migrate_pinned_tasks && - rq->nr_running <= num_pinned_kthreads)) + if (rq->nr_running == 1) break; /* @@ -5510,8 +5549,9 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks) if (!migrate_pinned_tasks && next->flags & PF_KTHREAD && !cpumask_intersects(&avail_cpus, &next->cpus_allowed)) { - lockdep_unpin_lock(&rq->lock); + detach_one_task(next, rq, &tasks); num_pinned_kthreads += 1; + lockdep_unpin_lock(&rq->lock); continue; } @@ -5559,6 +5599,9 @@ static void migrate_tasks(struct rq *dead_rq, bool migrate_pinned_tasks) } rq->stop = stop; + + if (num_pinned_kthreads > 1) + attach_tasks(&tasks, rq); } static void set_rq_online(struct rq *rq); @@ -5600,6 +5643,7 @@ int do_isolation_work_cpu_stop(void *data) */ nohz_balance_clear_nohz_mask(cpu); + clear_hmp_request(cpu); local_irq_enable(); return 0; } @@ -5724,7 +5768,6 @@ int sched_isolate_cpu(int cpu) migrate_sync_cpu(cpu, cpumask_first(&avail_cpus)); stop_cpus(cpumask_of(cpu), do_isolation_work_cpu_stop, 0); - clear_hmp_request(cpu); calc_load_migrate(rq); update_max_interval(); diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 12a04f30ef77..52edd6b158ed 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1970,11 +1970,11 @@ retry: goto retry; } - deactivate_task(rq, next_task, 0); next_task->on_rq = TASK_ON_RQ_MIGRATING; + deactivate_task(rq, next_task, 0); set_task_cpu(next_task, lowest_rq->cpu); - next_task->on_rq = TASK_ON_RQ_QUEUED; activate_task(lowest_rq, next_task, 0); + next_task->on_rq = TASK_ON_RQ_QUEUED; ret = 1; resched_curr(lowest_rq); @@ -2226,11 +2226,11 @@ static void pull_rt_task(struct rq *this_rq) resched = true; - deactivate_task(src_rq, p, 0); p->on_rq = TASK_ON_RQ_MIGRATING; + deactivate_task(src_rq, p, 0); set_task_cpu(p, this_cpu); - p->on_rq = TASK_ON_RQ_QUEUED; activate_task(this_rq, p, 0); + p->on_rq = TASK_ON_RQ_QUEUED; /* * We continue with the search, just in * case there's an even higher prio task @@ -58,6 +58,16 @@ static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address, return -EEXIST; } +/* + * FOLL_FORCE can write to even unwritable pte's, but only + * after we've gone through a COW cycle and they are dirty. + */ +static inline bool can_follow_write_pte(pte_t pte, unsigned int flags) +{ + return pte_write(pte) || + ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte)); +} + static struct page *follow_page_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd, unsigned int flags) { @@ -92,7 +102,7 @@ retry: } if ((flags & FOLL_NUMA) && pte_protnone(pte)) goto no_page; - if ((flags & FOLL_WRITE) && !pte_write(pte)) { + if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) { pte_unmap_unlock(ptep, ptl); return NULL; } @@ -352,7 +362,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma, * reCOWed by userspace write). */ if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE)) - *flags &= ~FOLL_WRITE; + *flags |= FOLL_COW; return 0; } diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c index 22468eee62db..8ce87195548e 100644 --- a/sound/usb/usb_audio_qmi_svc.c +++ b/sound/usb/usb_audio_qmi_svc.c @@ -495,9 +495,8 @@ static int prepare_qmi_response(struct snd_usb_substream *subs, if (subs->sync_endpoint) { ep = usb_pipe_endpoint(subs->dev, subs->sync_endpoint->pipe); if (!ep) { - pr_err("%s: sync ep # %d context is null\n", __func__, - subs->sync_endpoint->ep_num); - goto err; + pr_debug("%s: implicit fb on data ep\n", __func__); + goto skip_sync_ep; } memcpy(&resp->std_as_sync_ep_desc, &ep->desc, sizeof(ep->desc)); resp->std_as_sync_ep_desc_valid = 1; @@ -511,6 +510,7 @@ static int prepare_qmi_response(struct snd_usb_substream *subs, resp->xhci_mem_info.tr_sync.pa = xhci_pa; } +skip_sync_ep: resp->interrupter_num = uaudio_qdev->intr_num; resp->interrupter_num_valid = 1; |
