Linux 5.7-rc4
Unified · Split
| @@ -182,12 +182,15 @@ fix_padding · 181 unmodified lines | |||
| 182 | space-efficient. If this option is not present, large padding is | 182 | space-efficient. If this option is not present, large padding is |
| 183 | used - that is for compatibility with older kernels. | 183 | used - that is for compatibility with older kernels. |
| 184 | 184 | ||
| 185 | 185 | allow_discards | |
| 186 | The journal mode (D/J), buffer_sectors, journal_watermark, commit_time can | 186 | Allow block discard requests (a.k.a. TRIM) for the integrity device. |
| 187 | be changed when reloading the target (load an inactive table and swap the | 187 | Discards are only allowed to devices using internal hash. |
| 188 | tables with suspend and resume). The other arguments should not be changed | 188 | |
| 189 | when reloading the target because the layout of disk data depend on them | 189 | The journal mode (D/J), buffer_sectors, journal_watermark, commit_time and |
| 190 | and the reloaded target would be non-functional. | 190 | allow_discards can be changed when reloading the target (load an inactive |
| 191 | table and swap the tables with suspend and resume). The other arguments | ||
| 192 | should not be changed when reloading the target because the layout of disk | ||
| 193 | data depend on them and the reloaded target would be non-functional. | ||
| 191 | 194 | ||
| 192 | 195 | ||
| 193 | The layout of the formatted block device: | 196 | The layout of the formatted block device: |
| @@ -22,9 +22,7 @@ properties: · 21 unmodified lines | |||
| 22 | const: socionext,uniphier-xdmac | 22 | const: socionext,uniphier-xdmac |
| 23 | 23 | ||
| 24 | reg: | 24 | reg: |
| 25 | items: | 25 | maxItems: 1 |
| 26 | - description: XDMAC base register region (offset and length) | ||
| 27 | - description: XDMAC extension register region (offset and length) | ||
| 28 | 26 | ||
| 29 | interrupts: | 27 | interrupts: |
| 30 | maxItems: 1 | 28 | maxItems: 1 |
| @@ -49,12 +47,13 @@ required: · 18 unmodified lines | |||
| 49 | - reg | 47 | - reg |
| 50 | - interrupts | 48 | - interrupts |
| 51 | - "#dma-cells" | 49 | - "#dma-cells" |
| 50 | - dma-channels | ||
| 52 | 51 | ||
| 53 | examples: | 52 | examples: |
| 54 | - | | 53 | - | |
| 55 | xdmac: dma-controller@5fc10000 { | 54 | xdmac: dma-controller@5fc10000 { |
| 56 | compatible = "socionext,uniphier-xdmac"; | 55 | compatible = "socionext,uniphier-xdmac"; |
| 57 | reg = <0x5fc10000 0x1000>, <0x5fc20000 0x800>; | 56 | reg = <0x5fc10000 0x5300>; |
| 58 | interrupts = <0 188 4>; | 57 | interrupts = <0 188 4>; |
| 59 | #dma-cells = <2>; | 58 | #dma-cells = <2>; |
| 60 | dma-channels = <16>; | 59 | dma-channels = <16>; |
| @@ -3657,7 +3657,7 @@ L: linux-btrfs@vger.kernel.org · 3656 unmodified lines | |||
| 3657 | S: Maintained | 3657 | S: Maintained |
| 3658 | W: http://btrfs.wiki.kernel.org/ | 3658 | W: http://btrfs.wiki.kernel.org/ |
| 3659 | Q: http://patchwork.kernel.org/project/linux-btrfs/list/ | 3659 | Q: http://patchwork.kernel.org/project/linux-btrfs/list/ |
| 3660 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs.git | 3660 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git |
| 3661 | F: Documentation/filesystems/btrfs.rst | 3661 | F: Documentation/filesystems/btrfs.rst |
| 3662 | F: fs/btrfs/ | 3662 | F: fs/btrfs/ |
| 3663 | F: include/linux/btrfs* | 3663 | F: include/linux/btrfs* |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 5 | 2 | VERSION = 5 |
| 3 | PATCHLEVEL = 7 | 3 | PATCHLEVEL = 7 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc3 | 5 | EXTRAVERSION = -rc4 |
| 6 | NAME = Kleptomaniac Octopus | 6 | NAME = Kleptomaniac Octopus |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -32,7 +32,7 @@ UBSAN_SANITIZE := n · 31 unmodified lines | |||
| 32 | OBJECT_FILES_NON_STANDARD := y | 32 | OBJECT_FILES_NON_STANDARD := y |
| 33 | KCOV_INSTRUMENT := n | 33 | KCOV_INSTRUMENT := n |
| 34 | 34 | ||
| 35 | CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny | 35 | CFLAGS_vgettimeofday.o = -O2 -mcmodel=tiny -fasynchronous-unwind-tables |
| 36 | 36 | ||
| 37 | ifneq ($(c-gettimeofday-y),) | 37 | ifneq ($(c-gettimeofday-y),) |
| 38 | CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) | 38 | CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y) |
| @@ -60,7 +60,7 @@ config RISCV · 59 unmodified lines | |||
| 60 | select ARCH_HAS_GIGANTIC_PAGE | 60 | select ARCH_HAS_GIGANTIC_PAGE |
| 61 | select ARCH_HAS_SET_DIRECT_MAP | 61 | select ARCH_HAS_SET_DIRECT_MAP |
| 62 | select ARCH_HAS_SET_MEMORY | 62 | select ARCH_HAS_SET_MEMORY |
| 63 | select ARCH_HAS_STRICT_KERNEL_RWX | 63 | select ARCH_HAS_STRICT_KERNEL_RWX if MMU |
| 64 | select ARCH_WANT_HUGE_PMD_SHARE if 64BIT | 64 | select ARCH_WANT_HUGE_PMD_SHARE if 64BIT |
| 65 | select SPARSEMEM_STATIC if 32BIT | 65 | select SPARSEMEM_STATIC if 32BIT |
| 66 | select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU | 66 | select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU |
| @@ -102,7 +102,7 @@ void sbi_shutdown(void) · 101 unmodified lines | |||
| 102 | { | 102 | { |
| 103 | sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); | 103 | sbi_ecall(SBI_EXT_0_1_SHUTDOWN, 0, 0, 0, 0, 0, 0, 0); |
| 104 | } | 104 | } |
| 105 | EXPORT_SYMBOL(sbi_set_timer); | 105 | EXPORT_SYMBOL(sbi_shutdown); |
| 106 | 106 | ||
| 107 | /** | 107 | /** |
| 108 | * sbi_clear_ipi() - Clear any pending IPIs for the calling hart. | 108 | * sbi_clear_ipi() - Clear any pending IPIs for the calling hart. |
| @@ -113,7 +113,7 @@ void sbi_clear_ipi(void) · 4 unmodified lines | |||
| 113 | { | 113 | { |
| 114 | sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0); | 114 | sbi_ecall(SBI_EXT_0_1_CLEAR_IPI, 0, 0, 0, 0, 0, 0, 0); |
| 115 | } | 115 | } |
| 116 | EXPORT_SYMBOL(sbi_shutdown); | 116 | EXPORT_SYMBOL(sbi_clear_ipi); |
| 117 | 117 | ||
| 118 | /** | 118 | /** |
| 119 | * sbi_set_timer_v01() - Program the timer for next timer event. | 119 | * sbi_set_timer_v01() - Program the timer for next timer event. |
| @@ -167,6 +167,11 @@ static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask, · 47 unmodified lines | |||
| 167 | 167 | ||
| 168 | return result; | 168 | return result; |
| 169 | } | 169 | } |
| 170 | |||
| 171 | static void sbi_set_power_off(void) | ||
| 172 | { | ||
| 173 | pm_power_off = sbi_shutdown; | ||
| 174 | } | ||
| 170 | #else | 175 | #else |
| 171 | static void __sbi_set_timer_v01(uint64_t stime_value) | 176 | static void __sbi_set_timer_v01(uint64_t stime_value) |
| 172 | { | 177 | { |
| @@ -191,6 +196,8 @@ static int __sbi_rfence_v01(int fid, const unsigned long *hart_mask, · 18 unmodified lines | |||
| 191 | 196 | ||
| 192 | return 0; | 197 | return 0; |
| 193 | } | 198 | } |
| 199 | |||
| 200 | static void sbi_set_power_off(void) {} | ||
| 194 | #endif /* CONFIG_RISCV_SBI_V01 */ | 201 | #endif /* CONFIG_RISCV_SBI_V01 */ |
| 195 | 202 | ||
| 196 | static void __sbi_set_timer_v02(uint64_t stime_value) | 203 | static void __sbi_set_timer_v02(uint64_t stime_value) |
| @@ -540,16 +547,12 @@ static inline long sbi_get_firmware_version(void) · 343 unmodified lines | |||
| 540 | return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION); | 547 | return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_VERSION); |
| 541 | } | 548 | } |
| 542 | 549 | ||
| 543 | static void sbi_power_off(void) | ||
| 544 | { | ||
| 545 | sbi_shutdown(); | ||
| 546 | } | ||
| 547 | 550 | ||
| 548 | int __init sbi_init(void) | 551 | int __init sbi_init(void) |
| 549 | { | 552 | { |
| 550 | int ret; | 553 | int ret; |
| 551 | 554 | ||
| 552 | pm_power_off = sbi_power_off; | 555 | sbi_set_power_off(); |
| 553 | ret = sbi_get_spec_version(); | 556 | ret = sbi_get_spec_version(); |
| 554 | if (ret > 0) | 557 | if (ret > 0) |
| 555 | sbi_spec_version = ret; | 558 | sbi_spec_version = ret; |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | |||
| 12 | #include <linux/stacktrace.h> | 12 | #include <linux/stacktrace.h> |
| 13 | #include <linux/ftrace.h> | 13 | #include <linux/ftrace.h> |
| 14 | 14 | ||
| 15 | register unsigned long sp_in_global __asm__("sp"); | ||
| 16 | |||
| 15 | #ifdef CONFIG_FRAME_POINTER | 17 | #ifdef CONFIG_FRAME_POINTER |
| 16 | 18 | ||
| 17 | struct stackframe { | 19 | struct stackframe { |
| @@ -19,8 +21,6 @@ struct stackframe { · 1 unmodified line | |||
| 19 | unsigned long ra; | 21 | unsigned long ra; |
| 20 | }; | 22 | }; |
| 21 | 23 | ||
| 22 | register unsigned long sp_in_global __asm__("sp"); | ||
| 23 | |||
| 24 | void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, | 24 | void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, |
| 25 | bool (*fn)(unsigned long, void *), void *arg) | 25 | bool (*fn)(unsigned long, void *), void *arg) |
| 26 | { | 26 | { |
| @@ -33,15 +33,15 @@ $(obj)/vdso.so.dbg: $(src)/vdso.lds $(obj-vdso) FORCE · 32 unmodified lines | |||
| 33 | $(call if_changed,vdsold) | 33 | $(call if_changed,vdsold) |
| 34 | 34 | ||
| 35 | # We also create a special relocatable object that should mirror the symbol | 35 | # We also create a special relocatable object that should mirror the symbol |
| 36 | # table and layout of the linked DSO. With ld -R we can then refer to | 36 | # table and layout of the linked DSO. With ld --just-symbols we can then |
| 37 | # these symbols in the kernel code rather than hand-coded addresses. | 37 | # refer to these symbols in the kernel code rather than hand-coded addresses. |
| 38 | 38 | ||
| 39 | SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ | 39 | SYSCFLAGS_vdso.so.dbg = -shared -s -Wl,-soname=linux-vdso.so.1 \ |
| 40 | -Wl,--build-id -Wl,--hash-style=both | 40 | -Wl,--build-id -Wl,--hash-style=both |
| 41 | $(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE | 41 | $(obj)/vdso-dummy.o: $(src)/vdso.lds $(obj)/rt_sigreturn.o FORCE |
| 42 | $(call if_changed,vdsold) | 42 | $(call if_changed,vdsold) |
| 43 | 43 | ||
| 44 | LDFLAGS_vdso-syms.o := -r -R | 44 | LDFLAGS_vdso-syms.o := -r --just-symbols |
| 45 | $(obj)/vdso-syms.o: $(obj)/vdso-dummy.o FORCE | 45 | $(obj)/vdso-syms.o: $(obj)/vdso-dummy.o FORCE |
| 46 | $(call if_changed,ld) | 46 | $(call if_changed,ld) |
| 47 | 47 | ||
| @@ -64,10 +64,13 @@ mm_segment_t enable_sacf_uaccess(void) · 63 unmodified lines | |||
| 64 | { | 64 | { |
| 65 | mm_segment_t old_fs; | 65 | mm_segment_t old_fs; |
| 66 | unsigned long asce, cr; | 66 | unsigned long asce, cr; |
| 67 | unsigned long flags; | ||
| 67 | 68 | ||
| 68 | old_fs = current->thread.mm_segment; | 69 | old_fs = current->thread.mm_segment; |
| 69 | if (old_fs & 1) | 70 | if (old_fs & 1) |
| 70 | return old_fs; | 71 | return old_fs; |
| 72 | /* protect against a concurrent page table upgrade */ | ||
| 73 | local_irq_save(flags); | ||
| 71 | current->thread.mm_segment |= 1; | 74 | current->thread.mm_segment |= 1; |
| 72 | asce = S390_lowcore.kernel_asce; | 75 | asce = S390_lowcore.kernel_asce; |
| 73 | if (likely(old_fs == USER_DS)) { | 76 | if (likely(old_fs == USER_DS)) { |
| @@ -83,6 +86,7 @@ mm_segment_t enable_sacf_uaccess(void) · 9 unmodified lines | |||
| 83 | __ctl_load(asce, 7, 7); | 86 | __ctl_load(asce, 7, 7); |
| 84 | set_cpu_flag(CIF_ASCE_SECONDARY); | 87 | set_cpu_flag(CIF_ASCE_SECONDARY); |
| 85 | } | 88 | } |
| 89 | local_irq_restore(flags); | ||
| 86 | return old_fs; | 90 | return old_fs; |
| 87 | } | 91 | } |
| 88 | EXPORT_SYMBOL(enable_sacf_uaccess); | 92 | EXPORT_SYMBOL(enable_sacf_uaccess); |
| @@ -70,8 +70,20 @@ static void __crst_table_upgrade(void *arg) · 69 unmodified lines | |||
| 70 | { | 70 | { |
| 71 | struct mm_struct *mm = arg; | 71 | struct mm_struct *mm = arg; |
| 72 | 72 | ||
| 73 | if (current->active_mm == mm) | 73 | /* we must change all active ASCEs to avoid the creation of new TLBs */ |
| 74 | set_user_asce(mm); | 74 | if (current->active_mm == mm) { |
| 75 | S390_lowcore.user_asce = mm->context.asce; | ||
| 76 | if (current->thread.mm_segment == USER_DS) { | ||
| 77 | __ctl_load(S390_lowcore.user_asce, 1, 1); | ||
| 78 | /* Mark user-ASCE present in CR1 */ | ||
| 79 | clear_cpu_flag(CIF_ASCE_PRIMARY); | ||
| 80 | } | ||
| 81 | if (current->thread.mm_segment == USER_DS_SACF) { | ||
| 82 | __ctl_load(S390_lowcore.user_asce, 7, 7); | ||
| 83 | /* enable_sacf_uaccess does all or nothing */ | ||
| 84 | WARN_ON(!test_cpu_flag(CIF_ASCE_SECONDARY)); | ||
| 85 | } | ||
| 86 | } | ||
| 75 | __tlb_flush_local(); | 87 | __tlb_flush_local(); |
| 76 | } | 88 | } |
| 77 | 89 | ||
| @@ -73,7 +73,8 @@ static int hv_cpu_init(unsigned int cpu) · 72 unmodified lines | |||
| 73 | struct page *pg; | 73 | struct page *pg; |
| 74 | 74 | ||
| 75 | input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); | 75 | input_arg = (void **)this_cpu_ptr(hyperv_pcpu_input_arg); |
| 76 | pg = alloc_page(GFP_KERNEL); | 76 | /* hv_cpu_init() can be called with IRQs disabled from hv_resume() */ |
| 77 | pg = alloc_page(irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL); | ||
| 77 | if (unlikely(!pg)) | 78 | if (unlikely(!pg)) |
| 78 | return -ENOMEM; | 79 | return -ENOMEM; |
| 79 | *input_arg = page_address(pg); | 80 | *input_arg = page_address(pg); |
| @@ -254,6 +255,7 @@ static int __init hv_pci_init(void) · 174 unmodified lines | |||
| 254 | static int hv_suspend(void) | 255 | static int hv_suspend(void) |
| 255 | { | 256 | { |
| 256 | union hv_x64_msr_hypercall_contents hypercall_msr; | 257 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 258 | int ret; | ||
| 257 | 259 | ||
| 258 | /* | 260 | /* |
| 259 | * Reset the hypercall page as it is going to be invalidated | 261 | * Reset the hypercall page as it is going to be invalidated |
| @@ -270,12 +272,17 @@ static int hv_suspend(void) · 10 unmodified lines | |||
| 270 | hypercall_msr.enable = 0; | 272 | hypercall_msr.enable = 0; |
| 271 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); | 273 | wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| 272 | 274 | ||
| 273 | return 0; | 275 | ret = hv_cpu_die(0); |
| 276 | return ret; | ||
| 274 | } | 277 | } |
| 275 | 278 | ||
| 276 | static void hv_resume(void) | 279 | static void hv_resume(void) |
| 277 | { | 280 | { |
| 278 | union hv_x64_msr_hypercall_contents hypercall_msr; | 281 | union hv_x64_msr_hypercall_contents hypercall_msr; |
| 282 | int ret; | ||
| 283 | |||
| 284 | ret = hv_cpu_init(0); | ||
| 285 | WARN_ON(ret); | ||
| 279 | 286 | ||
| 280 | /* Re-enable the hypercall page */ | 287 | /* Re-enable the hypercall page */ |
| 281 | rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); | 288 | rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); |
| @@ -288,6 +295,7 @@ static void hv_resume(void) · 6 unmodified lines | |||
| 288 | hv_hypercall_pg_saved = NULL; | 295 | hv_hypercall_pg_saved = NULL; |
| 289 | } | 296 | } |
| 290 | 297 | ||
| 298 | /* Note: when the ops are called, only CPU0 is online and IRQs are disabled. */ | ||
| 291 | static struct syscore_ops hv_syscore_ops = { | 299 | static struct syscore_ops hv_syscore_ops = { |
| 292 | .suspend = hv_suspend, | 300 | .suspend = hv_suspend, |
| 293 | .resume = hv_resume, | 301 | .resume = hv_resume, |
| @@ -35,6 +35,8 @@ typedef int (*hyperv_fill_flush_list_func)( · 34 unmodified lines | |||
| 35 | rdmsrl(HV_X64_MSR_SINT0 + int_num, val) | 35 | rdmsrl(HV_X64_MSR_SINT0 + int_num, val) |
| 36 | #define hv_set_synint_state(int_num, val) \ | 36 | #define hv_set_synint_state(int_num, val) \ |
| 37 | wrmsrl(HV_X64_MSR_SINT0 + int_num, val) | 37 | wrmsrl(HV_X64_MSR_SINT0 + int_num, val) |
| 38 | #define hv_recommend_using_aeoi() \ | ||
| 39 | (!(ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED)) | ||
| 38 | 40 | ||
| 39 | #define hv_get_crash_ctl(val) \ | 41 | #define hv_get_crash_ctl(val) \ |
| 40 | rdmsrl(HV_X64_MSR_CRASH_CTL, val) | 42 | rdmsrl(HV_X64_MSR_CRASH_CTL, val) |
| @@ -496,7 +496,7 @@ int blk_drop_partitions(struct gendisk *disk, struct block_device *bdev) · 495 unmodified lines | |||
| 496 | 496 | ||
| 497 | if (!disk_part_scan_enabled(disk)) | 497 | if (!disk_part_scan_enabled(disk)) |
| 498 | return 0; | 498 | return 0; |
| 499 | if (bdev->bd_part_count || bdev->bd_openers > 1) | 499 | if (bdev->bd_part_count) |
| 500 | return -EBUSY; | 500 | return -EBUSY; |
| 501 | res = invalidate_partition(disk, 0); | 501 | res = invalidate_partition(disk, 0); |
| 502 | if (res) | 502 | if (res) |
| @@ -273,13 +273,13 @@ int acpi_device_set_power(struct acpi_device *device, int state) · 272 unmodified lines | |||
| 273 | end: | 273 | end: |
| 274 | if (result) { | 274 | if (result) { |
| 275 | dev_warn(&device->dev, "Failed to change power state to %s\n", | 275 | dev_warn(&device->dev, "Failed to change power state to %s\n", |
| 276 | acpi_power_state_string(state)); | 276 | acpi_power_state_string(target_state)); |
| 277 | } else { | 277 | } else { |
| 278 | device->power.state = target_state; | 278 | device->power.state = target_state; |
| 279 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 279 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
| 280 | "Device [%s] transitioned to %s\n", | 280 | "Device [%s] transitioned to %s\n", |
| 281 | device->pnp.bus_id, | 281 | device->pnp.bus_id, |
| 282 | acpi_power_state_string(state))); | 282 | acpi_power_state_string(target_state))); |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | return result; | 285 | return result; |
| @@ -1059,7 +1059,7 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b, · 1058 unmodified lines | |||
| 1059 | 1059 | ||
| 1060 | update_turbo_state(); | 1060 | update_turbo_state(); |
| 1061 | if (global.turbo_disabled) { | 1061 | if (global.turbo_disabled) { |
| 1062 | pr_warn("Turbo disabled by BIOS or unavailable on processor\n"); | 1062 | pr_notice_once("Turbo disabled by BIOS or unavailable on processor\n"); |
| 1063 | mutex_unlock(&intel_pstate_limits_lock); | 1063 | mutex_unlock(&intel_pstate_limits_lock); |
| 1064 | mutex_unlock(&intel_pstate_driver_lock); | 1064 | mutex_unlock(&intel_pstate_driver_lock); |
| 1065 | return -EPERM; | 1065 | return -EPERM; |
| @@ -963,10 +963,12 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 962 unmodified lines | |||
| 963 | struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); | 963 | struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); |
| 964 | struct aead_edesc *edesc; | 964 | struct aead_edesc *edesc; |
| 965 | int ecode = 0; | 965 | int ecode = 0; |
| 966 | bool has_bklog; | ||
| 966 | 967 | ||
| 967 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); | 968 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 968 | 969 | ||
| 969 | edesc = rctx->edesc; | 970 | edesc = rctx->edesc; |
| 971 | has_bklog = edesc->bklog; | ||
| 970 | 972 | ||
| 971 | if (err) | 973 | if (err) |
| 972 | ecode = caam_jr_strstatus(jrdev, err); | 974 | ecode = caam_jr_strstatus(jrdev, err); |
| @@ -979,7 +981,7 @@ static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 6 unmodified lines | |||
| 979 | * If no backlog flag, the completion of the request is done | 981 | * If no backlog flag, the completion of the request is done |
| 980 | * by CAAM, not crypto engine. | 982 | * by CAAM, not crypto engine. |
| 981 | */ | 983 | */ |
| 982 | if (!edesc->bklog) | 984 | if (!has_bklog) |
| 983 | aead_request_complete(req, ecode); | 985 | aead_request_complete(req, ecode); |
| 984 | else | 986 | else |
| 985 | crypto_finalize_aead_request(jrp->engine, req, ecode); | 987 | crypto_finalize_aead_request(jrp->engine, req, ecode); |
| @@ -995,10 +997,12 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 9 unmodified lines | |||
| 995 | struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); | 997 | struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev); |
| 996 | int ivsize = crypto_skcipher_ivsize(skcipher); | 998 | int ivsize = crypto_skcipher_ivsize(skcipher); |
| 997 | int ecode = 0; | 999 | int ecode = 0; |
| 1000 | bool has_bklog; | ||
| 998 | 1001 | ||
| 999 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); | 1002 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 1000 | 1003 | ||
| 1001 | edesc = rctx->edesc; | 1004 | edesc = rctx->edesc; |
| 1005 | has_bklog = edesc->bklog; | ||
| 1002 | if (err) | 1006 | if (err) |
| 1003 | ecode = caam_jr_strstatus(jrdev, err); | 1007 | ecode = caam_jr_strstatus(jrdev, err); |
| 1004 | 1008 | ||
| @@ -1028,7 +1032,7 @@ static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err, · 23 unmodified lines | |||
| 1028 | * If no backlog flag, the completion of the request is done | 1032 | * If no backlog flag, the completion of the request is done |
| 1029 | * by CAAM, not crypto engine. | 1033 | * by CAAM, not crypto engine. |
| 1030 | */ | 1034 | */ |
| 1031 | if (!edesc->bklog) | 1035 | if (!has_bklog) |
| 1032 | skcipher_request_complete(req, ecode); | 1036 | skcipher_request_complete(req, ecode); |
| 1033 | else | 1037 | else |
| 1034 | crypto_finalize_skcipher_request(jrp->engine, req, ecode); | 1038 | crypto_finalize_skcipher_request(jrp->engine, req, ecode); |
| @@ -1711,7 +1715,7 @@ static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req, · 676 unmodified lines | |||
| 1711 | 1715 | ||
| 1712 | if (ivsize || mapped_dst_nents > 1) | 1716 | if (ivsize || mapped_dst_nents > 1) |
| 1713 | sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx + | 1717 | sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx + |
| 1714 | mapped_dst_nents); | 1718 | mapped_dst_nents - 1 + !!ivsize); |
| 1715 | 1719 | ||
| 1716 | if (sec4_sg_bytes) { | 1720 | if (sec4_sg_bytes) { |
| 1717 | edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, | 1721 | edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg, |
| @@ -583,10 +583,12 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err, · 582 unmodified lines | |||
| 583 | struct caam_hash_state *state = ahash_request_ctx(req); | 583 | struct caam_hash_state *state = ahash_request_ctx(req); |
| 584 | struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); | 584 | struct caam_hash_ctx *ctx = crypto_ahash_ctx(ahash); |
| 585 | int ecode = 0; | 585 | int ecode = 0; |
| 586 | bool has_bklog; | ||
| 586 | 587 | ||
| 587 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); | 588 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 588 | 589 | ||
| 589 | edesc = state->edesc; | 590 | edesc = state->edesc; |
| 591 | has_bklog = edesc->bklog; | ||
| 590 | 592 | ||
| 591 | if (err) | 593 | if (err) |
| 592 | ecode = caam_jr_strstatus(jrdev, err); | 594 | ecode = caam_jr_strstatus(jrdev, err); |
| @@ -603,7 +605,7 @@ static inline void ahash_done_cpy(struct device *jrdev, u32 *desc, u32 err, · 10 unmodified lines | |||
| 603 | * If no backlog flag, the completion of the request is done | 605 | * If no backlog flag, the completion of the request is done |
| 604 | * by CAAM, not crypto engine. | 606 | * by CAAM, not crypto engine. |
| 605 | */ | 607 | */ |
| 606 | if (!edesc->bklog) | 608 | if (!has_bklog) |
| 607 | req->base.complete(&req->base, ecode); | 609 | req->base.complete(&req->base, ecode); |
| 608 | else | 610 | else |
| 609 | crypto_finalize_hash_request(jrp->engine, req, ecode); | 611 | crypto_finalize_hash_request(jrp->engine, req, ecode); |
| @@ -632,10 +634,12 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err, · 22 unmodified lines | |||
| 632 | struct caam_hash_state *state = ahash_request_ctx(req); | 634 | struct caam_hash_state *state = ahash_request_ctx(req); |
| 633 | int digestsize = crypto_ahash_digestsize(ahash); | 635 | int digestsize = crypto_ahash_digestsize(ahash); |
| 634 | int ecode = 0; | 636 | int ecode = 0; |
| 637 | bool has_bklog; | ||
| 635 | 638 | ||
| 636 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); | 639 | dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err); |
| 637 | 640 | ||
| 638 | edesc = state->edesc; | 641 | edesc = state->edesc; |
| 642 | has_bklog = edesc->bklog; | ||
| 639 | if (err) | 643 | if (err) |
| 640 | ecode = caam_jr_strstatus(jrdev, err); | 644 | ecode = caam_jr_strstatus(jrdev, err); |
| 641 | 645 | ||
| @@ -663,7 +667,7 @@ static inline void ahash_done_switch(struct device *jrdev, u32 *desc, u32 err, · 21 unmodified lines | |||
| 663 | * If no backlog flag, the completion of the request is done | 667 | * If no backlog flag, the completion of the request is done |
| 664 | * by CAAM, not crypto engine. | 668 | * by CAAM, not crypto engine. |
| 665 | */ | 669 | */ |
| 666 | if (!edesc->bklog) | 670 | if (!has_bklog) |
| 667 | req->base.complete(&req->base, ecode); | 671 | req->base.complete(&req->base, ecode); |
| 668 | else | 672 | else |
| 669 | crypto_finalize_hash_request(jrp->engine, req, ecode); | 673 | crypto_finalize_hash_request(jrp->engine, req, ecode); |
| @@ -121,11 +121,13 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context) · 120 unmodified lines | |||
| 121 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); | 121 | struct caam_drv_private_jr *jrp = dev_get_drvdata(dev); |
| 122 | struct rsa_edesc *edesc; | 122 | struct rsa_edesc *edesc; |
| 123 | int ecode = 0; | 123 | int ecode = 0; |
| 124 | bool has_bklog; | ||
| 124 | 125 | ||
| 125 | if (err) | 126 | if (err) |
| 126 | ecode = caam_jr_strstatus(dev, err); | 127 | ecode = caam_jr_strstatus(dev, err); |
| 127 | 128 | ||
| 128 | edesc = req_ctx->edesc; | 129 | edesc = req_ctx->edesc; |
| 130 | has_bklog = edesc->bklog; | ||
| 129 | 131 | ||
| 130 | rsa_pub_unmap(dev, edesc, req); | 132 | rsa_pub_unmap(dev, edesc, req); |
| 131 | rsa_io_unmap(dev, edesc, req); | 133 | rsa_io_unmap(dev, edesc, req); |
| @@ -135,7 +137,7 @@ static void rsa_pub_done(struct device *dev, u32 *desc, u32 err, void *context) · 3 unmodified lines | |||
| 135 | * If no backlog flag, the completion of the request is done | 137 | * If no backlog flag, the completion of the request is done |
| 136 | * by CAAM, not crypto engine. | 138 | * by CAAM, not crypto engine. |
| 137 | */ | 139 | */ |
| 138 | if (!edesc->bklog) | 140 | if (!has_bklog) |
| 139 | akcipher_request_complete(req, ecode); | 141 | akcipher_request_complete(req, ecode); |
| 140 | else | 142 | else |
| 141 | crypto_finalize_akcipher_request(jrp->engine, req, ecode); | 143 | crypto_finalize_akcipher_request(jrp->engine, req, ecode); |
| @@ -152,11 +154,13 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err, · 10 unmodified lines | |||
| 152 | struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); | 154 | struct caam_rsa_req_ctx *req_ctx = akcipher_request_ctx(req); |
| 153 | struct rsa_edesc *edesc; | 155 | struct rsa_edesc *edesc; |
| 154 | int ecode = 0; | 156 | int ecode = 0; |
| 157 | bool has_bklog; | ||
| 155 | 158 | ||
| 156 | if (err) | 159 | if (err) |
| 157 | ecode = caam_jr_strstatus(dev, err); | 160 | ecode = caam_jr_strstatus(dev, err); |
| 158 | 161 | ||
| 159 | edesc = req_ctx->edesc; | 162 | edesc = req_ctx->edesc; |
| 163 | has_bklog = edesc->bklog; | ||
| 160 | 164 | ||
| 161 | switch (key->priv_form) { | 165 | switch (key->priv_form) { |
| 162 | case FORM1: | 166 | case FORM1: |
| @@ -176,7 +180,7 @@ static void rsa_priv_f_done(struct device *dev, u32 *desc, u32 err, · 13 unmodified lines | |||
| 176 | * If no backlog flag, the completion of the request is done | 180 | * If no backlog flag, the completion of the request is done |
| 177 | * by CAAM, not crypto engine. | 181 | * by CAAM, not crypto engine. |
| 178 | */ | 182 | */ |
| 179 | if (!edesc->bklog) | 183 | if (!has_bklog) |
| 180 | akcipher_request_complete(req, ecode); | 184 | akcipher_request_complete(req, ecode); |
| 181 | else | 185 | else |
| 182 | crypto_finalize_akcipher_request(jrp->engine, req, ecode); | 186 | crypto_finalize_akcipher_request(jrp->engine, req, ecode); |
| @@ -388,7 +388,8 @@ static long dma_buf_ioctl(struct file *file, · 387 unmodified lines | |||
| 388 | 388 | ||
| 389 | return ret; | 389 | return ret; |
| 390 | 390 | ||
| 391 | case DMA_BUF_SET_NAME: | 391 | case DMA_BUF_SET_NAME_A: |
| 392 | case DMA_BUF_SET_NAME_B: | ||
| 392 | return dma_buf_set_name(dmabuf, (const char __user *)arg); | 393 | return dma_buf_set_name(dmabuf, (const char __user *)arg); |
| 393 | 394 | ||
| 394 | default: | 395 | default: |
| @@ -655,8 +656,8 @@ EXPORT_SYMBOL_GPL(dma_buf_put); · 260 unmodified lines | |||
| 655 | * calls attach() of dma_buf_ops to allow device-specific attach functionality | 656 | * calls attach() of dma_buf_ops to allow device-specific attach functionality |
| 656 | * @dmabuf: [in] buffer to attach device to. | 657 | * @dmabuf: [in] buffer to attach device to. |
| 657 | * @dev: [in] device to be attached. | 658 | * @dev: [in] device to be attached. |
| 658 | * @importer_ops [in] importer operations for the attachment | 659 | * @importer_ops: [in] importer operations for the attachment |
| 659 | * @importer_priv [in] importer private pointer for the attachment | 660 | * @importer_priv: [in] importer private pointer for the attachment |
| 660 | * | 661 | * |
| 661 | * Returns struct dma_buf_attachment pointer for this attachment. Attachments | 662 | * Returns struct dma_buf_attachment pointer for this attachment. Attachments |
| 662 | * must be cleaned up by calling dma_buf_detach(). | 663 | * must be cleaned up by calling dma_buf_detach(). |
| @@ -241,7 +241,8 @@ config FSL_RAID · 240 unmodified lines | |||
| 241 | 241 | ||
| 242 | config HISI_DMA | 242 | config HISI_DMA |
| 243 | tristate "HiSilicon DMA Engine support" | 243 | tristate "HiSilicon DMA Engine support" |
| 244 | depends on ARM64 || (COMPILE_TEST && PCI_MSI) | 244 | depends on ARM64 || COMPILE_TEST |
| 245 | depends on PCI_MSI | ||
| 245 | select DMA_ENGINE | 246 | select DMA_ENGINE |
| 246 | select DMA_VIRTUAL_CHANNELS | 247 | select DMA_VIRTUAL_CHANNELS |
| 247 | help | 248 | help |
| @@ -232,10 +232,6 @@ static void chan_dev_release(struct device *dev) · 231 unmodified lines | |||
| 232 | struct dma_chan_dev *chan_dev; | 232 | struct dma_chan_dev *chan_dev; |
| 233 | 233 | ||
| 234 | chan_dev = container_of(dev, typeof(*chan_dev), device); | 234 | chan_dev = container_of(dev, typeof(*chan_dev), device); |
| 235 | if (atomic_dec_and_test(chan_dev->idr_ref)) { | ||
| 236 | ida_free(&dma_ida, chan_dev->dev_id); | ||
| 237 | kfree(chan_dev->idr_ref); | ||
| 238 | } | ||
| 239 | kfree(chan_dev); | 235 | kfree(chan_dev); |
| 240 | } | 236 | } |
| 241 | 237 | ||
| @@ -1043,27 +1039,9 @@ static int get_dma_id(struct dma_device *device) · 801 unmodified lines | |||
| 1043 | } | 1039 | } |
| 1044 | 1040 | ||
| 1045 | static int __dma_async_device_channel_register(struct dma_device *device, | 1041 | static int __dma_async_device_channel_register(struct dma_device *device, |
| 1046 | struct dma_chan *chan, | 1042 | struct dma_chan *chan) |
| 1047 | int chan_id) | ||
| 1048 | { | 1043 | { |
| 1049 | int rc = 0; | 1044 | int rc = 0; |
| 1050 | int chancnt = device->chancnt; | ||
| 1051 | atomic_t *idr_ref; | ||
| 1052 | struct dma_chan *tchan; | ||
| 1053 | |||
| 1054 | tchan = list_first_entry_or_null(&device->channels, | ||
| 1055 | struct dma_chan, device_node); | ||
| 1056 | if (!tchan) | ||
| 1057 | return -ENODEV; | ||
| 1058 | |||
| 1059 | if (tchan->dev) { | ||
| 1060 | idr_ref = tchan->dev->idr_ref; | ||
| 1061 | } else { | ||
| 1062 | idr_ref = kmalloc(sizeof(*idr_ref), GFP_KERNEL); | ||
| 1063 | if (!idr_ref) | ||
| 1064 | return -ENOMEM; | ||
| 1065 | atomic_set(idr_ref, 0); | ||
| 1066 | } | ||
| 1067 | 1045 | ||
| 1068 | chan->local = alloc_percpu(typeof(*chan->local)); | 1046 | chan->local = alloc_percpu(typeof(*chan->local)); |
| 1069 | if (!chan->local) | 1047 | if (!chan->local) |
| @@ -1079,29 +1057,36 @@ static int __dma_async_device_channel_register(struct dma_device *device, · 9 unmodified lines | |||
| 1079 | * When the chan_id is a negative value, we are dynamically adding | 1057 | * When the chan_id is a negative value, we are dynamically adding |
| 1080 | * the channel. Otherwise we are static enumerating. | 1058 | * the channel. Otherwise we are static enumerating. |
| 1081 | */ | 1059 | */ |
| 1082 | chan->chan_id = chan_id < 0 ? chancnt : chan_id; | 1060 | mutex_lock(&device->chan_mutex); |
| 1061 | chan->chan_id = ida_alloc(&device->chan_ida, GFP_KERNEL); | ||
| 1062 | mutex_unlock(&device->chan_mutex); | ||
| 1063 | if (chan->chan_id < 0) { | ||
| 1064 | pr_err("%s: unable to alloc ida for chan: %d\n", | ||
| 1065 | __func__, chan->chan_id); | ||
| 1066 | goto err_out; | ||
| 1067 | } | ||
| 1068 | |||
| 1083 | chan->dev->device.class = &dma_devclass; | 1069 | chan->dev->device.class = &dma_devclass; |
| 1084 | chan->dev->device.parent = device->dev; | 1070 | chan->dev->device.parent = device->dev; |
| 1085 | chan->dev->chan = chan; | 1071 | chan->dev->chan = chan; |
| 1086 | chan->dev->idr_ref = idr_ref; | ||
| 1087 | chan->dev->dev_id = device->dev_id; | 1072 | chan->dev->dev_id = device->dev_id; |
| 1088 | atomic_inc(idr_ref); | ||
| 1089 | dev_set_name(&chan->dev->device, "dma%dchan%d", | 1073 | dev_set_name(&chan->dev->device, "dma%dchan%d", |
| 1090 | device->dev_id, chan->chan_id); | 1074 | device->dev_id, chan->chan_id); |
| 1091 | |||
| 1092 | rc = device_register(&chan->dev->device); | 1075 | rc = device_register(&chan->dev->device); |
| 1093 | if (rc) | 1076 | if (rc) |
| 1094 | goto err_out; | 1077 | goto err_out_ida; |
| 1095 | chan->client_count = 0; | 1078 | chan->client_count = 0; |
| 1096 | device->chancnt = chan->chan_id + 1; | 1079 | device->chancnt++; |
| 1097 | 1080 | ||
| 1098 | return 0; | 1081 | return 0; |
| 1099 | 1082 | ||
| 1083 | err_out_ida: | ||
| 1084 | mutex_lock(&device->chan_mutex); | ||
| 1085 | ida_free(&device->chan_ida, chan->chan_id); | ||
| 1086 | mutex_unlock(&device->chan_mutex); | ||
| 1100 | err_out: | 1087 | err_out: |
| 1101 | free_percpu(chan->local); | 1088 | free_percpu(chan->local); |
| 1102 | kfree(chan->dev); | 1089 | kfree(chan->dev); |
| 1103 | if (atomic_dec_return(idr_ref) == 0) | ||
| 1104 | kfree(idr_ref); | ||
| 1105 | return rc; | 1090 | return rc; |
| 1106 | } | 1091 | } |
| 1107 | 1092 | ||
| @@ -1110,7 +1095,7 @@ int dma_async_device_channel_register(struct dma_device *device, · 2 unmodified lines | |||
| 1110 | { | 1095 | { |
| 1111 | int rc; | 1096 | int rc; |
| 1112 | 1097 | ||
| 1113 | rc = __dma_async_device_channel_register(device, chan, -1); | 1098 | rc = __dma_async_device_channel_register(device, chan); |
| 1114 | if (rc < 0) | 1099 | if (rc < 0) |
| 1115 | return rc; | 1100 | return rc; |
| 1116 | 1101 | ||
| @@ -1130,6 +1115,9 @@ static void __dma_async_device_channel_unregister(struct dma_device *device, · 13 unmodified lines | |||
| 1130 | device->chancnt--; | 1115 | device->chancnt--; |
| 1131 | chan->dev->chan = NULL; | 1116 | chan->dev->chan = NULL; |
| 1132 | mutex_unlock(&dma_list_mutex); | 1117 | mutex_unlock(&dma_list_mutex); |
| 1118 | mutex_lock(&device->chan_mutex); | ||
| 1119 | ida_free(&device->chan_ida, chan->chan_id); | ||
| 1120 | mutex_unlock(&device->chan_mutex); | ||
| 1133 | device_unregister(&chan->dev->device); | 1121 | device_unregister(&chan->dev->device); |
| 1134 | free_percpu(chan->local); | 1122 | free_percpu(chan->local); |
| 1135 | } | 1123 | } |
| @@ -1152,7 +1140,7 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_unregister); · 16 unmodified lines | |||
| 1152 | */ | 1140 | */ |
| 1153 | int dma_async_device_register(struct dma_device *device) | 1141 | int dma_async_device_register(struct dma_device *device) |
| 1154 | { | 1142 | { |
| 1155 | int rc, i = 0; | 1143 | int rc; |
| 1156 | struct dma_chan* chan; | 1144 | struct dma_chan* chan; |
| 1157 | 1145 | ||
| 1158 | if (!device) | 1146 | if (!device) |
| @@ -1257,9 +1245,12 @@ int dma_async_device_register(struct dma_device *device) · 98 unmodified lines | |||
| 1257 | if (rc != 0) | 1245 | if (rc != 0) |
| 1258 | return rc; | 1246 | return rc; |
| 1259 | 1247 | ||
| 1248 | mutex_init(&device->chan_mutex); | ||
| 1249 | ida_init(&device->chan_ida); | ||
| 1250 | |||
| 1260 | /* represent channels in sysfs. Probably want devs too */ | 1251 | /* represent channels in sysfs. Probably want devs too */ |
| 1261 | list_for_each_entry(chan, &device->channels, device_node) { | 1252 | list_for_each_entry(chan, &device->channels, device_node) { |
| 1262 | rc = __dma_async_device_channel_register(device, chan, i++); | 1253 | rc = __dma_async_device_channel_register(device, chan); |
| 1263 | if (rc < 0) | 1254 | if (rc < 0) |
| 1264 | goto err_out; | 1255 | goto err_out; |
| 1265 | } | 1256 | } |
| @@ -1334,6 +1325,7 @@ void dma_async_device_unregister(struct dma_device *device) · 68 unmodified lines | |||
| 1334 | */ | 1325 | */ |
| 1335 | dma_cap_set(DMA_PRIVATE, device->cap_mask); | 1326 | dma_cap_set(DMA_PRIVATE, device->cap_mask); |
| 1336 | dma_channel_rebalance(); | 1327 | dma_channel_rebalance(); |
| 1328 | ida_free(&dma_ida, device->dev_id); | ||
| 1337 | dma_device_put(device); | 1329 | dma_device_put(device); |
| 1338 | mutex_unlock(&dma_list_mutex); | 1330 | mutex_unlock(&dma_list_mutex); |
| 1339 | } | 1331 | } |
| @@ -240,7 +240,7 @@ static bool is_threaded_test_run(struct dmatest_info *info) · 239 unmodified lines | |||
| 240 | struct dmatest_thread *thread; | 240 | struct dmatest_thread *thread; |
| 241 | 241 | ||
| 242 | list_for_each_entry(thread, &dtc->threads, node) { | 242 | list_for_each_entry(thread, &dtc->threads, node) { |
| 243 | if (!thread->done) | 243 | if (!thread->done && !thread->pending) |
| 244 | return true; | 244 | return true; |
| 245 | } | 245 | } |
| 246 | } | 246 | } |
| @@ -662,8 +662,8 @@ static int dmatest_func(void *data) · 415 unmodified lines | |||
| 662 | flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; | 662 | flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; |
| 663 | 663 | ||
| 664 | ktime = ktime_get(); | 664 | ktime = ktime_get(); |
| 665 | while (!kthread_should_stop() | 665 | while (!(kthread_should_stop() || |
| 666 | && !(params->iterations && total_tests >= params->iterations)) { | 666 | (params->iterations && total_tests >= params->iterations))) { |
| 667 | struct dma_async_tx_descriptor *tx = NULL; | 667 | struct dma_async_tx_descriptor *tx = NULL; |
| 668 | struct dmaengine_unmap_data *um; | 668 | struct dmaengine_unmap_data *um; |
| 669 | dma_addr_t *dsts; | 669 | dma_addr_t *dsts; |
| @@ -363,6 +363,8 @@ static void mmp_tdma_free_descriptor(struct mmp_tdma_chan *tdmac) · 362 unmodified lines | |||
| 363 | gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, | 363 | gen_pool_free(gpool, (unsigned long)tdmac->desc_arr, |
| 364 | size); | 364 | size); |
| 365 | tdmac->desc_arr = NULL; | 365 | tdmac->desc_arr = NULL; |
| 366 | if (tdmac->status == DMA_ERROR) | ||
| 367 | tdmac->status = DMA_COMPLETE; | ||
| 366 | 368 | ||
| 367 | return; | 369 | return; |
| 368 | } | 370 | } |
| @@ -443,7 +445,8 @@ static struct dma_async_tx_descriptor *mmp_tdma_prep_dma_cyclic( · 74 unmodified lines | |||
| 443 | if (!desc) | 445 | if (!desc) |
| 444 | goto err_out; | 446 | goto err_out; |
| 445 | 447 | ||
| 446 | mmp_tdma_config_write(chan, direction, &tdmac->slave_config); | 448 | if (mmp_tdma_config_write(chan, direction, &tdmac->slave_config)) |
| 449 | goto err_out; | ||
| 447 | 450 | ||
| 448 | while (buf < buf_len) { | 451 | while (buf < buf_len) { |
| 449 | desc = &tdmac->desc_arr[i]; | 452 | desc = &tdmac->desc_arr[i]; |
| @@ -865,6 +865,7 @@ static int pch_dma_probe(struct pci_dev *pdev, · 864 unmodified lines | |||
| 865 | } | 865 | } |
| 866 | 866 | ||
| 867 | pci_set_master(pdev); | 867 | pci_set_master(pdev); |
| 868 | pd->dma.dev = &pdev->dev; | ||
| 868 | 869 | ||
| 869 | err = request_irq(pdev->irq, pd_irq, IRQF_SHARED, DRV_NAME, pd); | 870 | err = request_irq(pdev->irq, pd_irq, IRQF_SHARED, DRV_NAME, pd); |
| 870 | if (err) { | 871 | if (err) { |
| @@ -880,7 +881,6 @@ static int pch_dma_probe(struct pci_dev *pdev, · 9 unmodified lines | |||
| 880 | goto err_free_irq; | 881 | goto err_free_irq; |
| 881 | } | 882 | } |
| 882 | 883 | ||
| 883 | pd->dma.dev = &pdev->dev; | ||
| 884 | 884 | ||
| 885 | INIT_LIST_HEAD(&pd->dma.channels); | 885 | INIT_LIST_HEAD(&pd->dma.channels); |
| 886 | 886 | ||
| @@ -816,6 +816,13 @@ static bool tegra_dma_eoc_interrupt_deasserted(struct tegra_dma_channel *tdc) · 815 unmodified lines | |||
| 816 | static void tegra_dma_synchronize(struct dma_chan *dc) | 816 | static void tegra_dma_synchronize(struct dma_chan *dc) |
| 817 | { | 817 | { |
| 818 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); | 818 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
| 819 | int err; | ||
| 820 | |||
| 821 | err = pm_runtime_get_sync(tdc->tdma->dev); | ||
| 822 | if (err < 0) { | ||
| 823 | dev_err(tdc2dev(tdc), "Failed to synchronize DMA: %d\n", err); | ||
| 824 | return; | ||
| 825 | } | ||
| 819 | 826 | ||
| 820 | /* | 827 | /* |
| 821 | * CPU, which handles interrupt, could be busy in | 828 | * CPU, which handles interrupt, could be busy in |
| @@ -825,6 +832,8 @@ static void tegra_dma_synchronize(struct dma_chan *dc) · 3 unmodified lines | |||
| 825 | wait_event(tdc->wq, tegra_dma_eoc_interrupt_deasserted(tdc)); | 832 | wait_event(tdc->wq, tegra_dma_eoc_interrupt_deasserted(tdc)); |
| 826 | 833 | ||
| 827 | tasklet_kill(&tdc->tasklet); | 834 | tasklet_kill(&tdc->tasklet); |
| 835 | |||
| 836 | pm_runtime_put(tdc->tdma->dev); | ||
| 828 | } | 837 | } |
| 829 | 838 | ||
| 830 | static unsigned int tegra_dma_sg_bytes_xferred(struct tegra_dma_channel *tdc, | 839 | static unsigned int tegra_dma_sg_bytes_xferred(struct tegra_dma_channel *tdc, |
| @@ -27,6 +27,7 @@ struct psil_endpoint_config *psil_get_ep_config(u32 thread_id) · 26 unmodified lines | |||
| 27 | soc_ep_map = &j721e_ep_map; | 27 | soc_ep_map = &j721e_ep_map; |
| 28 | } else { | 28 | } else { |
| 29 | pr_err("PSIL: No compatible machine found for map\n"); | 29 | pr_err("PSIL: No compatible machine found for map\n"); |
| 30 | mutex_unlock(&ep_map_mutex); | ||
| 30 | return ERR_PTR(-ENOTSUPP); | 31 | return ERR_PTR(-ENOTSUPP); |
| 31 | } | 32 | } |
| 32 | pr_debug("%s: Using map for %s\n", __func__, soc_ep_map->name); | 33 | pr_debug("%s: Using map for %s\n", __func__, soc_ep_map->name); |
| @@ -1230,16 +1230,16 @@ static enum dma_status xilinx_dma_tx_status(struct dma_chan *dchan, · 1229 unmodified lines | |||
| 1230 | return ret; | 1230 | return ret; |
| 1231 | 1231 | ||
| 1232 | spin_lock_irqsave(&chan->lock, flags); | 1232 | spin_lock_irqsave(&chan->lock, flags); |
| 1233 | 1233 | if (!list_empty(&chan->active_list)) { | |
| 1234 | desc = list_last_entry(&chan->active_list, | 1234 | desc = list_last_entry(&chan->active_list, |
| 1235 | struct xilinx_dma_tx_descriptor, node); | 1235 | struct xilinx_dma_tx_descriptor, node); |
| 1236 | /* | 1236 | /* |
| 1237 | * VDMA and simple mode do not support residue reporting, so the | 1237 | * VDMA and simple mode do not support residue reporting, so the |
| 1238 | * residue field will always be 0. | 1238 | * residue field will always be 0. |
| 1239 | */ | 1239 | */ |
| 1240 | if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA) | 1240 | if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA) |
| 1241 | residue = xilinx_dma_get_residue(chan, desc); | 1241 | residue = xilinx_dma_get_residue(chan, desc); |
| 1242 | 1242 | } | |
| 1243 | spin_unlock_irqrestore(&chan->lock, flags); | 1243 | spin_unlock_irqrestore(&chan->lock, flags); |
| 1244 | 1244 | ||
| 1245 | dma_set_residue(txstate, residue); | 1245 | dma_set_residue(txstate, residue); |
| @@ -85,9 +85,10 @@ · 84 unmodified lines | |||
| 85 | * - 3.34.0 - Non-DC can flip correctly between buffers with different pitches | 85 | * - 3.34.0 - Non-DC can flip correctly between buffers with different pitches |
| 86 | * - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask | 86 | * - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask |
| 87 | * - 3.36.0 - Allow reading more status registers on si/cik | 87 | * - 3.36.0 - Allow reading more status registers on si/cik |
| 88 | * - 3.37.0 - L2 is invalidated before SDMA IBs, needed for correctness | ||
| 88 | */ | 89 | */ |
| 89 | #define KMS_DRIVER_MAJOR 3 | 90 | #define KMS_DRIVER_MAJOR 3 |
| 90 | #define KMS_DRIVER_MINOR 36 | 91 | #define KMS_DRIVER_MINOR 37 |
| 91 | #define KMS_DRIVER_PATCHLEVEL 0 | 92 | #define KMS_DRIVER_PATCHLEVEL 0 |
| 92 | 93 | ||
| 93 | int amdgpu_vram_limit = 0; | 94 | int amdgpu_vram_limit = 0; |
| @@ -73,6 +73,22 @@ · 72 unmodified lines | |||
| 73 | #define SDMA_OP_AQL_COPY 0 | 73 | #define SDMA_OP_AQL_COPY 0 |
| 74 | #define SDMA_OP_AQL_BARRIER_OR 0 | 74 | #define SDMA_OP_AQL_BARRIER_OR 0 |
| 75 | 75 | ||
| 76 | #define SDMA_GCR_RANGE_IS_PA (1 << 18) | ||
| 77 | #define SDMA_GCR_SEQ(x) (((x) & 0x3) << 16) | ||
| 78 | #define SDMA_GCR_GL2_WB (1 << 15) | ||
| 79 | #define SDMA_GCR_GL2_INV (1 << 14) | ||
| 80 | #define SDMA_GCR_GL2_DISCARD (1 << 13) | ||
| 81 | #define SDMA_GCR_GL2_RANGE(x) (((x) & 0x3) << 11) | ||
| 82 | #define SDMA_GCR_GL2_US (1 << 10) | ||
| 83 | #define SDMA_GCR_GL1_INV (1 << 9) | ||
| 84 | #define SDMA_GCR_GLV_INV (1 << 8) | ||
| 85 | #define SDMA_GCR_GLK_INV (1 << 7) | ||
| 86 | #define SDMA_GCR_GLK_WB (1 << 6) | ||
| 87 | #define SDMA_GCR_GLM_INV (1 << 5) | ||
| 88 | #define SDMA_GCR_GLM_WB (1 << 4) | ||
| 89 | #define SDMA_GCR_GL1_RANGE(x) (((x) & 0x3) << 2) | ||
| 90 | #define SDMA_GCR_GLI_INV(x) (((x) & 0x3) << 0) | ||
| 91 | |||
| 76 | /*define for op field*/ | 92 | /*define for op field*/ |
| 77 | #define SDMA_PKT_HEADER_op_offset 0 | 93 | #define SDMA_PKT_HEADER_op_offset 0 |
| 78 | #define SDMA_PKT_HEADER_op_mask 0x000000FF | 94 | #define SDMA_PKT_HEADER_op_mask 0x000000FF |
| @@ -382,6 +382,18 @@ static void sdma_v5_0_ring_emit_ib(struct amdgpu_ring *ring, · 381 unmodified lines | |||
| 382 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); | 382 | unsigned vmid = AMDGPU_JOB_GET_VMID(job); |
| 383 | uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid); | 383 | uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid); |
| 384 | 384 | ||
| 385 | /* Invalidate L2, because if we don't do it, we might get stale cache | ||
| 386 | * lines from previous IBs. | ||
| 387 | */ | ||
| 388 | amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_GCR_REQ)); | ||
| 389 | amdgpu_ring_write(ring, 0); | ||
| 390 | amdgpu_ring_write(ring, (SDMA_GCR_GL2_INV | | ||
| 391 | SDMA_GCR_GL2_WB | | ||
| 392 | SDMA_GCR_GLM_INV | | ||
| 393 | SDMA_GCR_GLM_WB) << 16); | ||
| 394 | amdgpu_ring_write(ring, 0xffffff80); | ||
| 395 | amdgpu_ring_write(ring, 0xffff); | ||
| 396 | |||
| 385 | /* An IB packet must end on a 8 DW boundary--the next dword | 397 | /* An IB packet must end on a 8 DW boundary--the next dword |
| 386 | * must be on a 8-dword boundary. Our IB packet below is 6 | 398 | * must be on a 8-dword boundary. Our IB packet below is 6 |
| 387 | * dwords long, thus add x number of NOPs, such that, in | 399 | * dwords long, thus add x number of NOPs, such that, in |
| @@ -1595,7 +1607,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = { · 1207 unmodified lines | |||
| 1595 | SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + | 1607 | SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 + |
| 1596 | SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 + | 1608 | SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 + |
| 1597 | 10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */ | 1609 | 10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */ |
| 1598 | .emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */ | 1610 | .emit_ib_size = 5 + 7 + 6, /* sdma_v5_0_ring_emit_ib */ |
| 1599 | .emit_ib = sdma_v5_0_ring_emit_ib, | 1611 | .emit_ib = sdma_v5_0_ring_emit_ib, |
| 1600 | .emit_fence = sdma_v5_0_ring_emit_fence, | 1612 | .emit_fence = sdma_v5_0_ring_emit_fence, |
| 1601 | .emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync, | 1613 | .emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync, |
| @@ -3340,7 +3340,8 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev, · 3339 unmodified lines | |||
| 3340 | const union dc_tiling_info *tiling_info, | 3340 | const union dc_tiling_info *tiling_info, |
| 3341 | const uint64_t info, | 3341 | const uint64_t info, |
| 3342 | struct dc_plane_dcc_param *dcc, | 3342 | struct dc_plane_dcc_param *dcc, |
| 3343 | struct dc_plane_address *address) | 3343 | struct dc_plane_address *address, |
| 3344 | bool force_disable_dcc) | ||
| 3344 | { | 3345 | { |
| 3345 | struct dc *dc = adev->dm.dc; | 3346 | struct dc *dc = adev->dm.dc; |
| 3346 | struct dc_dcc_surface_param input; | 3347 | struct dc_dcc_surface_param input; |
| @@ -3352,6 +3353,9 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev, · 5 unmodified lines | |||
| 3352 | memset(&input, 0, sizeof(input)); | 3353 | memset(&input, 0, sizeof(input)); |
| 3353 | memset(&output, 0, sizeof(output)); | 3354 | memset(&output, 0, sizeof(output)); |
| 3354 | 3355 | ||
| 3356 | if (force_disable_dcc) | ||
| 3357 | return 0; | ||
| 3358 | |||
| 3355 | if (!offset) | 3359 | if (!offset) |
| 3356 | return 0; | 3360 | return 0; |
| 3357 | 3361 | ||
| @@ -3401,7 +3405,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 43 unmodified lines | |||
| 3401 | union dc_tiling_info *tiling_info, | 3405 | union dc_tiling_info *tiling_info, |
| 3402 | struct plane_size *plane_size, | 3406 | struct plane_size *plane_size, |
| 3403 | struct dc_plane_dcc_param *dcc, | 3407 | struct dc_plane_dcc_param *dcc, |
| 3404 | struct dc_plane_address *address) | 3408 | struct dc_plane_address *address, |
| 3409 | bool force_disable_dcc) | ||
| 3405 | { | 3410 | { |
| 3406 | const struct drm_framebuffer *fb = &afb->base; | 3411 | const struct drm_framebuffer *fb = &afb->base; |
| 3407 | int ret; | 3412 | int ret; |
| @@ -3507,7 +3512,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev, · 99 unmodified lines | |||
| 3507 | 3512 | ||
| 3508 | ret = fill_plane_dcc_attributes(adev, afb, format, rotation, | 3513 | ret = fill_plane_dcc_attributes(adev, afb, format, rotation, |
| 3509 | plane_size, tiling_info, | 3514 | plane_size, tiling_info, |
| 3510 | tiling_flags, dcc, address); | 3515 | tiling_flags, dcc, address, |
| 3516 | force_disable_dcc); | ||
| 3511 | if (ret) | 3517 | if (ret) |
| 3512 | return ret; | 3518 | return ret; |
| 3513 | } | 3519 | } |
| @@ -3599,7 +3605,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, · 85 unmodified lines | |||
| 3599 | const struct drm_plane_state *plane_state, | 3605 | const struct drm_plane_state *plane_state, |
| 3600 | const uint64_t tiling_flags, | 3606 | const uint64_t tiling_flags, |
| 3601 | struct dc_plane_info *plane_info, | 3607 | struct dc_plane_info *plane_info, |
| 3602 | struct dc_plane_address *address) | 3608 | struct dc_plane_address *address, |
| 3609 | bool force_disable_dcc) | ||
| 3603 | { | 3610 | { |
| 3604 | const struct drm_framebuffer *fb = plane_state->fb; | 3611 | const struct drm_framebuffer *fb = plane_state->fb; |
| 3605 | const struct amdgpu_framebuffer *afb = | 3612 | const struct amdgpu_framebuffer *afb = |
| @@ -3681,7 +3688,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev, · 75 unmodified lines | |||
| 3681 | plane_info->rotation, tiling_flags, | 3688 | plane_info->rotation, tiling_flags, |
| 3682 | &plane_info->tiling_info, | 3689 | &plane_info->tiling_info, |
| 3683 | &plane_info->plane_size, | 3690 | &plane_info->plane_size, |
| 3684 | &plane_info->dcc, address); | 3691 | &plane_info->dcc, address, |
| 3692 | force_disable_dcc); | ||
| 3685 | if (ret) | 3693 | if (ret) |
| 3686 | return ret; | 3694 | return ret; |
| 3687 | 3695 | ||
| @@ -3704,6 +3712,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 16 unmodified lines | |||
| 3704 | struct dc_plane_info plane_info; | 3712 | struct dc_plane_info plane_info; |
| 3705 | uint64_t tiling_flags; | 3713 | uint64_t tiling_flags; |
| 3706 | int ret; | 3714 | int ret; |
| 3715 | bool force_disable_dcc = false; | ||
| 3707 | 3716 | ||
| 3708 | ret = fill_dc_scaling_info(plane_state, &scaling_info); | 3717 | ret = fill_dc_scaling_info(plane_state, &scaling_info); |
| 3709 | if (ret) | 3718 | if (ret) |
| @@ -3718,9 +3727,11 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev, · 8 unmodified lines | |||
| 3718 | if (ret) | 3727 | if (ret) |
| 3719 | return ret; | 3728 | return ret; |
| 3720 | 3729 | ||
| 3730 | force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; | ||
| 3721 | ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags, | 3731 | ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags, |
| 3722 | &plane_info, | 3732 | &plane_info, |
| 3723 | &dc_plane_state->address); | 3733 | &dc_plane_state->address, |
| 3734 | force_disable_dcc); | ||
| 3724 | if (ret) | 3735 | if (ret) |
| 3725 | return ret; | 3736 | return ret; |
| 3726 | 3737 | ||
| @@ -5342,6 +5353,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, · 1615 unmodified lines | |||
| 5342 | uint64_t tiling_flags; | 5353 | uint64_t tiling_flags; |
| 5343 | uint32_t domain; | 5354 | uint32_t domain; |
| 5344 | int r; | 5355 | int r; |
| 5356 | bool force_disable_dcc = false; | ||
| 5345 | 5357 | ||
| 5346 | dm_plane_state_old = to_dm_plane_state(plane->state); | 5358 | dm_plane_state_old = to_dm_plane_state(plane->state); |
| 5347 | dm_plane_state_new = to_dm_plane_state(new_state); | 5359 | dm_plane_state_new = to_dm_plane_state(new_state); |
| @@ -5400,11 +5412,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, · 52 unmodified lines | |||
| 5400 | dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { | 5412 | dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { |
| 5401 | struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; | 5413 | struct dc_plane_state *plane_state = dm_plane_state_new->dc_state; |
| 5402 | 5414 | ||
| 5415 | force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend; | ||
| 5403 | fill_plane_buffer_attributes( | 5416 | fill_plane_buffer_attributes( |
| 5404 | adev, afb, plane_state->format, plane_state->rotation, | 5417 | adev, afb, plane_state->format, plane_state->rotation, |
| 5405 | tiling_flags, &plane_state->tiling_info, | 5418 | tiling_flags, &plane_state->tiling_info, |
| 5406 | &plane_state->plane_size, &plane_state->dcc, | 5419 | &plane_state->plane_size, &plane_state->dcc, |
| 5407 | &plane_state->address); | 5420 | &plane_state->address, |
| 5421 | force_disable_dcc); | ||
| 5408 | } | 5422 | } |
| 5409 | 5423 | ||
| 5410 | return 0; | 5424 | return 0; |
| @@ -6676,7 +6690,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 1265 unmodified lines | |||
| 6676 | fill_dc_plane_info_and_addr( | 6690 | fill_dc_plane_info_and_addr( |
| 6677 | dm->adev, new_plane_state, tiling_flags, | 6691 | dm->adev, new_plane_state, tiling_flags, |
| 6678 | &bundle->plane_infos[planes_count], | 6692 | &bundle->plane_infos[planes_count], |
| 6679 | &bundle->flip_addrs[planes_count].address); | 6693 | &bundle->flip_addrs[planes_count].address, |
| 6694 | false); | ||
| 6695 | |||
| 6696 | DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n", | ||
| 6697 | new_plane_state->plane->index, | ||
| 6698 | bundle->plane_infos[planes_count].dcc.enable); | ||
| 6680 | 6699 | ||
| 6681 | bundle->surface_updates[planes_count].plane_info = | 6700 | bundle->surface_updates[planes_count].plane_info = |
| 6682 | &bundle->plane_infos[planes_count]; | 6701 | &bundle->plane_infos[planes_count]; |
| @@ -8096,7 +8115,8 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm, · 1413 unmodified lines | |||
| 8096 | ret = fill_dc_plane_info_and_addr( | 8115 | ret = fill_dc_plane_info_and_addr( |
| 8097 | dm->adev, new_plane_state, tiling_flags, | 8116 | dm->adev, new_plane_state, tiling_flags, |
| 8098 | plane_info, | 8117 | plane_info, |
| 8099 | &flip_addr->address); | 8118 | &flip_addr->address, |
| 8119 | false); | ||
| 8100 | if (ret) | 8120 | if (ret) |
| 8101 | goto cleanup; | 8121 | goto cleanup; |
| 8102 | 8122 | ||
| @@ -2908,6 +2908,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd · 2907 unmodified lines | |||
| 2908 | sizeof(hpd_irq_dpcd_data), | 2908 | sizeof(hpd_irq_dpcd_data), |
| 2909 | "Status: "); | 2909 | "Status: "); |
| 2910 | 2910 | ||
| 2911 | for (i = 0; i < MAX_PIPES; i++) { | ||
| 2912 | pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; | ||
| 2913 | if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) | ||
| 2914 | link->dc->hwss.blank_stream(pipe_ctx); | ||
| 2915 | } | ||
| 2916 | |||
| 2911 | for (i = 0; i < MAX_PIPES; i++) { | 2917 | for (i = 0; i < MAX_PIPES; i++) { |
| 2912 | pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; | 2918 | pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; |
| 2913 | if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) | 2919 | if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) |
| @@ -2927,6 +2933,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd · 13 unmodified lines | |||
| 2927 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) | 2933 | if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) |
| 2928 | dc_link_reallocate_mst_payload(link); | 2934 | dc_link_reallocate_mst_payload(link); |
| 2929 | 2935 | ||
| 2936 | for (i = 0; i < MAX_PIPES; i++) { | ||
| 2937 | pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i]; | ||
| 2938 | if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link) | ||
| 2939 | link->dc->hwss.unblank_stream(pipe_ctx, &previous_link_settings); | ||
| 2940 | } | ||
| 2941 | |||
| 2930 | status = false; | 2942 | status = false; |
| 2931 | if (out_link_loss) | 2943 | if (out_link_loss) |
| 2932 | *out_link_loss = true; | 2944 | *out_link_loss = true; |
| @@ -4227,6 +4239,21 @@ void dp_set_fec_enable(struct dc_link *link, bool enable) · 1294 unmodified lines | |||
| 4227 | void dpcd_set_source_specific_data(struct dc_link *link) | 4239 | void dpcd_set_source_specific_data(struct dc_link *link) |
| 4228 | { | 4240 | { |
| 4229 | const uint32_t post_oui_delay = 30; // 30ms | 4241 | const uint32_t post_oui_delay = 30; // 30ms |
| 4242 | uint8_t dspc = 0; | ||
| 4243 | enum dc_status ret = DC_ERROR_UNEXPECTED; | ||
| 4244 | |||
| 4245 | ret = core_link_read_dpcd(link, DP_DOWN_STREAM_PORT_COUNT, &dspc, | ||
| 4246 | sizeof(dspc)); | ||
| 4247 | |||
| 4248 | if (ret != DC_OK) { | ||
| 4249 | DC_LOG_ERROR("Error in DP aux read transaction," | ||
| 4250 | " not writing source specific data\n"); | ||
| 4251 | return; | ||
| 4252 | } | ||
| 4253 | |||
| 4254 | /* Return if OUI unsupported */ | ||
| 4255 | if (!(dspc & DP_OUI_SUPPORT)) | ||
| 4256 | return; | ||
| 4230 | 4257 | ||
| 4231 | if (!link->dc->vendor_signature.is_valid) { | 4258 | if (!link->dc->vendor_signature.is_valid) { |
| 4232 | struct dpcd_amd_signature amd_signature; | 4259 | struct dpcd_amd_signature amd_signature; |
| @@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status( · 230 unmodified lines | |||
| 231 | return dc_stream_get_status_from_state(dc->current_state, stream); | 231 | return dc_stream_get_status_from_state(dc->current_state, stream); |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc) | ||
| 235 | { | ||
| 236 | #if defined(CONFIG_DRM_AMD_DC_DCN) | ||
| 237 | unsigned int vupdate_line; | ||
| 238 | unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos; | ||
| 239 | struct dc_stream_state *stream = pipe_ctx->stream; | ||
| 240 | unsigned int us_per_line; | ||
| 241 | |||
| 242 | if (stream->ctx->asic_id.chip_family == FAMILY_RV && | ||
| 243 | ASICREV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) { | ||
| 244 | |||
| 245 | vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx); | ||
| 246 | if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos)) | ||
| 247 | return; | ||
| 248 | |||
| 249 | if (vpos >= vupdate_line) | ||
| 250 | return; | ||
| 251 | |||
| 252 | us_per_line = stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz; | ||
| 253 | lines_to_vupdate = vupdate_line - vpos; | ||
| 254 | us_to_vupdate = lines_to_vupdate * us_per_line; | ||
| 255 | |||
| 256 | /* 70 us is a conservative estimate of cursor update time*/ | ||
| 257 | if (us_to_vupdate < 70) | ||
| 258 | udelay(us_to_vupdate); | ||
| 259 | } | ||
| 260 | #endif | ||
| 261 | } | ||
| 262 | 234 | ||
| 263 | /** | 235 | /** |
| 264 | * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address | 236 | * dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address |
| @@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes( · 33 unmodified lines | |||
| 298 | 270 | ||
| 299 | if (!pipe_to_program) { | 271 | if (!pipe_to_program) { |
| 300 | pipe_to_program = pipe_ctx; | 272 | pipe_to_program = pipe_ctx; |
| 301 | 273 | dc->hwss.cursor_lock(dc, pipe_to_program, true); | |
| 302 | delay_cursor_until_vupdate(pipe_ctx, dc); | ||
| 303 | dc->hwss.pipe_control_lock(dc, pipe_to_program, true); | ||
| 304 | } | 274 | } |
| 305 | 275 | ||
| 306 | dc->hwss.set_cursor_attribute(pipe_ctx); | 276 | dc->hwss.set_cursor_attribute(pipe_ctx); |
| @@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes( · 2 unmodified lines | |||
| 309 | } | 279 | } |
| 310 | 280 | ||
| 311 | if (pipe_to_program) | 281 | if (pipe_to_program) |
| 312 | dc->hwss.pipe_control_lock(dc, pipe_to_program, false); | 282 | dc->hwss.cursor_lock(dc, pipe_to_program, false); |
| 313 | 283 | ||
| 314 | return true; | 284 | return true; |
| 315 | } | 285 | } |
| @@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position( · 33 unmodified lines | |||
| 349 | 319 | ||
| 350 | if (!pipe_to_program) { | 320 | if (!pipe_to_program) { |
| 351 | pipe_to_program = pipe_ctx; | 321 | pipe_to_program = pipe_ctx; |
| 352 | 322 | dc->hwss.cursor_lock(dc, pipe_to_program, true); | |
| 353 | delay_cursor_until_vupdate(pipe_ctx, dc); | ||
| 354 | dc->hwss.pipe_control_lock(dc, pipe_to_program, true); | ||
| 355 | } | 323 | } |
| 356 | 324 | ||
| 357 | dc->hwss.set_cursor_position(pipe_ctx); | 325 | dc->hwss.set_cursor_position(pipe_ctx); |
| 358 | } | 326 | } |
| 359 | 327 | ||
| 360 | if (pipe_to_program) | 328 | if (pipe_to_program) |
| 361 | dc->hwss.pipe_control_lock(dc, pipe_to_program, false); | 329 | dc->hwss.cursor_lock(dc, pipe_to_program, false); |
| 362 | 330 | ||
| 363 | return true; | 331 | return true; |
| 364 | } | 332 | } |
| @@ -2757,6 +2757,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { · 2756 unmodified lines | |||
| 2757 | .disable_plane = dce110_power_down_fe, | 2757 | .disable_plane = dce110_power_down_fe, |
| 2758 | .pipe_control_lock = dce_pipe_control_lock, | 2758 | .pipe_control_lock = dce_pipe_control_lock, |
| 2759 | .interdependent_update_lock = NULL, | 2759 | .interdependent_update_lock = NULL, |
| 2760 | .cursor_lock = dce_pipe_control_lock, | ||
| 2760 | .prepare_bandwidth = dce110_prepare_bandwidth, | 2761 | .prepare_bandwidth = dce110_prepare_bandwidth, |
| 2761 | .optimize_bandwidth = dce110_optimize_bandwidth, | 2762 | .optimize_bandwidth = dce110_optimize_bandwidth, |
| 2762 | .set_drr = set_drr, | 2763 | .set_drr = set_drr, |
| @@ -1625,6 +1625,16 @@ void dcn10_pipe_control_lock( · 1624 unmodified lines | |||
| 1625 | hws->funcs.verify_allow_pstate_change_high(dc); | 1625 | hws->funcs.verify_allow_pstate_change_high(dc); |
| 1626 | } | 1626 | } |
| 1627 | 1627 | ||
| 1628 | void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock) | ||
| 1629 | { | ||
| 1630 | /* cursor lock is per MPCC tree, so only need to lock one pipe per stream */ | ||
| 1631 | if (!pipe || pipe->top_pipe) | ||
| 1632 | return; | ||
| 1633 | |||
| 1634 | dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc, | ||
| 1635 | pipe->stream_res.opp->inst, lock); | ||
| 1636 | } | ||
| 1637 | |||
| 1628 | static bool wait_for_reset_trigger_to_occur( | 1638 | static bool wait_for_reset_trigger_to_occur( |
| 1629 | struct dc_context *dc_ctx, | 1639 | struct dc_context *dc_ctx, |
| 1630 | struct timing_generator *tg) | 1640 | struct timing_generator *tg) |
| @@ -49,6 +49,7 @@ void dcn10_pipe_control_lock( · 48 unmodified lines | |||
| 49 | struct dc *dc, | 49 | struct dc *dc, |
| 50 | struct pipe_ctx *pipe, | 50 | struct pipe_ctx *pipe, |
| 51 | bool lock); | 51 | bool lock); |
| 52 | void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock); | ||
| 52 | void dcn10_blank_pixel_data( | 53 | void dcn10_blank_pixel_data( |
| 53 | struct dc *dc, | 54 | struct dc *dc, |
| 54 | struct pipe_ctx *pipe_ctx, | 55 | struct pipe_ctx *pipe_ctx, |
| @@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { · 49 unmodified lines | |||
| 50 | .disable_audio_stream = dce110_disable_audio_stream, | 50 | .disable_audio_stream = dce110_disable_audio_stream, |
| 51 | .disable_plane = dcn10_disable_plane, | 51 | .disable_plane = dcn10_disable_plane, |
| 52 | .pipe_control_lock = dcn10_pipe_control_lock, | 52 | .pipe_control_lock = dcn10_pipe_control_lock, |
| 53 | .cursor_lock = dcn10_cursor_lock, | ||
| 53 | .interdependent_update_lock = dcn10_lock_all_pipes, | 54 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 54 | .prepare_bandwidth = dcn10_prepare_bandwidth, | 55 | .prepare_bandwidth = dcn10_prepare_bandwidth, |
| 55 | .optimize_bandwidth = dcn10_optimize_bandwidth, | 56 | .optimize_bandwidth = dcn10_optimize_bandwidth, |
| @@ -223,6 +223,9 @@ struct mpcc *mpc1_insert_plane( · 222 unmodified lines | |||
| 223 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id); | 223 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id); |
| 224 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id); | 224 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id); |
| 225 | 225 | ||
| 226 | /* Configure VUPDATE lock set for this MPCC to map to the OPP */ | ||
| 227 | REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id); | ||
| 228 | |||
| 226 | /* update mpc tree mux setting */ | 229 | /* update mpc tree mux setting */ |
| 227 | if (tree->opp_list == insert_above_mpcc) { | 230 | if (tree->opp_list == insert_above_mpcc) { |
| 228 | /* insert the toppest mpcc */ | 231 | /* insert the toppest mpcc */ |
| @@ -318,6 +321,7 @@ void mpc1_remove_mpcc( · 89 unmodified lines | |||
| 318 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); | 321 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 319 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); | 322 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 320 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); | 323 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 324 | REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | ||
| 321 | 325 | ||
| 322 | /* mark this mpcc as not in use */ | 326 | /* mark this mpcc as not in use */ |
| 323 | mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); | 327 | mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id); |
| @@ -328,6 +332,7 @@ void mpc1_remove_mpcc( · 4 unmodified lines | |||
| 328 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); | 332 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 329 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); | 333 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 330 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); | 334 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 335 | REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | ||
| 331 | } | 336 | } |
| 332 | } | 337 | } |
| 333 | 338 | ||
| @@ -361,6 +366,7 @@ void mpc1_mpc_init(struct mpc *mpc) · 27 unmodified lines | |||
| 361 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); | 366 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 362 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); | 367 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 363 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); | 368 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 369 | REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | ||
| 364 | 370 | ||
| 365 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); | 371 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); |
| 366 | } | 372 | } |
| @@ -381,6 +387,7 @@ void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id) · 14 unmodified lines | |||
| 381 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); | 387 | REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf); |
| 382 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); | 388 | REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf); |
| 383 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); | 389 | REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf); |
| 390 | REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf); | ||
| 384 | 391 | ||
| 385 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); | 392 | mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id); |
| 386 | 393 | ||
| @@ -453,6 +460,13 @@ void mpc1_read_mpcc_state( · 66 unmodified lines | |||
| 453 | MPCC_BUSY, &s->busy); | 460 | MPCC_BUSY, &s->busy); |
| 454 | } | 461 | } |
| 455 | 462 | ||
| 463 | void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock) | ||
| 464 | { | ||
| 465 | struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc); | ||
| 466 | |||
| 467 | REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0); | ||
| 468 | } | ||
| 469 | |||
| 456 | static const struct mpc_funcs dcn10_mpc_funcs = { | 470 | static const struct mpc_funcs dcn10_mpc_funcs = { |
| 457 | .read_mpcc_state = mpc1_read_mpcc_state, | 471 | .read_mpcc_state = mpc1_read_mpcc_state, |
| 458 | .insert_plane = mpc1_insert_plane, | 472 | .insert_plane = mpc1_insert_plane, |
| @@ -464,6 +478,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = { · 5 unmodified lines | |||
| 464 | .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect, | 478 | .assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect, |
| 465 | .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, | 479 | .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw, |
| 466 | .update_blending = mpc1_update_blending, | 480 | .update_blending = mpc1_update_blending, |
| 481 | .cursor_lock = mpc1_cursor_lock, | ||
| 467 | .set_denorm = NULL, | 482 | .set_denorm = NULL, |
| 468 | .set_denorm_clamp = NULL, | 483 | .set_denorm_clamp = NULL, |
| 469 | .set_output_csc = NULL, | 484 | .set_output_csc = NULL, |
| @@ -39,11 +39,12 @@ · 38 unmodified lines | |||
| 39 | SRII(MPCC_BG_G_Y, MPCC, inst),\ | 39 | SRII(MPCC_BG_G_Y, MPCC, inst),\ |
| 40 | SRII(MPCC_BG_R_CR, MPCC, inst),\ | 40 | SRII(MPCC_BG_R_CR, MPCC, inst),\ |
| 41 | SRII(MPCC_BG_B_CB, MPCC, inst),\ | 41 | SRII(MPCC_BG_B_CB, MPCC, inst),\ |
| 42 | SRII(MPCC_BG_B_CB, MPCC, inst),\ | 42 | SRII(MPCC_SM_CONTROL, MPCC, inst),\ |
| 43 | SRII(MPCC_SM_CONTROL, MPCC, inst) | 43 | SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst) |
| 44 | 44 | ||
| 45 | #define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \ | 45 | #define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \ |
| 46 | SRII(MUX, MPC_OUT, inst) | 46 | SRII(MUX, MPC_OUT, inst),\ |
| 47 | VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst) | ||
| 47 | 48 | ||
| 48 | #define MPC_COMMON_REG_VARIABLE_LIST \ | 49 | #define MPC_COMMON_REG_VARIABLE_LIST \ |
| 49 | uint32_t MPCC_TOP_SEL[MAX_MPCC]; \ | 50 | uint32_t MPCC_TOP_SEL[MAX_MPCC]; \ |
| @@ -55,7 +56,9 @@ · 5 unmodified lines | |||
| 55 | uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ | 56 | uint32_t MPCC_BG_R_CR[MAX_MPCC]; \ |
| 56 | uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ | 57 | uint32_t MPCC_BG_B_CB[MAX_MPCC]; \ |
| 57 | uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \ | 58 | uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \ |
| 58 | uint32_t MUX[MAX_OPP]; | 59 | uint32_t MUX[MAX_OPP]; \ |
| 60 | uint32_t MPCC_UPDATE_LOCK_SEL[MAX_MPCC]; \ | ||
| 61 | uint32_t CUR[MAX_OPP]; | ||
| 59 | 62 | ||
| 60 | #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ | 63 | #define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\ |
| 61 | SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ | 64 | SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\ |
| @@ -78,7 +81,8 @@ · 16 unmodified lines | |||
| 78 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\ | 81 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\ |
| 79 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\ | 82 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\ |
| 80 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\ | 83 | SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\ |
| 81 | SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh) | 84 | SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\ |
| 85 | SF(MPCC0_MPCC_UPDATE_LOCK_SEL, MPCC_UPDATE_LOCK_SEL, mask_sh) | ||
| 82 | 86 | ||
| 83 | #define MPC_REG_FIELD_LIST(type) \ | 87 | #define MPC_REG_FIELD_LIST(type) \ |
| 84 | type MPCC_TOP_SEL;\ | 88 | type MPCC_TOP_SEL;\ |
| @@ -101,7 +105,9 @@ · 16 unmodified lines | |||
| 101 | type MPCC_SM_FIELD_ALT;\ | 105 | type MPCC_SM_FIELD_ALT;\ |
| 102 | type MPCC_SM_FORCE_NEXT_FRAME_POL;\ | 106 | type MPCC_SM_FORCE_NEXT_FRAME_POL;\ |
| 103 | type MPCC_SM_FORCE_NEXT_TOP_POL;\ | 107 | type MPCC_SM_FORCE_NEXT_TOP_POL;\ |
| 104 | type MPC_OUT_MUX; | 108 | type MPC_OUT_MUX;\ |
| 109 | type MPCC_UPDATE_LOCK_SEL;\ | ||
| 110 | type CUR_VUPDATE_LOCK_SET; | ||
| 105 | 111 | ||
| 106 | struct dcn_mpc_registers { | 112 | struct dcn_mpc_registers { |
| 107 | MPC_COMMON_REG_VARIABLE_LIST | 113 | MPC_COMMON_REG_VARIABLE_LIST |
| @@ -192,4 +198,6 @@ void mpc1_read_mpcc_state( · 84 unmodified lines | |||
| 192 | int mpcc_inst, | 198 | int mpcc_inst, |
| 193 | struct mpcc_state *s); | 199 | struct mpcc_state *s); |
| 194 | 200 | ||
| 201 | void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock); | ||
| 202 | |||
| 195 | #endif | 203 | #endif |
| @@ -181,6 +181,14 @@ enum dcn10_clk_src_array_id { · 180 unmodified lines | |||
| 181 | .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ | 181 | .reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 182 | mm ## block ## id ## _ ## reg_name | 182 | mm ## block ## id ## _ ## reg_name |
| 183 | 183 | ||
| 184 | #define VUPDATE_SRII(reg_name, block, id)\ | ||
| 185 | .reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \ | ||
| 186 | mm ## reg_name ## 0 ## _ ## block ## id | ||
| 187 | |||
| 188 | /* set field/register/bitfield name */ | ||
| 189 | #define SFRB(field_name, reg_name, bitfield, post_fix)\ | ||
| 190 | .field_name = reg_name ## __ ## bitfield ## post_fix | ||
| 191 | |||
| 184 | /* NBIO */ | 192 | /* NBIO */ |
| 185 | #define NBIO_BASE_INNER(seg) \ | 193 | #define NBIO_BASE_INNER(seg) \ |
| 186 | NBIF_BASE__INST0_SEG ## seg | 194 | NBIF_BASE__INST0_SEG ## seg |
| @@ -419,11 +427,13 @@ static const struct dcn_mpc_registers mpc_regs = { · 232 unmodified lines | |||
| 419 | }; | 427 | }; |
| 420 | 428 | ||
| 421 | static const struct dcn_mpc_shift mpc_shift = { | 429 | static const struct dcn_mpc_shift mpc_shift = { |
| 422 | MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT) | 430 | MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\ |
| 431 | SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT) | ||
| 423 | }; | 432 | }; |
| 424 | 433 | ||
| 425 | static const struct dcn_mpc_mask mpc_mask = { | 434 | static const struct dcn_mpc_mask mpc_mask = { |
| 426 | MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK), | 435 | MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\ |
| 436 | SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK) | ||
| 427 | }; | 437 | }; |
| 428 | 438 | ||
| 429 | #define tg_regs(id)\ | 439 | #define tg_regs(id)\ |
| @@ -2294,7 +2294,8 @@ void dcn20_fpga_init_hw(struct dc *dc) · 2293 unmodified lines | |||
| 2294 | 2294 | ||
| 2295 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2); | 2295 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2); |
| 2296 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); | 2296 | REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1); |
| 2297 | REG_WRITE(REFCLK_CNTL, 0); | 2297 | if (REG(REFCLK_CNTL)) |
| 2298 | REG_WRITE(REFCLK_CNTL, 0); | ||
| 2298 | // | 2299 | // |
| 2299 | 2300 | ||
| 2300 | 2301 | ||
| @@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { · 51 unmodified lines | |||
| 52 | .disable_plane = dcn20_disable_plane, | 52 | .disable_plane = dcn20_disable_plane, |
| 53 | .pipe_control_lock = dcn20_pipe_control_lock, | 53 | .pipe_control_lock = dcn20_pipe_control_lock, |
| 54 | .interdependent_update_lock = dcn10_lock_all_pipes, | 54 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 55 | .cursor_lock = dcn10_cursor_lock, | ||
| 55 | .prepare_bandwidth = dcn20_prepare_bandwidth, | 56 | .prepare_bandwidth = dcn20_prepare_bandwidth, |
| 56 | .optimize_bandwidth = dcn20_optimize_bandwidth, | 57 | .optimize_bandwidth = dcn20_optimize_bandwidth, |
| 57 | .update_bandwidth = dcn20_update_bandwidth, | 58 | .update_bandwidth = dcn20_update_bandwidth, |
| @@ -545,6 +545,7 @@ const struct mpc_funcs dcn20_mpc_funcs = { · 544 unmodified lines | |||
| 545 | .mpc_init = mpc1_mpc_init, | 545 | .mpc_init = mpc1_mpc_init, |
| 546 | .mpc_init_single_inst = mpc1_mpc_init_single_inst, | 546 | .mpc_init_single_inst = mpc1_mpc_init_single_inst, |
| 547 | .update_blending = mpc2_update_blending, | 547 | .update_blending = mpc2_update_blending, |
| 548 | .cursor_lock = mpc1_cursor_lock, | ||
| 548 | .get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp, | 549 | .get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp, |
| 549 | .wait_for_idle = mpc2_assert_idle_mpcc, | 550 | .wait_for_idle = mpc2_assert_idle_mpcc, |
| 550 | .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, | 551 | .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect, |
| @@ -179,7 +179,8 @@ · 178 unmodified lines | |||
| 179 | SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\ | 179 | SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\ |
| 180 | SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\ | 180 | SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\ |
| 181 | SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\ | 181 | SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\ |
| 182 | SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh) | 182 | SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\ |
| 183 | SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh) | ||
| 183 | 184 | ||
| 184 | /* | 185 | /* |
| 185 | * DCN2 MPC_OCSC debug status register: | 186 | * DCN2 MPC_OCSC debug status register: |
| @@ -508,6 +508,10 @@ enum dcn20_clk_src_array_id { · 507 unmodified lines | |||
| 508 | .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ | 508 | .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 509 | mm ## block ## id ## _ ## reg_name | 509 | mm ## block ## id ## _ ## reg_name |
| 510 | 510 | ||
| 511 | #define VUPDATE_SRII(reg_name, block, id)\ | ||
| 512 | .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ | ||
| 513 | mm ## reg_name ## _ ## block ## id | ||
| 514 | |||
| 511 | /* NBIO */ | 515 | /* NBIO */ |
| 512 | #define NBIO_BASE_INNER(seg) \ | 516 | #define NBIO_BASE_INNER(seg) \ |
| 513 | NBIO_BASE__INST0_SEG ## seg | 517 | NBIO_BASE__INST0_SEG ## seg |
| @@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { · 52 unmodified lines | |||
| 53 | .disable_plane = dcn20_disable_plane, | 53 | .disable_plane = dcn20_disable_plane, |
| 54 | .pipe_control_lock = dcn20_pipe_control_lock, | 54 | .pipe_control_lock = dcn20_pipe_control_lock, |
| 55 | .interdependent_update_lock = dcn10_lock_all_pipes, | 55 | .interdependent_update_lock = dcn10_lock_all_pipes, |
| 56 | .cursor_lock = dcn10_cursor_lock, | ||
| 56 | .prepare_bandwidth = dcn20_prepare_bandwidth, | 57 | .prepare_bandwidth = dcn20_prepare_bandwidth, |
| 57 | .optimize_bandwidth = dcn20_optimize_bandwidth, | 58 | .optimize_bandwidth = dcn20_optimize_bandwidth, |
| 58 | .update_bandwidth = dcn20_update_bandwidth, | 59 | .update_bandwidth = dcn20_update_bandwidth, |
| @@ -284,7 +284,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 283 unmodified lines | |||
| 284 | .dram_channel_width_bytes = 4, | 284 | .dram_channel_width_bytes = 4, |
| 285 | .fabric_datapath_to_dcn_data_return_bytes = 32, | 285 | .fabric_datapath_to_dcn_data_return_bytes = 32, |
| 286 | .dcn_downspread_percent = 0.5, | 286 | .dcn_downspread_percent = 0.5, |
| 287 | .downspread_percent = 0.5, | 287 | .downspread_percent = 0.38, |
| 288 | .dram_page_open_time_ns = 50.0, | 288 | .dram_page_open_time_ns = 50.0, |
| 289 | .dram_rw_turnaround_time_ns = 17.5, | 289 | .dram_rw_turnaround_time_ns = 17.5, |
| 290 | .dram_return_buffer_per_channel_bytes = 8192, | 290 | .dram_return_buffer_per_channel_bytes = 8192, |
| @@ -340,6 +340,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = { · 49 unmodified lines | |||
| 340 | .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ | 340 | .block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \ |
| 341 | mm ## block ## id ## _ ## reg_name | 341 | mm ## block ## id ## _ ## reg_name |
| 342 | 342 | ||
| 343 | #define VUPDATE_SRII(reg_name, block, id)\ | ||
| 344 | .reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \ | ||
| 345 | mm ## reg_name ## _ ## block ## id | ||
| 346 | |||
| 343 | /* NBIO */ | 347 | /* NBIO */ |
| 344 | #define NBIO_BASE_INNER(seg) \ | 348 | #define NBIO_BASE_INNER(seg) \ |
| 345 | NBIF0_BASE__INST0_SEG ## seg | 349 | NBIF0_BASE__INST0_SEG ## seg |
| @@ -1374,64 +1378,49 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param · 1028 unmodified lines | |||
| 1374 | { | 1378 | { |
| 1375 | struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); | 1379 | struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool); |
| 1376 | struct clk_limit_table *clk_table = &bw_params->clk_table; | 1380 | struct clk_limit_table *clk_table = &bw_params->clk_table; |
| 1377 | unsigned int i, j, k; | 1381 | struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES]; |
| 1378 | int closest_clk_lvl; | 1382 | unsigned int i, j, closest_clk_lvl; |
| 1379 | 1383 | ||
| 1380 | // Default clock levels are used for diags, which may lead to overclocking. | 1384 | // Default clock levels are used for diags, which may lead to overclocking. |
| 1381 | if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) { | 1385 | if (!IS_DIAG_DC(dc->ctx->dce_environment)) { |
| 1382 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; | 1386 | dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator; |
| 1383 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; | 1387 | dcn2_1_ip.max_num_dpp = pool->base.pipe_count; |
| 1384 | dcn2_1_soc.num_chans = bw_params->num_channels; | 1388 | dcn2_1_soc.num_chans = bw_params->num_channels; |
| 1385 | 1389 | ||
| 1386 | /* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */ | 1390 | ASSERT(clk_table->num_entries); |
| 1387 | dcn2_1_soc.clock_limits[0].state = 0; | 1391 | for (i = 0; i < clk_table->num_entries; i++) { |
| 1388 | dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz; | 1392 | /* loop backwards*/ |
| 1389 | dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz; | 1393 | for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) { |
| 1390 | dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz; | ||
| 1391 | dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2; | ||
| 1392 | |||
| 1393 | /* | ||
| 1394 | * Other levels: find closest DCN clocks that fit the given clock limit using dcfclk | ||
| 1395 | * as indicator | ||
| 1396 | */ | ||
| 1397 | |||
| 1398 | closest_clk_lvl = -1; | ||
| 1399 | /* index currently being filled */ | ||
| 1400 | k = 1; | ||
| 1401 | for (i = 1; i < clk_table->num_entries; i++) { | ||
| 1402 | /* loop backwards, skip duplicate state*/ | ||
| 1403 | for (j = dcn2_1_soc.num_states - 1; j >= k; j--) { | ||
| 1404 | if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { | 1394 | if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) { |
| 1405 | closest_clk_lvl = j; | 1395 | closest_clk_lvl = j; |
| 1406 | break; | 1396 | break; |
| 1407 | } | 1397 | } |
| 1408 | } | 1398 | } |
| 1409 | 1399 | ||
| 1410 | /* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/ | 1400 | clock_limits[i].state = i; |
| 1411 | if (closest_clk_lvl != -1) { | 1401 | clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; |
| 1412 | dcn2_1_soc.clock_limits[k].state = i; | 1402 | clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz; |
| 1413 | dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz; | 1403 | clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz; |
| 1414 | dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz; | 1404 | clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; |
| 1415 | dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz; | 1405 | |
| 1416 | dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2; | 1406 | clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; |
| 1417 | 1407 | clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; | |
| 1418 | dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz; | 1408 | clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; |
| 1419 | dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz; | 1409 | clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; |
| 1420 | dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps; | 1410 | clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; |
| 1421 | dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz; | 1411 | clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; |
| 1422 | dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz; | 1412 | clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; |
| 1423 | dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz; | 1413 | } |
| 1424 | dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz; | 1414 | for (i = 0; i < clk_table->num_entries; i++) |
| 1425 | k++; | 1415 | dcn2_1_soc.clock_limits[i] = clock_limits[i]; |
| 1426 | } | 1416 | if (clk_table->num_entries) { |
| 1417 | dcn2_1_soc.num_states = clk_table->num_entries; | ||
| 1418 | /* duplicate last level */ | ||
| 1419 | dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; | ||
| 1420 | dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; | ||
| 1427 | } | 1421 | } |
| 1428 | dcn2_1_soc.num_states = k; | ||
| 1429 | } | 1422 | } |
| 1430 | 1423 | ||
| 1431 | /* duplicate last level */ | ||
| 1432 | dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1]; | ||
| 1433 | dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states; | ||
| 1434 | |||
| 1435 | dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); | 1424 | dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21); |
| 1436 | } | 1425 | } |
| 1437 | 1426 | ||
| @@ -210,6 +210,22 @@ struct mpc_funcs { · 209 unmodified lines | |||
| 210 | struct mpcc_blnd_cfg *blnd_cfg, | 210 | struct mpcc_blnd_cfg *blnd_cfg, |
| 211 | int mpcc_id); | 211 | int mpcc_id); |
| 212 | 212 | ||
| 213 | /* | ||
| 214 | * Lock cursor updates for the specified OPP. | ||
| 215 | * OPP defines the set of MPCC that are locked together for cursor. | ||
| 216 | * | ||
| 217 | * Parameters: | ||
| 218 | * [in] mpc - MPC context. | ||
| 219 | * [in] opp_id - The OPP to lock cursor updates on | ||
| 220 | * [in] lock - lock/unlock the OPP | ||
| 221 | * | ||
| 222 | * Return: void | ||
| 223 | */ | ||
| 224 | void (*cursor_lock)( | ||
| 225 | struct mpc *mpc, | ||
| 226 | int opp_id, | ||
| 227 | bool lock); | ||
| 228 | |||
| 213 | struct mpcc* (*get_mpcc_for_dpp)( | 229 | struct mpcc* (*get_mpcc_for_dpp)( |
| 214 | struct mpc_tree *tree, | 230 | struct mpc_tree *tree, |
| 215 | int dpp_id); | 231 | int dpp_id); |
| @@ -86,6 +86,7 @@ struct hw_sequencer_funcs { · 85 unmodified lines | |||
| 86 | struct dc_state *context, bool lock); | 86 | struct dc_state *context, bool lock); |
| 87 | void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx, | 87 | void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx, |
| 88 | bool flip_immediate); | 88 | bool flip_immediate); |
| 89 | void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock); | ||
| 89 | 90 | ||
| 90 | /* Timing Related */ | 91 | /* Timing Related */ |
| 91 | void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, | 92 | void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes, |
| @@ -1435,7 +1435,8 @@ static int pp_get_asic_baco_capability(void *handle, bool *cap) · 1434 unmodified lines | |||
| 1435 | if (!hwmgr) | 1435 | if (!hwmgr) |
| 1436 | return -EINVAL; | 1436 | return -EINVAL; |
| 1437 | 1437 | ||
| 1438 | if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_capability) | 1438 | if (!(hwmgr->not_vf && amdgpu_dpm) || |
| 1439 | !hwmgr->hwmgr_func->get_asic_baco_capability) | ||
| 1439 | return 0; | 1440 | return 0; |
| 1440 | 1441 | ||
| 1441 | mutex_lock(&hwmgr->smu_lock); | 1442 | mutex_lock(&hwmgr->smu_lock); |
| @@ -1452,8 +1453,7 @@ static int pp_get_asic_baco_state(void *handle, int *state) · 10 unmodified lines | |||
| 1452 | if (!hwmgr) | 1453 | if (!hwmgr) |
| 1453 | return -EINVAL; | 1454 | return -EINVAL; |
| 1454 | 1455 | ||
| 1455 | if (!(hwmgr->not_vf && amdgpu_dpm) || | 1456 | if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_state) |
| 1456 | !hwmgr->hwmgr_func->get_asic_baco_state) | ||
| 1457 | return 0; | 1457 | return 0; |
| 1458 | 1458 | ||
| 1459 | mutex_lock(&hwmgr->smu_lock); | 1459 | mutex_lock(&hwmgr->smu_lock); |
| @@ -1470,7 +1470,8 @@ static int pp_set_asic_baco_state(void *handle, int state) · 10 unmodified lines | |||
| 1470 | if (!hwmgr) | 1470 | if (!hwmgr) |
| 1471 | return -EINVAL; | 1471 | return -EINVAL; |
| 1472 | 1472 | ||
| 1473 | if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_asic_baco_state) | 1473 | if (!(hwmgr->not_vf && amdgpu_dpm) || |
| 1474 | !hwmgr->hwmgr_func->set_asic_baco_state) | ||
| 1474 | return 0; | 1475 | return 0; |
| 1475 | 1476 | ||
| 1476 | mutex_lock(&hwmgr->smu_lock); | 1477 | mutex_lock(&hwmgr->smu_lock); |
| @@ -3442,8 +3442,12 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, · 3441 unmodified lines | |||
| 3442 | drm_dp_queue_down_tx(mgr, txmsg); | 3442 | drm_dp_queue_down_tx(mgr, txmsg); |
| 3443 | 3443 | ||
| 3444 | ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); | 3444 | ret = drm_dp_mst_wait_tx_reply(mstb, txmsg); |
| 3445 | if (ret > 0 && txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) | 3445 | if (ret > 0) { |
| 3446 | ret = -EIO; | 3446 | if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK) |
| 3447 | ret = -EIO; | ||
| 3448 | else | ||
| 3449 | ret = size; | ||
| 3450 | } | ||
| 3447 | 3451 | ||
| 3448 | kfree(txmsg); | 3452 | kfree(txmsg); |
| 3449 | fail_put: | 3453 | fail_put: |
| @@ -5111,7 +5111,7 @@ static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *d · 5110 unmodified lines | |||
| 5111 | struct drm_display_mode *mode; | 5111 | struct drm_display_mode *mode; |
| 5112 | unsigned pixel_clock = (timings->pixel_clock[0] | | 5112 | unsigned pixel_clock = (timings->pixel_clock[0] | |
| 5113 | (timings->pixel_clock[1] << 8) | | 5113 | (timings->pixel_clock[1] << 8) | |
| 5114 | (timings->pixel_clock[2] << 16)); | 5114 | (timings->pixel_clock[2] << 16)) + 1; |
| 5115 | unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1; | 5115 | unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1; |
| 5116 | unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1; | 5116 | unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1; |
| 5117 | unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1; | 5117 | unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1; |
| @@ -182,21 +182,35 @@ i915_gem_object_fence_prepare(struct drm_i915_gem_object *obj, · 181 unmodified lines | |||
| 182 | int tiling_mode, unsigned int stride) | 182 | int tiling_mode, unsigned int stride) |
| 183 | { | 183 | { |
| 184 | struct i915_ggtt *ggtt = &to_i915(obj->base.dev)->ggtt; | 184 | struct i915_ggtt *ggtt = &to_i915(obj->base.dev)->ggtt; |
| 185 | struct i915_vma *vma; | 185 | struct i915_vma *vma, *vn; |
| 186 | LIST_HEAD(unbind); | ||
| 186 | int ret = 0; | 187 | int ret = 0; |
| 187 | 188 | ||
| 188 | if (tiling_mode == I915_TILING_NONE) | 189 | if (tiling_mode == I915_TILING_NONE) |
| 189 | return 0; | 190 | return 0; |
| 190 | 191 | ||
| 191 | mutex_lock(&ggtt->vm.mutex); | 192 | mutex_lock(&ggtt->vm.mutex); |
| 193 | |||
| 194 | spin_lock(&obj->vma.lock); | ||
| 192 | for_each_ggtt_vma(vma, obj) { | 195 | for_each_ggtt_vma(vma, obj) { |
| 196 | GEM_BUG_ON(vma->vm != &ggtt->vm); | ||
| 197 | |||
| 193 | if (i915_vma_fence_prepare(vma, tiling_mode, stride)) | 198 | if (i915_vma_fence_prepare(vma, tiling_mode, stride)) |
| 194 | continue; | 199 | continue; |
| 195 | 200 | ||
| 201 | list_move(&vma->vm_link, &unbind); | ||
| 202 | } | ||
| 203 | spin_unlock(&obj->vma.lock); | ||
| 204 | |||
| 205 | list_for_each_entry_safe(vma, vn, &unbind, vm_link) { | ||
| 196 | ret = __i915_vma_unbind(vma); | 206 | ret = __i915_vma_unbind(vma); |
| 197 | if (ret) | 207 | if (ret) { |
| 208 | /* Restore the remaining vma on an error */ | ||
| 209 | list_splice(&unbind, &ggtt->vm.bound_list); | ||
| 198 | break; | 210 | break; |
| 211 | } | ||
| 199 | } | 212 | } |
| 213 | |||
| 200 | mutex_unlock(&ggtt->vm.mutex); | 214 | mutex_unlock(&ggtt->vm.mutex); |
| 201 | 215 | ||
| 202 | return ret; | 216 | return ret; |
| @@ -268,6 +282,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 65 unmodified lines | |||
| 268 | } | 282 | } |
| 269 | mutex_unlock(&obj->mm.lock); | 283 | mutex_unlock(&obj->mm.lock); |
| 270 | 284 | ||
| 285 | spin_lock(&obj->vma.lock); | ||
| 271 | for_each_ggtt_vma(vma, obj) { | 286 | for_each_ggtt_vma(vma, obj) { |
| 272 | vma->fence_size = | 287 | vma->fence_size = |
| 273 | i915_gem_fence_size(i915, vma->size, tiling, stride); | 288 | i915_gem_fence_size(i915, vma->size, tiling, stride); |
| @@ -278,6 +293,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj, · 4 unmodified lines | |||
| 278 | if (vma->fence) | 293 | if (vma->fence) |
| 279 | vma->fence->dirty = true; | 294 | vma->fence->dirty = true; |
| 280 | } | 295 | } |
| 296 | spin_unlock(&obj->vma.lock); | ||
| 281 | 297 | ||
| 282 | obj->tiling_and_stride = tiling | stride; | 298 | obj->tiling_and_stride = tiling | stride; |
| 283 | i915_gem_object_unlock(obj); | 299 | i915_gem_object_unlock(obj); |
| @@ -1477,8 +1477,10 @@ static int igt_ppgtt_pin_update(void *arg) · 1476 unmodified lines | |||
| 1477 | unsigned int page_size = BIT(first); | 1477 | unsigned int page_size = BIT(first); |
| 1478 | 1478 | ||
| 1479 | obj = i915_gem_object_create_internal(dev_priv, page_size); | 1479 | obj = i915_gem_object_create_internal(dev_priv, page_size); |
| 1480 | if (IS_ERR(obj)) | 1480 | if (IS_ERR(obj)) { |
| 1481 | return PTR_ERR(obj); | 1481 | err = PTR_ERR(obj); |
| 1482 | goto out_vm; | ||
| 1483 | } | ||
| 1482 | 1484 | ||
| 1483 | vma = i915_vma_instance(obj, vm, NULL); | 1485 | vma = i915_vma_instance(obj, vm, NULL); |
| 1484 | if (IS_ERR(vma)) { | 1486 | if (IS_ERR(vma)) { |
| @@ -1531,8 +1533,10 @@ static int igt_ppgtt_pin_update(void *arg) · 46 unmodified lines | |||
| 1531 | } | 1533 | } |
| 1532 | 1534 | ||
| 1533 | obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE); | 1535 | obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE); |
| 1534 | if (IS_ERR(obj)) | 1536 | if (IS_ERR(obj)) { |
| 1535 | return PTR_ERR(obj); | 1537 | err = PTR_ERR(obj); |
| 1538 | goto out_vm; | ||
| 1539 | } | ||
| 1536 | 1540 | ||
| 1537 | vma = i915_vma_instance(obj, vm, NULL); | 1541 | vma = i915_vma_instance(obj, vm, NULL); |
| 1538 | if (IS_ERR(vma)) { | 1542 | if (IS_ERR(vma)) { |
| @@ -521,6 +521,8 @@ int intel_timeline_read_hwsp(struct i915_request *from, · 520 unmodified lines | |||
| 521 | 521 | ||
| 522 | rcu_read_lock(); | 522 | rcu_read_lock(); |
| 523 | cl = rcu_dereference(from->hwsp_cacheline); | 523 | cl = rcu_dereference(from->hwsp_cacheline); |
| 524 | if (i915_request_completed(from)) /* confirm cacheline is valid */ | ||
| 525 | goto unlock; | ||
| 524 | if (unlikely(!i915_active_acquire_if_busy(&cl->active))) | 526 | if (unlikely(!i915_active_acquire_if_busy(&cl->active))) |
| 525 | goto unlock; /* seqno wrapped and completed! */ | 527 | goto unlock; /* seqno wrapped and completed! */ |
| 526 | if (unlikely(i915_request_completed(from))) | 528 | if (unlikely(i915_request_completed(from))) |
| @@ -3358,7 +3358,8 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) · 3357 unmodified lines | |||
| 3358 | { | 3358 | { |
| 3359 | struct intel_uncore *uncore = &dev_priv->uncore; | 3359 | struct intel_uncore *uncore = &dev_priv->uncore; |
| 3360 | 3360 | ||
| 3361 | u32 de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE; | 3361 | u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) | |
| 3362 | GEN8_PIPE_CDCLK_CRC_DONE; | ||
| 3362 | u32 de_pipe_enables; | 3363 | u32 de_pipe_enables; |
| 3363 | u32 de_port_masked = GEN8_AUX_CHANNEL_A; | 3364 | u32 de_port_masked = GEN8_AUX_CHANNEL_A; |
| 3364 | u32 de_port_enables; | 3365 | u32 de_port_enables; |
| @@ -3369,13 +3370,10 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv) · 4 unmodified lines | |||
| 3369 | de_misc_masked |= GEN8_DE_MISC_GSE; | 3370 | de_misc_masked |= GEN8_DE_MISC_GSE; |
| 3370 | 3371 | ||
| 3371 | if (INTEL_GEN(dev_priv) >= 9) { | 3372 | if (INTEL_GEN(dev_priv) >= 9) { |
| 3372 | de_pipe_masked |= GEN9_DE_PIPE_IRQ_FAULT_ERRORS; | ||
| 3373 | de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | | 3373 | de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | |
| 3374 | GEN9_AUX_CHANNEL_D; | 3374 | GEN9_AUX_CHANNEL_D; |
| 3375 | if (IS_GEN9_LP(dev_priv)) | 3375 | if (IS_GEN9_LP(dev_priv)) |
| 3376 | de_port_masked |= BXT_DE_PORT_GMBUS; | 3376 | de_port_masked |= BXT_DE_PORT_GMBUS; |
| 3377 | } else { | ||
| 3378 | de_pipe_masked |= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; | ||
| 3379 | } | 3377 | } |
| 3380 | 3378 | ||
| 3381 | if (INTEL_GEN(dev_priv) >= 11) | 3379 | if (INTEL_GEN(dev_priv) >= 11) |
| @@ -158,16 +158,18 @@ vma_create(struct drm_i915_gem_object *obj, · 157 unmodified lines | |||
| 158 | 158 | ||
| 159 | GEM_BUG_ON(!IS_ALIGNED(vma->size, I915_GTT_PAGE_SIZE)); | 159 | GEM_BUG_ON(!IS_ALIGNED(vma->size, I915_GTT_PAGE_SIZE)); |
| 160 | 160 | ||
| 161 | spin_lock(&obj->vma.lock); | ||
| 162 | |||
| 161 | if (i915_is_ggtt(vm)) { | 163 | if (i915_is_ggtt(vm)) { |
| 162 | if (unlikely(overflows_type(vma->size, u32))) | 164 | if (unlikely(overflows_type(vma->size, u32))) |
| 163 | goto err_vma; | 165 | goto err_unlock; |
| 164 | 166 | ||
| 165 | vma->fence_size = i915_gem_fence_size(vm->i915, vma->size, | 167 | vma->fence_size = i915_gem_fence_size(vm->i915, vma->size, |
| 166 | i915_gem_object_get_tiling(obj), | 168 | i915_gem_object_get_tiling(obj), |
| 167 | i915_gem_object_get_stride(obj)); | 169 | i915_gem_object_get_stride(obj)); |
| 168 | if (unlikely(vma->fence_size < vma->size || /* overflow */ | 170 | if (unlikely(vma->fence_size < vma->size || /* overflow */ |
| 169 | vma->fence_size > vm->total)) | 171 | vma->fence_size > vm->total)) |
| 170 | goto err_vma; | 172 | goto err_unlock; |
| 171 | 173 | ||
| 172 | GEM_BUG_ON(!IS_ALIGNED(vma->fence_size, I915_GTT_MIN_ALIGNMENT)); | 174 | GEM_BUG_ON(!IS_ALIGNED(vma->fence_size, I915_GTT_MIN_ALIGNMENT)); |
| 173 | 175 | ||
| @@ -179,8 +181,6 @@ vma_create(struct drm_i915_gem_object *obj, · 5 unmodified lines | |||
| 179 | __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma)); | 181 | __set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma)); |
| 180 | } | 182 | } |
| 181 | 183 | ||
| 182 | spin_lock(&obj->vma.lock); | ||
| 183 | |||
| 184 | rb = NULL; | 184 | rb = NULL; |
| 185 | p = &obj->vma.tree.rb_node; | 185 | p = &obj->vma.tree.rb_node; |
| 186 | while (*p) { | 186 | while (*p) { |
| @@ -225,6 +225,8 @@ vma_create(struct drm_i915_gem_object *obj, · 38 unmodified lines | |||
| 225 | 225 | ||
| 226 | return vma; | 226 | return vma; |
| 227 | 227 | ||
| 228 | err_unlock: | ||
| 229 | spin_unlock(&obj->vma.lock); | ||
| 228 | err_vma: | 230 | err_vma: |
| 229 | i915_vma_free(vma); | 231 | i915_vma_free(vma); |
| 230 | return ERR_PTR(-E2BIG); | 232 | return ERR_PTR(-E2BIG); |
| @@ -480,9 +480,10 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, · 479 unmodified lines | |||
| 480 | return ret; | 480 | return ret; |
| 481 | 481 | ||
| 482 | ret = qxl_release_reserve_list(release, true); | 482 | ret = qxl_release_reserve_list(release, true); |
| 483 | if (ret) | 483 | if (ret) { |
| 484 | qxl_release_free(qdev, release); | ||
| 484 | return ret; | 485 | return ret; |
| 485 | 486 | } | |
| 486 | cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release); | 487 | cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release); |
| 487 | cmd->type = QXL_SURFACE_CMD_CREATE; | 488 | cmd->type = QXL_SURFACE_CMD_CREATE; |
| 488 | cmd->flags = QXL_SURF_FLAG_KEEP_DATA; | 489 | cmd->flags = QXL_SURF_FLAG_KEEP_DATA; |
| @@ -499,8 +500,8 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev, · 10 unmodified lines | |||
| 499 | /* no need to add a release to the fence for this surface bo, | 500 | /* no need to add a release to the fence for this surface bo, |
| 500 | since it is only released when we ask to destroy the surface | 501 | since it is only released when we ask to destroy the surface |
| 501 | and it would never signal otherwise */ | 502 | and it would never signal otherwise */ |
| 502 | qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | ||
| 503 | qxl_release_fence_buffer_objects(release); | 503 | qxl_release_fence_buffer_objects(release); |
| 504 | qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | ||
| 504 | 505 | ||
| 505 | surf->hw_surf_alloc = true; | 506 | surf->hw_surf_alloc = true; |
| 506 | spin_lock(&qdev->surf_id_idr_lock); | 507 | spin_lock(&qdev->surf_id_idr_lock); |
| @@ -542,9 +543,8 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev, · 35 unmodified lines | |||
| 542 | cmd->surface_id = id; | 543 | cmd->surface_id = id; |
| 543 | qxl_release_unmap(qdev, release, &cmd->release_info); | 544 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 544 | 545 | ||
| 545 | qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | ||
| 546 | |||
| 547 | qxl_release_fence_buffer_objects(release); | 546 | qxl_release_fence_buffer_objects(release); |
| 547 | qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false); | ||
| 548 | 548 | ||
| 549 | return 0; | 549 | return 0; |
| 550 | } | 550 | } |
| @@ -510,8 +510,8 @@ static int qxl_primary_apply_cursor(struct drm_plane *plane) · 509 unmodified lines | |||
| 510 | cmd->u.set.visible = 1; | 510 | cmd->u.set.visible = 1; |
| 511 | qxl_release_unmap(qdev, release, &cmd->release_info); | 511 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 512 | 512 | ||
| 513 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | ||
| 514 | qxl_release_fence_buffer_objects(release); | 513 | qxl_release_fence_buffer_objects(release); |
| 514 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | ||
| 515 | 515 | ||
| 516 | return ret; | 516 | return ret; |
| 517 | 517 | ||
| @@ -652,8 +652,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane, · 134 unmodified lines | |||
| 652 | cmd->u.position.y = plane->state->crtc_y + fb->hot_y; | 652 | cmd->u.position.y = plane->state->crtc_y + fb->hot_y; |
| 653 | 653 | ||
| 654 | qxl_release_unmap(qdev, release, &cmd->release_info); | 654 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 655 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | ||
| 656 | qxl_release_fence_buffer_objects(release); | 655 | qxl_release_fence_buffer_objects(release); |
| 656 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | ||
| 657 | 657 | ||
| 658 | if (old_cursor_bo != NULL) | 658 | if (old_cursor_bo != NULL) |
| 659 | qxl_bo_unpin(old_cursor_bo); | 659 | qxl_bo_unpin(old_cursor_bo); |
| @@ -700,8 +700,8 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane, · 40 unmodified lines | |||
| 700 | cmd->type = QXL_CURSOR_HIDE; | 700 | cmd->type = QXL_CURSOR_HIDE; |
| 701 | qxl_release_unmap(qdev, release, &cmd->release_info); | 701 | qxl_release_unmap(qdev, release, &cmd->release_info); |
| 702 | 702 | ||
| 703 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | ||
| 704 | qxl_release_fence_buffer_objects(release); | 703 | qxl_release_fence_buffer_objects(release); |
| 704 | qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false); | ||
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | static void qxl_update_dumb_head(struct qxl_device *qdev, | 707 | static void qxl_update_dumb_head(struct qxl_device *qdev, |
| @@ -209,9 +209,10 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, · 208 unmodified lines | |||
| 209 | goto out_release_backoff; | 209 | goto out_release_backoff; |
| 210 | 210 | ||
| 211 | rects = drawable_set_clipping(qdev, num_clips, clips_bo); | 211 | rects = drawable_set_clipping(qdev, num_clips, clips_bo); |
| 212 | if (!rects) | 212 | if (!rects) { |
| 213 | ret = -EINVAL; | ||
| 213 | goto out_release_backoff; | 214 | goto out_release_backoff; |
| 214 | 215 | } | |
| 215 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); | 216 | drawable = (struct qxl_drawable *)qxl_release_map(qdev, release); |
| 216 | 217 | ||
| 217 | drawable->clip.type = SPICE_CLIP_TYPE_RECTS; | 218 | drawable->clip.type = SPICE_CLIP_TYPE_RECTS; |
| @@ -242,8 +243,8 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev, · 24 unmodified lines | |||
| 242 | } | 243 | } |
| 243 | qxl_bo_kunmap(clips_bo); | 244 | qxl_bo_kunmap(clips_bo); |
| 244 | 245 | ||
| 245 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | ||
| 246 | qxl_release_fence_buffer_objects(release); | 246 | qxl_release_fence_buffer_objects(release); |
| 247 | qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false); | ||
| 247 | 248 | ||
| 248 | out_release_backoff: | 249 | out_release_backoff: |
| 249 | if (ret) | 250 | if (ret) |
| @@ -212,7 +212,8 @@ qxl_image_init_helper(struct qxl_device *qdev, · 211 unmodified lines | |||
| 212 | break; | 212 | break; |
| 213 | default: | 213 | default: |
| 214 | DRM_ERROR("unsupported image bit depth\n"); | 214 | DRM_ERROR("unsupported image bit depth\n"); |
| 215 | return -EINVAL; /* TODO: cleanup */ | 215 | qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr); |
| 216 | return -EINVAL; | ||
| 216 | } | 217 | } |
| 217 | image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN; | 218 | image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN; |
| 218 | image->u.bitmap.x = width; | 219 | image->u.bitmap.x = width; |
| @@ -261,11 +261,8 @@ static int qxl_process_single_command(struct qxl_device *qdev, · 260 unmodified lines | |||
| 261 | apply_surf_reloc(qdev, &reloc_info[i]); | 261 | apply_surf_reloc(qdev, &reloc_info[i]); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | qxl_release_fence_buffer_objects(release); | ||
| 264 | ret = qxl_push_command_ring_release(qdev, release, cmd->type, true); | 265 | ret = qxl_push_command_ring_release(qdev, release, cmd->type, true); |
| 265 | if (ret) | ||
| 266 | qxl_release_backoff_reserve_list(release); | ||
| 267 | else | ||
| 268 | qxl_release_fence_buffer_objects(release); | ||
| 269 | 266 | ||
| 270 | out_free_bos: | 267 | out_free_bos: |
| 271 | out_free_release: | 268 | out_free_release: |
| @@ -53,14 +53,6 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work) · 52 unmodified lines | |||
| 53 | events_clear, &events_clear); | 53 | events_clear, &events_clear); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev, | ||
| 57 | uint32_t ctx_id) | ||
| 58 | { | ||
| 59 | virtio_gpu_cmd_context_destroy(vgdev, ctx_id); | ||
| 60 | virtio_gpu_notify(vgdev); | ||
| 61 | ida_free(&vgdev->ctx_id_ida, ctx_id - 1); | ||
| 62 | } | ||
| 63 | |||
| 64 | static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq, | 56 | static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq, |
| 65 | void (*work_func)(struct work_struct *work)) | 57 | void (*work_func)(struct work_struct *work)) |
| 66 | { | 58 | { |
| @@ -275,14 +267,17 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) · 208 unmodified lines | |||
| 275 | void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file) | 267 | void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file) |
| 276 | { | 268 | { |
| 277 | struct virtio_gpu_device *vgdev = dev->dev_private; | 269 | struct virtio_gpu_device *vgdev = dev->dev_private; |
| 278 | struct virtio_gpu_fpriv *vfpriv; | 270 | struct virtio_gpu_fpriv *vfpriv = file->driver_priv; |
| 279 | 271 | ||
| 280 | if (!vgdev->has_virgl_3d) | 272 | if (!vgdev->has_virgl_3d) |
| 281 | return; | 273 | return; |
| 282 | 274 | ||
| 283 | vfpriv = file->driver_priv; | 275 | if (vfpriv->context_created) { |
| 276 | virtio_gpu_cmd_context_destroy(vgdev, vfpriv->ctx_id); | ||
| 277 | virtio_gpu_notify(vgdev); | ||
| 278 | } | ||
| 284 | 279 | ||
| 285 | virtio_gpu_context_destroy(vgdev, vfpriv->ctx_id); | 280 | ida_free(&vgdev->ctx_id_ida, vfpriv->ctx_id - 1); |
| 286 | mutex_destroy(&vfpriv->context_lock); | 281 | mutex_destroy(&vfpriv->context_lock); |
| 287 | kfree(vfpriv); | 282 | kfree(vfpriv); |
| 288 | file->driver_priv = NULL; | 283 | file->driver_priv = NULL; |
| @@ -184,11 +184,7 @@ void hv_synic_enable_regs(unsigned int cpu) · 183 unmodified lines | |||
| 184 | 184 | ||
| 185 | shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR; | 185 | shared_sint.vector = HYPERVISOR_CALLBACK_VECTOR; |
| 186 | shared_sint.masked = false; | 186 | shared_sint.masked = false; |
| 187 | if (ms_hyperv.hints & HV_DEPRECATING_AEOI_RECOMMENDED) | 187 | shared_sint.auto_eoi = hv_recommend_using_aeoi(); |
| 188 | shared_sint.auto_eoi = false; | ||
| 189 | else | ||
| 190 | shared_sint.auto_eoi = true; | ||
| 191 | |||
| 192 | hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); | 188 | hv_set_synint_state(VMBUS_MESSAGE_SINT, shared_sint.as_uint64); |
| 193 | 189 | ||
| 194 | /* Enable the global synic bit */ | 190 | /* Enable the global synic bit */ |
| @@ -286,8 +286,8 @@ TRACE_EVENT(vmbus_send_tl_connect_request, · 285 unmodified lines | |||
| 286 | __field(int, ret) | 286 | __field(int, ret) |
| 287 | ), | 287 | ), |
| 288 | TP_fast_assign( | 288 | TP_fast_assign( |
| 289 | memcpy(__entry->guest_id, &msg->guest_endpoint_id.b, 16); | 289 | export_guid(__entry->guest_id, &msg->guest_endpoint_id); |
| 290 | memcpy(__entry->host_id, &msg->host_service_id.b, 16); | 290 | export_guid(__entry->host_id, &msg->host_service_id); |
| 291 | __entry->ret = ret; | 291 | __entry->ret = ret; |
| 292 | ), | 292 | ), |
| 293 | TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, " | 293 | TP_printk("sending guest_endpoint_id %pUl, host_service_id %pUl, " |
| @@ -978,6 +978,9 @@ static int vmbus_resume(struct device *child_device) · 977 unmodified lines | |||
| 978 | 978 | ||
| 979 | return drv->resume(dev); | 979 | return drv->resume(dev); |
| 980 | } | 980 | } |
| 981 | #else | ||
| 982 | #define vmbus_suspend NULL | ||
| 983 | #define vmbus_resume NULL | ||
| 981 | #endif /* CONFIG_PM_SLEEP */ | 984 | #endif /* CONFIG_PM_SLEEP */ |
| 982 | 985 | ||
| 983 | /* | 986 | /* |
| @@ -997,11 +1000,22 @@ static void vmbus_device_release(struct device *device) · 13 unmodified lines | |||
| 997 | } | 1000 | } |
| 998 | 1001 | ||
| 999 | /* | 1002 | /* |
| 1000 | * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than | 1003 | * Note: we must use the "noirq" ops: see the comment before vmbus_bus_pm. |
| 1001 | * SET_SYSTEM_SLEEP_PM_OPS: see the comment before vmbus_bus_pm. | 1004 | * |
| 1005 | * suspend_noirq/resume_noirq are set to NULL to support Suspend-to-Idle: we | ||
| 1006 | * shouldn't suspend the vmbus devices upon Suspend-to-Idle, otherwise there | ||
| 1007 | * is no way to wake up a Generation-2 VM. | ||
| 1008 | * | ||
| 1009 | * The other 4 ops are for hibernation. | ||
| 1002 | */ | 1010 | */ |
| 1011 | |||
| 1003 | static const struct dev_pm_ops vmbus_pm = { | 1012 | static const struct dev_pm_ops vmbus_pm = { |
| 1004 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_suspend, vmbus_resume) | 1013 | .suspend_noirq = NULL, |
| 1014 | .resume_noirq = NULL, | ||
| 1015 | .freeze_noirq = vmbus_suspend, | ||
| 1016 | .thaw_noirq = vmbus_resume, | ||
| 1017 | .poweroff_noirq = vmbus_suspend, | ||
| 1018 | .restore_noirq = vmbus_resume, | ||
| 1005 | }; | 1019 | }; |
| 1006 | 1020 | ||
| 1007 | /* The one and only one */ | 1021 | /* The one and only one */ |
| @@ -2281,6 +2295,9 @@ static int vmbus_bus_resume(struct device *dev) · 1273 unmodified lines | |||
| 2281 | 2295 | ||
| 2282 | return 0; | 2296 | return 0; |
| 2283 | } | 2297 | } |
| 2298 | #else | ||
| 2299 | #define vmbus_bus_suspend NULL | ||
| 2300 | #define vmbus_bus_resume NULL | ||
| 2284 | #endif /* CONFIG_PM_SLEEP */ | 2301 | #endif /* CONFIG_PM_SLEEP */ |
| 2285 | 2302 | ||
| 2286 | static const struct acpi_device_id vmbus_acpi_device_ids[] = { | 2303 | static const struct acpi_device_id vmbus_acpi_device_ids[] = { |
| @@ -2291,16 +2308,24 @@ static const struct acpi_device_id vmbus_acpi_device_ids[] = { · 4 unmodified lines | |||
| 2291 | MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); | 2308 | MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids); |
| 2292 | 2309 | ||
| 2293 | /* | 2310 | /* |
| 2294 | * Note: we must use SET_NOIRQ_SYSTEM_SLEEP_PM_OPS rather than | 2311 | * Note: we must use the "no_irq" ops, otherwise hibernation can not work with |
| 2295 | * SET_SYSTEM_SLEEP_PM_OPS, otherwise NIC SR-IOV can not work, because the | 2312 | * PCI device assignment, because "pci_dev_pm_ops" uses the "noirq" ops: in |
| 2296 | * "pci_dev_pm_ops" uses the "noirq" callbacks: in the resume path, the | 2313 | * the resume path, the pci "noirq" restore op runs before "non-noirq" op (see |
| 2297 | * pci "noirq" restore callback runs before "non-noirq" callbacks (see | ||
| 2298 | * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() -> | 2314 | * resume_target_kernel() -> dpm_resume_start(), and hibernation_restore() -> |
| 2299 | * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's | 2315 | * dpm_resume_end()). This means vmbus_bus_resume() and the pci-hyperv's |
| 2300 | * resume callback must also run via the "noirq" callbacks. | 2316 | * resume callback must also run via the "noirq" ops. |
| 2317 | * | ||
| 2318 | * Set suspend_noirq/resume_noirq to NULL for Suspend-to-Idle: see the comment | ||
| 2319 | * earlier in this file before vmbus_pm. | ||
| 2301 | */ | 2320 | */ |
| 2321 | |||
| 2302 | static const struct dev_pm_ops vmbus_bus_pm = { | 2322 | static const struct dev_pm_ops vmbus_bus_pm = { |
| 2303 | SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(vmbus_bus_suspend, vmbus_bus_resume) | 2323 | .suspend_noirq = NULL, |
| 2324 | .resume_noirq = NULL, | ||
| 2325 | .freeze_noirq = vmbus_bus_suspend, | ||
| 2326 | .thaw_noirq = vmbus_bus_resume, | ||
| 2327 | .poweroff_noirq = vmbus_bus_suspend, | ||
| 2328 | .restore_noirq = vmbus_bus_resume | ||
| 2304 | }; | 2329 | }; |
| 2305 | 2330 | ||
| 2306 | static struct acpi_driver vmbus_acpi_driver = { | 2331 | static struct acpi_driver vmbus_acpi_driver = { |
| @@ -349,12 +349,12 @@ static int amd_mp2_pci_probe(struct pci_dev *pci_dev, · 348 unmodified lines | |||
| 349 | if (!privdata) | 349 | if (!privdata) |
| 350 | return -ENOMEM; | 350 | return -ENOMEM; |
| 351 | 351 | ||
| 352 | privdata->pci_dev = pci_dev; | ||
| 352 | rc = amd_mp2_pci_init(privdata, pci_dev); | 353 | rc = amd_mp2_pci_init(privdata, pci_dev); |
| 353 | if (rc) | 354 | if (rc) |
| 354 | return rc; | 355 | return rc; |
| 355 | 356 | ||
| 356 | mutex_init(&privdata->c2p_lock); | 357 | mutex_init(&privdata->c2p_lock); |
| 357 | privdata->pci_dev = pci_dev; | ||
| 358 | 358 | ||
| 359 | pm_runtime_set_autosuspend_delay(&pci_dev->dev, 1000); | 359 | pm_runtime_set_autosuspend_delay(&pci_dev->dev, 1000); |
| 360 | pm_runtime_use_autosuspend(&pci_dev->dev); | 360 | pm_runtime_use_autosuspend(&pci_dev->dev); |
| @@ -603,6 +603,7 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) · 602 unmodified lines | |||
| 603 | /* Ack all interrupts except for Rx done */ | 603 | /* Ack all interrupts except for Rx done */ |
| 604 | writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE, | 604 | writel(irq_received & ~ASPEED_I2CD_INTR_RX_DONE, |
| 605 | bus->base + ASPEED_I2C_INTR_STS_REG); | 605 | bus->base + ASPEED_I2C_INTR_STS_REG); |
| 606 | readl(bus->base + ASPEED_I2C_INTR_STS_REG); | ||
| 606 | irq_remaining = irq_received; | 607 | irq_remaining = irq_received; |
| 607 | 608 | ||
| 608 | #if IS_ENABLED(CONFIG_I2C_SLAVE) | 609 | #if IS_ENABLED(CONFIG_I2C_SLAVE) |
| @@ -645,9 +646,11 @@ static irqreturn_t aspeed_i2c_bus_irq(int irq, void *dev_id) · 36 unmodified lines | |||
| 645 | irq_received, irq_handled); | 646 | irq_received, irq_handled); |
| 646 | 647 | ||
| 647 | /* Ack Rx done */ | 648 | /* Ack Rx done */ |
| 648 | if (irq_received & ASPEED_I2CD_INTR_RX_DONE) | 649 | if (irq_received & ASPEED_I2CD_INTR_RX_DONE) { |
| 649 | writel(ASPEED_I2CD_INTR_RX_DONE, | 650 | writel(ASPEED_I2CD_INTR_RX_DONE, |
| 650 | bus->base + ASPEED_I2C_INTR_STS_REG); | 651 | bus->base + ASPEED_I2C_INTR_STS_REG); |
| 652 | readl(bus->base + ASPEED_I2C_INTR_STS_REG); | ||
| 653 | } | ||
| 651 | spin_unlock(&bus->lock); | 654 | spin_unlock(&bus->lock); |
| 652 | return irq_remaining ? IRQ_NONE : IRQ_HANDLED; | 655 | return irq_remaining ? IRQ_NONE : IRQ_HANDLED; |
| 653 | } | 656 | } |
| @@ -360,6 +360,9 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c, · 359 unmodified lines | |||
| 360 | value = (u8)((val >> S_RX_DATA_SHIFT) & S_RX_DATA_MASK); | 360 | value = (u8)((val >> S_RX_DATA_SHIFT) & S_RX_DATA_MASK); |
| 361 | i2c_slave_event(iproc_i2c->slave, | 361 | i2c_slave_event(iproc_i2c->slave, |
| 362 | I2C_SLAVE_WRITE_RECEIVED, &value); | 362 | I2C_SLAVE_WRITE_RECEIVED, &value); |
| 363 | if (rx_status == I2C_SLAVE_RX_END) | ||
| 364 | i2c_slave_event(iproc_i2c->slave, | ||
| 365 | I2C_SLAVE_STOP, &value); | ||
| 363 | } | 366 | } |
| 364 | } else if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) { | 367 | } else if (status & BIT(IS_S_TX_UNDERRUN_SHIFT)) { |
| 365 | /* Master read other than start */ | 368 | /* Master read other than start */ |
| @@ -996,13 +996,14 @@ tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev, · 995 unmodified lines | |||
| 996 | do { | 996 | do { |
| 997 | u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS); | 997 | u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS); |
| 998 | 998 | ||
| 999 | if (status) | 999 | if (status) { |
| 1000 | tegra_i2c_isr(i2c_dev->irq, i2c_dev); | 1000 | tegra_i2c_isr(i2c_dev->irq, i2c_dev); |
| 1001 | 1001 | ||
| 1002 | if (completion_done(complete)) { | 1002 | if (completion_done(complete)) { |
| 1003 | s64 delta = ktime_ms_delta(ktimeout, ktime); | 1003 | s64 delta = ktime_ms_delta(ktimeout, ktime); |
| 1004 | 1004 | ||
| 1005 | return msecs_to_jiffies(delta) ?: 1; | 1005 | return msecs_to_jiffies(delta) ?: 1; |
| 1006 | } | ||
| 1006 | } | 1007 | } |
| 1007 | 1008 | ||
| 1008 | ktime = ktime_get(); | 1009 | ktime = ktime_get(); |
| @@ -1029,18 +1030,14 @@ tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev, · 20 unmodified lines | |||
| 1029 | disable_irq(i2c_dev->irq); | 1030 | disable_irq(i2c_dev->irq); |
| 1030 | 1031 | ||
| 1031 | /* | 1032 | /* |
| 1032 | * Under some rare circumstances (like running KASAN + | 1033 | * There is a chance that completion may happen after IRQ |
| 1033 | * NFS root) CPU, which handles interrupt, may stuck in | 1034 | * synchronization, which is done by disable_irq(). |
| 1034 | * uninterruptible state for a significant time. In this | ||
| 1035 | * case we will get timeout if I2C transfer is running on | ||
| 1036 | * a sibling CPU, despite of IRQ being raised. | ||
| 1037 | * | ||
| 1038 | * In order to handle this rare condition, the IRQ status | ||
| 1039 | * needs to be checked after timeout. | ||
| 1040 | */ | 1035 | */ |
| 1041 | if (ret == 0) | 1036 | if (ret == 0 && completion_done(complete)) { |
| 1042 | ret = tegra_i2c_poll_completion_timeout(i2c_dev, | 1037 | dev_warn(i2c_dev->dev, |
| 1043 | complete, 0); | 1038 | "completion done after timeout\n"); |
| 1039 | ret = 1; | ||
| 1040 | } | ||
| 1044 | } | 1041 | } |
| 1045 | 1042 | ||
| 1046 | return ret; | 1043 | return ret; |
| @@ -1219,15 +1216,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev, · 172 unmodified lines | |||
| 1219 | time_left = tegra_i2c_wait_completion_timeout( | 1216 | time_left = tegra_i2c_wait_completion_timeout( |
| 1220 | i2c_dev, &i2c_dev->dma_complete, xfer_time); | 1217 | i2c_dev, &i2c_dev->dma_complete, xfer_time); |
| 1221 | 1218 | ||
| 1222 | /* | ||
| 1223 | * Synchronize DMA first, since dmaengine_terminate_sync() | ||
| 1224 | * performs synchronization after the transfer's termination | ||
| 1225 | * and we want to get a completion if transfer succeeded. | ||
| 1226 | */ | ||
| 1227 | dmaengine_synchronize(i2c_dev->msg_read ? | ||
| 1228 | i2c_dev->rx_dma_chan : | ||
| 1229 | i2c_dev->tx_dma_chan); | ||
| 1230 | |||
| 1231 | dmaengine_terminate_sync(i2c_dev->msg_read ? | 1219 | dmaengine_terminate_sync(i2c_dev->msg_read ? |
| 1232 | i2c_dev->rx_dma_chan : | 1220 | i2c_dev->rx_dma_chan : |
| 1233 | i2c_dev->tx_dma_chan); | 1221 | i2c_dev->tx_dma_chan); |
| @@ -862,7 +862,7 @@ static struct cm_id_private *cm_alloc_id_priv(struct ib_device *device, · 861 unmodified lines | |||
| 862 | 862 | ||
| 863 | ret = xa_alloc_cyclic_irq(&cm.local_id_table, &id, NULL, xa_limit_32b, | 863 | ret = xa_alloc_cyclic_irq(&cm.local_id_table, &id, NULL, xa_limit_32b, |
| 864 | &cm.local_id_next, GFP_KERNEL); | 864 | &cm.local_id_next, GFP_KERNEL); |
| 865 | if (ret) | 865 | if (ret < 0) |
| 866 | goto error; | 866 | goto error; |
| 867 | cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand; | 867 | cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand; |
| 868 | 868 | ||
| @@ -1828,11 +1828,9 @@ static void cm_format_mra(struct cm_mra_msg *mra_msg, · 959 unmodified lines | |||
| 1828 | 1828 | ||
| 1829 | static void cm_format_rej(struct cm_rej_msg *rej_msg, | 1829 | static void cm_format_rej(struct cm_rej_msg *rej_msg, |
| 1830 | struct cm_id_private *cm_id_priv, | 1830 | struct cm_id_private *cm_id_priv, |
| 1831 | enum ib_cm_rej_reason reason, | 1831 | enum ib_cm_rej_reason reason, void *ari, |
| 1832 | void *ari, | 1832 | u8 ari_length, const void *private_data, |
| 1833 | u8 ari_length, | 1833 | u8 private_data_len, enum ib_cm_state state) |
| 1834 | const void *private_data, | ||
| 1835 | u8 private_data_len) | ||
| 1836 | { | 1834 | { |
| 1837 | lockdep_assert_held(&cm_id_priv->lock); | 1835 | lockdep_assert_held(&cm_id_priv->lock); |
| 1838 | 1836 | ||
| @@ -1840,7 +1838,7 @@ static void cm_format_rej(struct cm_rej_msg *rej_msg, · 1 unmodified line | |||
| 1840 | IBA_SET(CM_REJ_REMOTE_COMM_ID, rej_msg, | 1838 | IBA_SET(CM_REJ_REMOTE_COMM_ID, rej_msg, |
| 1841 | be32_to_cpu(cm_id_priv->id.remote_id)); | 1839 | be32_to_cpu(cm_id_priv->id.remote_id)); |
| 1842 | 1840 | ||
| 1843 | switch(cm_id_priv->id.state) { | 1841 | switch (state) { |
| 1844 | case IB_CM_REQ_RCVD: | 1842 | case IB_CM_REQ_RCVD: |
| 1845 | IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, be32_to_cpu(0)); | 1843 | IBA_SET(CM_REJ_LOCAL_COMM_ID, rej_msg, be32_to_cpu(0)); |
| 1846 | IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, CM_MSG_RESPONSE_REQ); | 1844 | IBA_SET(CM_REJ_MESSAGE_REJECTED, rej_msg, CM_MSG_RESPONSE_REQ); |
| @@ -1905,8 +1903,9 @@ static void cm_dup_req_handler(struct cm_work *work, · 58 unmodified lines | |||
| 1905 | cm_id_priv->private_data_len); | 1903 | cm_id_priv->private_data_len); |
| 1906 | break; | 1904 | break; |
| 1907 | case IB_CM_TIMEWAIT: | 1905 | case IB_CM_TIMEWAIT: |
| 1908 | cm_format_rej((struct cm_rej_msg *) msg->mad, cm_id_priv, | 1906 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, |
| 1909 | IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0); | 1907 | IB_CM_REJ_STALE_CONN, NULL, 0, NULL, 0, |
| 1908 | IB_CM_TIMEWAIT); | ||
| 1910 | break; | 1909 | break; |
| 1911 | default: | 1910 | default: |
| 1912 | goto unlock; | 1911 | goto unlock; |
| @@ -2904,6 +2903,7 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 991 unmodified lines | |||
| 2904 | u8 ari_length, const void *private_data, | 2903 | u8 ari_length, const void *private_data, |
| 2905 | u8 private_data_len) | 2904 | u8 private_data_len) |
| 2906 | { | 2905 | { |
| 2906 | enum ib_cm_state state = cm_id_priv->id.state; | ||
| 2907 | struct ib_mad_send_buf *msg; | 2907 | struct ib_mad_send_buf *msg; |
| 2908 | int ret; | 2908 | int ret; |
| 2909 | 2909 | ||
| @@ -2913,7 +2913,7 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 3 unmodified lines | |||
| 2913 | (ari && ari_length > IB_CM_REJ_ARI_LENGTH)) | 2913 | (ari && ari_length > IB_CM_REJ_ARI_LENGTH)) |
| 2914 | return -EINVAL; | 2914 | return -EINVAL; |
| 2915 | 2915 | ||
| 2916 | switch (cm_id_priv->id.state) { | 2916 | switch (state) { |
| 2917 | case IB_CM_REQ_SENT: | 2917 | case IB_CM_REQ_SENT: |
| 2918 | case IB_CM_MRA_REQ_RCVD: | 2918 | case IB_CM_MRA_REQ_RCVD: |
| 2919 | case IB_CM_REQ_RCVD: | 2919 | case IB_CM_REQ_RCVD: |
| @@ -2925,7 +2925,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 5 unmodified lines | |||
| 2925 | if (ret) | 2925 | if (ret) |
| 2926 | return ret; | 2926 | return ret; |
| 2927 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, | 2927 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, |
| 2928 | ari, ari_length, private_data, private_data_len); | 2928 | ari, ari_length, private_data, private_data_len, |
| 2929 | state); | ||
| 2929 | break; | 2930 | break; |
| 2930 | case IB_CM_REP_SENT: | 2931 | case IB_CM_REP_SENT: |
| 2931 | case IB_CM_MRA_REP_RCVD: | 2932 | case IB_CM_MRA_REP_RCVD: |
| @@ -2934,7 +2935,8 @@ static int cm_send_rej_locked(struct cm_id_private *cm_id_priv, · 2 unmodified lines | |||
| 2934 | if (ret) | 2935 | if (ret) |
| 2935 | return ret; | 2936 | return ret; |
| 2936 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, | 2937 | cm_format_rej((struct cm_rej_msg *)msg->mad, cm_id_priv, reason, |
| 2937 | ari, ari_length, private_data, private_data_len); | 2938 | ari, ari_length, private_data, private_data_len, |
| 2939 | state); | ||
| 2938 | break; | 2940 | break; |
| 2939 | default: | 2941 | default: |
| 2940 | pr_debug("%s: local_id %d, cm_id->state: %d\n", __func__, | 2942 | pr_debug("%s: local_id %d, cm_id->state: %d\n", __func__, |
| @@ -360,7 +360,7 @@ lookup_get_fd_uobject(const struct uverbs_api_object *obj, · 359 unmodified lines | |||
| 360 | * uverbs_uobject_fd_release(), and the caller is expected to ensure | 360 | * uverbs_uobject_fd_release(), and the caller is expected to ensure |
| 361 | * that release is never done while a call to lookup is possible. | 361 | * that release is never done while a call to lookup is possible. |
| 362 | */ | 362 | */ |
| 363 | if (f->f_op != fd_type->fops) { | 363 | if (f->f_op != fd_type->fops || uobject->ufile != ufile) { |
| 364 | fput(f); | 364 | fput(f); |
| 365 | return ERR_PTR(-EBADF); | 365 | return ERR_PTR(-EBADF); |
| 366 | } | 366 | } |
| @@ -474,16 +474,15 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj, · 107 unmodified lines | |||
| 474 | filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL, | 474 | filp = anon_inode_getfile(fd_type->name, fd_type->fops, NULL, |
| 475 | fd_type->flags); | 475 | fd_type->flags); |
| 476 | if (IS_ERR(filp)) { | 476 | if (IS_ERR(filp)) { |
| 477 | uverbs_uobject_put(uobj); | ||
| 477 | uobj = ERR_CAST(filp); | 478 | uobj = ERR_CAST(filp); |
| 478 | goto err_uobj; | 479 | goto err_fd; |
| 479 | } | 480 | } |
| 480 | uobj->object = filp; | 481 | uobj->object = filp; |
| 481 | 482 | ||
| 482 | uobj->id = new_fd; | 483 | uobj->id = new_fd; |
| 483 | return uobj; | 484 | return uobj; |
| 484 | 485 | ||
| 485 | err_uobj: | ||
| 486 | uverbs_uobject_put(uobj); | ||
| 487 | err_fd: | 486 | err_fd: |
| 488 | put_unused_fd(new_fd); | 487 | put_unused_fd(new_fd); |
| 489 | return uobj; | 488 | return uobj; |
| @@ -679,7 +678,6 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj, · 189 unmodified lines | |||
| 679 | enum rdma_lookup_mode mode) | 678 | enum rdma_lookup_mode mode) |
| 680 | { | 679 | { |
| 681 | assert_uverbs_usecnt(uobj, mode); | 680 | assert_uverbs_usecnt(uobj, mode); |
| 682 | uobj->uapi_object->type_class->lookup_put(uobj, mode); | ||
| 683 | /* | 681 | /* |
| 684 | * In order to unlock an object, either decrease its usecnt for | 682 | * In order to unlock an object, either decrease its usecnt for |
| 685 | * read access or zero it in case of exclusive access. See | 683 | * read access or zero it in case of exclusive access. See |
| @@ -696,6 +694,7 @@ void rdma_lookup_put_uobject(struct ib_uobject *uobj, · 10 unmodified lines | |||
| 696 | break; | 694 | break; |
| 697 | } | 695 | } |
| 698 | 696 | ||
| 697 | uobj->uapi_object->type_class->lookup_put(uobj, mode); | ||
| 699 | /* Pairs with the kref obtained by type->lookup_get */ | 698 | /* Pairs with the kref obtained by type->lookup_get */ |
| 700 | uverbs_uobject_put(uobj); | 699 | uverbs_uobject_put(uobj); |
| 701 | } | 700 | } |
| @@ -820,6 +820,10 @@ void uverbs_user_mmap_disassociate(struct ib_uverbs_file *ufile) · 819 unmodified lines | |||
| 820 | ret = mmget_not_zero(mm); | 820 | ret = mmget_not_zero(mm); |
| 821 | if (!ret) { | 821 | if (!ret) { |
| 822 | list_del_init(&priv->list); | 822 | list_del_init(&priv->list); |
| 823 | if (priv->entry) { | ||
| 824 | rdma_user_mmap_entry_put(priv->entry); | ||
| 825 | priv->entry = NULL; | ||
| 826 | } | ||
| 823 | mm = NULL; | 827 | mm = NULL; |
| 824 | continue; | 828 | continue; |
| 825 | } | 829 | } |
| @@ -1046,7 +1046,7 @@ i40iw_sc_query_rdma_features(struct i40iw_sc_cqp *cqp, · 1045 unmodified lines | |||
| 1046 | u64 header; | 1046 | u64 header; |
| 1047 | 1047 | ||
| 1048 | wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch); | 1048 | wqe = i40iw_sc_cqp_get_next_send_wqe(cqp, scratch); |
| 1049 | if (wqe) | 1049 | if (!wqe) |
| 1050 | return I40IW_ERR_RING_FULL; | 1050 | return I40IW_ERR_RING_FULL; |
| 1051 | 1051 | ||
| 1052 | set_64bit_val(wqe, 32, feat_mem->pa); | 1052 | set_64bit_val(wqe, 32, feat_mem->pa); |
| @@ -1499,8 +1499,9 @@ static int __mlx4_ib_create_default_rules( · 1498 unmodified lines | |||
| 1499 | int i; | 1499 | int i; |
| 1500 | 1500 | ||
| 1501 | for (i = 0; i < ARRAY_SIZE(pdefault_rules->rules_create_list); i++) { | 1501 | for (i = 0; i < ARRAY_SIZE(pdefault_rules->rules_create_list); i++) { |
| 1502 | union ib_flow_spec ib_spec = {}; | ||
| 1502 | int ret; | 1503 | int ret; |
| 1503 | union ib_flow_spec ib_spec; | 1504 | |
| 1504 | switch (pdefault_rules->rules_create_list[i]) { | 1505 | switch (pdefault_rules->rules_create_list[i]) { |
| 1505 | case 0: | 1506 | case 0: |
| 1506 | /* no rule */ | 1507 | /* no rule */ |
| @@ -5558,7 +5558,9 @@ static void to_rdma_ah_attr(struct mlx5_ib_dev *ibdev, · 5557 unmodified lines | |||
| 5558 | rdma_ah_set_path_bits(ah_attr, path->grh_mlid & 0x7f); | 5558 | rdma_ah_set_path_bits(ah_attr, path->grh_mlid & 0x7f); |
| 5559 | rdma_ah_set_static_rate(ah_attr, | 5559 | rdma_ah_set_static_rate(ah_attr, |
| 5560 | path->static_rate ? path->static_rate - 5 : 0); | 5560 | path->static_rate ? path->static_rate - 5 : 0); |
| 5561 | if (path->grh_mlid & (1 << 7)) { | 5561 | |
| 5562 | if (path->grh_mlid & (1 << 7) || | ||
| 5563 | ah_attr->type == RDMA_AH_ATTR_TYPE_ROCE) { | ||
| 5562 | u32 tc_fl = be32_to_cpu(path->tclass_flowlabel); | 5564 | u32 tc_fl = be32_to_cpu(path->tclass_flowlabel); |
| 5563 | 5565 | ||
| 5564 | rdma_ah_set_grh(ah_attr, NULL, | 5566 | rdma_ah_set_grh(ah_attr, NULL, |
| @@ -248,8 +248,8 @@ int rvt_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, · 247 unmodified lines | |||
| 248 | */ | 248 | */ |
| 249 | if (udata && udata->outlen >= sizeof(__u64)) { | 249 | if (udata && udata->outlen >= sizeof(__u64)) { |
| 250 | cq->ip = rvt_create_mmap_info(rdi, sz, udata, u_wc); | 250 | cq->ip = rvt_create_mmap_info(rdi, sz, udata, u_wc); |
| 251 | if (!cq->ip) { | 251 | if (IS_ERR(cq->ip)) { |
| 252 | err = -ENOMEM; | 252 | err = PTR_ERR(cq->ip); |
| 253 | goto bail_wc; | 253 | goto bail_wc; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| @@ -154,7 +154,7 @@ done: · 153 unmodified lines | |||
| 154 | * @udata: user data (must be valid!) | 154 | * @udata: user data (must be valid!) |
| 155 | * @obj: opaque pointer to a cq, wq etc | 155 | * @obj: opaque pointer to a cq, wq etc |
| 156 | * | 156 | * |
| 157 | * Return: rvt_mmap struct on success | 157 | * Return: rvt_mmap struct on success, ERR_PTR on failure |
| 158 | */ | 158 | */ |
| 159 | struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size, | 159 | struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size, |
| 160 | struct ib_udata *udata, void *obj) | 160 | struct ib_udata *udata, void *obj) |
| @@ -166,7 +166,7 @@ struct rvt_mmap_info *rvt_create_mmap_info(struct rvt_dev_info *rdi, u32 size, · 5 unmodified lines | |||
| 166 | 166 | ||
| 167 | ip = kmalloc_node(sizeof(*ip), GFP_KERNEL, rdi->dparms.node); | 167 | ip = kmalloc_node(sizeof(*ip), GFP_KERNEL, rdi->dparms.node); |
| 168 | if (!ip) | 168 | if (!ip) |
| 169 | return ip; | 169 | return ERR_PTR(-ENOMEM); |
| 170 | 170 | ||
| 171 | size = PAGE_ALIGN(size); | 171 | size = PAGE_ALIGN(size); |
| 172 | 172 | ||
| @@ -1244,8 +1244,8 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd, · 1243 unmodified lines | |||
| 1244 | 1244 | ||
| 1245 | qp->ip = rvt_create_mmap_info(rdi, s, udata, | 1245 | qp->ip = rvt_create_mmap_info(rdi, s, udata, |
| 1246 | qp->r_rq.wq); | 1246 | qp->r_rq.wq); |
| 1247 | if (!qp->ip) { | 1247 | if (IS_ERR(qp->ip)) { |
| 1248 | ret = ERR_PTR(-ENOMEM); | 1248 | ret = ERR_CAST(qp->ip); |
| 1249 | goto bail_qpn; | 1249 | goto bail_qpn; |
| 1250 | } | 1250 | } |
| 1251 | 1251 | ||
| @@ -111,8 +111,8 @@ int rvt_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *srq_init_attr, · 110 unmodified lines | |||
| 111 | u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz; | 111 | u32 s = sizeof(struct rvt_rwq) + srq->rq.size * sz; |
| 112 | 112 | ||
| 113 | srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq); | 113 | srq->ip = rvt_create_mmap_info(dev, s, udata, srq->rq.wq); |
| 114 | if (!srq->ip) { | 114 | if (IS_ERR(srq->ip)) { |
| 115 | ret = -ENOMEM; | 115 | ret = PTR_ERR(srq->ip); |
| 116 | goto bail_wq; | 116 | goto bail_wq; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| @@ -920,20 +920,27 @@ static int siw_fastreg_mr(struct ib_pd *pd, struct siw_sqe *sqe) · 919 unmodified lines | |||
| 920 | { | 920 | { |
| 921 | struct ib_mr *base_mr = (struct ib_mr *)(uintptr_t)sqe->base_mr; | 921 | struct ib_mr *base_mr = (struct ib_mr *)(uintptr_t)sqe->base_mr; |
| 922 | struct siw_device *sdev = to_siw_dev(pd->device); | 922 | struct siw_device *sdev = to_siw_dev(pd->device); |
| 923 | struct siw_mem *mem = siw_mem_id2obj(sdev, sqe->rkey >> 8); | 923 | struct siw_mem *mem; |
| 924 | int rv = 0; | 924 | int rv = 0; |
| 925 | 925 | ||
| 926 | siw_dbg_pd(pd, "STag 0x%08x\n", sqe->rkey); | 926 | siw_dbg_pd(pd, "STag 0x%08x\n", sqe->rkey); |
| 927 | 927 | ||
| 928 | if (unlikely(!mem || !base_mr)) { | 928 | if (unlikely(!base_mr)) { |
| 929 | pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); | 929 | pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); |
| 930 | return -EINVAL; | 930 | return -EINVAL; |
| 931 | } | 931 | } |
| 932 | |||
| 932 | if (unlikely(base_mr->rkey >> 8 != sqe->rkey >> 8)) { | 933 | if (unlikely(base_mr->rkey >> 8 != sqe->rkey >> 8)) { |
| 933 | pr_warn("siw: fastreg: STag 0x%08x: bad MR\n", sqe->rkey); | 934 | pr_warn("siw: fastreg: STag 0x%08x: bad MR\n", sqe->rkey); |
| 934 | rv = -EINVAL; | 935 | return -EINVAL; |
| 935 | goto out; | ||
| 936 | } | 936 | } |
| 937 | |||
| 938 | mem = siw_mem_id2obj(sdev, sqe->rkey >> 8); | ||
| 939 | if (unlikely(!mem)) { | ||
| 940 | pr_warn("siw: fastreg: STag 0x%08x unknown\n", sqe->rkey); | ||
| 941 | return -EINVAL; | ||
| 942 | } | ||
| 943 | |||
| 937 | if (unlikely(mem->pd != pd)) { | 944 | if (unlikely(mem->pd != pd)) { |
| 938 | pr_warn("siw: fastreg: PD mismatch\n"); | 945 | pr_warn("siw: fastreg: PD mismatch\n"); |
| 939 | rv = -EINVAL; | 946 | rv = -EINVAL; |
| @@ -362,7 +362,7 @@ config IPMMU_VMSA · 361 unmodified lines | |||
| 362 | 362 | ||
| 363 | config SPAPR_TCE_IOMMU | 363 | config SPAPR_TCE_IOMMU |
| 364 | bool "sPAPR TCE IOMMU Support" | 364 | bool "sPAPR TCE IOMMU Support" |
| 365 | depends on PPC_POWERNV || PPC_PSERIES || (PPC && COMPILE_TEST) | 365 | depends on PPC_POWERNV || PPC_PSERIES |
| 366 | select IOMMU_API | 366 | select IOMMU_API |
| 367 | help | 367 | help |
| 368 | Enables bits of IOMMU API required by VFIO. The iommu_ops | 368 | Enables bits of IOMMU API required by VFIO. The iommu_ops |
| @@ -457,7 +457,7 @@ config S390_AP_IOMMU · 88 unmodified lines | |||
| 457 | 457 | ||
| 458 | config MTK_IOMMU | 458 | config MTK_IOMMU |
| 459 | bool "MTK IOMMU Support" | 459 | bool "MTK IOMMU Support" |
| 460 | depends on ARM || ARM64 || COMPILE_TEST | 460 | depends on HAS_DMA |
| 461 | depends on ARCH_MEDIATEK || COMPILE_TEST | 461 | depends on ARCH_MEDIATEK || COMPILE_TEST |
| 462 | select ARM_DMA_USE_IOMMU | 462 | select ARM_DMA_USE_IOMMU |
| 463 | select IOMMU_API | 463 | select IOMMU_API |
| @@ -2936,7 +2936,7 @@ static int __init parse_amd_iommu_intr(char *str) · 2935 unmodified lines | |||
| 2936 | { | 2936 | { |
| 2937 | for (; *str; ++str) { | 2937 | for (; *str; ++str) { |
| 2938 | if (strncmp(str, "legacy", 6) == 0) { | 2938 | if (strncmp(str, "legacy", 6) == 0) { |
| 2939 | amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY; | 2939 | amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA; |
| 2940 | break; | 2940 | break; |
| 2941 | } | 2941 | } |
| 2942 | if (strncmp(str, "vapic", 5) == 0) { | 2942 | if (strncmp(str, "vapic", 5) == 0) { |
| @@ -371,11 +371,11 @@ int dmar_disabled = 0; · 370 unmodified lines | |||
| 371 | int dmar_disabled = 1; | 371 | int dmar_disabled = 1; |
| 372 | #endif /* CONFIG_INTEL_IOMMU_DEFAULT_ON */ | 372 | #endif /* CONFIG_INTEL_IOMMU_DEFAULT_ON */ |
| 373 | 373 | ||
| 374 | #ifdef INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON | 374 | #ifdef CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON |
| 375 | int intel_iommu_sm = 1; | 375 | int intel_iommu_sm = 1; |
| 376 | #else | 376 | #else |
| 377 | int intel_iommu_sm; | 377 | int intel_iommu_sm; |
| 378 | #endif /* INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */ | 378 | #endif /* CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */ |
| 379 | 379 | ||
| 380 | int intel_iommu_enabled = 0; | 380 | int intel_iommu_enabled = 0; |
| 381 | EXPORT_SYMBOL_GPL(intel_iommu_enabled); | 381 | EXPORT_SYMBOL_GPL(intel_iommu_enabled); |
| @@ -184,6 +184,7 @@ static struct dev_iommu *dev_iommu_get(struct device *dev) · 183 unmodified lines | |||
| 184 | 184 | ||
| 185 | static void dev_iommu_free(struct device *dev) | 185 | static void dev_iommu_free(struct device *dev) |
| 186 | { | 186 | { |
| 187 | iommu_fwspec_free(dev); | ||
| 187 | kfree(dev->iommu); | 188 | kfree(dev->iommu); |
| 188 | dev->iommu = NULL; | 189 | dev->iommu = NULL; |
| 189 | } | 190 | } |
| @@ -814,8 +814,11 @@ static int qcom_iommu_device_probe(struct platform_device *pdev) · 813 unmodified lines | |||
| 814 | qcom_iommu->dev = dev; | 814 | qcom_iommu->dev = dev; |
| 815 | 815 | ||
| 816 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 816 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 817 | if (res) | 817 | if (res) { |
| 818 | qcom_iommu->local_base = devm_ioremap_resource(dev, res); | 818 | qcom_iommu->local_base = devm_ioremap_resource(dev, res); |
| 819 | if (IS_ERR(qcom_iommu->local_base)) | ||
| 820 | return PTR_ERR(qcom_iommu->local_base); | ||
| 821 | } | ||
| 819 | 822 | ||
| 820 | qcom_iommu->iface_clk = devm_clk_get(dev, "iface"); | 823 | qcom_iommu->iface_clk = devm_clk_get(dev, "iface"); |
| 821 | if (IS_ERR(qcom_iommu->iface_clk)) { | 824 | if (IS_ERR(qcom_iommu->iface_clk)) { |
| @@ -585,10 +585,12 @@ static struct pgpath *__map_bio(struct multipath *m, struct bio *bio) · 584 unmodified lines | |||
| 585 | 585 | ||
| 586 | /* Do we need to select a new pgpath? */ | 586 | /* Do we need to select a new pgpath? */ |
| 587 | pgpath = READ_ONCE(m->current_pgpath); | 587 | pgpath = READ_ONCE(m->current_pgpath); |
| 588 | queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); | 588 | if (!pgpath || !test_bit(MPATHF_QUEUE_IO, &m->flags)) |
| 589 | if (!pgpath || !queue_io) | ||
| 590 | pgpath = choose_pgpath(m, bio->bi_iter.bi_size); | 589 | pgpath = choose_pgpath(m, bio->bi_iter.bi_size); |
| 591 | 590 | ||
| 591 | /* MPATHF_QUEUE_IO might have been cleared by choose_pgpath. */ | ||
| 592 | queue_io = test_bit(MPATHF_QUEUE_IO, &m->flags); | ||
| 593 | |||
| 592 | if ((pgpath && queue_io) || | 594 | if ((pgpath && queue_io) || |
| 593 | (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) { | 595 | (!pgpath && test_bit(MPATHF_QUEUE_IF_NO_PATH, &m->flags))) { |
| 594 | /* Queue for the daemon to resubmit */ | 596 | /* Queue for the daemon to resubmit */ |
| @@ -435,7 +435,7 @@ int verity_fec_decode(struct dm_verity *v, struct dm_verity_io *io, · 434 unmodified lines | |||
| 435 | fio->level++; | 435 | fio->level++; |
| 436 | 436 | ||
| 437 | if (type == DM_VERITY_BLOCK_TYPE_METADATA) | 437 | if (type == DM_VERITY_BLOCK_TYPE_METADATA) |
| 438 | block += v->data_blocks; | 438 | block = block - v->hash_start + v->data_blocks; |
| 439 | 439 | ||
| 440 | /* | 440 | /* |
| 441 | * For RS(M, N), the continuous FEC data is divided into blocks of N | 441 | * For RS(M, N), the continuous FEC data is divided into blocks of N |
| @@ -931,6 +931,24 @@ static int writecache_alloc_entries(struct dm_writecache *wc) · 930 unmodified lines | |||
| 931 | return 0; | 931 | return 0; |
| 932 | } | 932 | } |
| 933 | 933 | ||
| 934 | static int writecache_read_metadata(struct dm_writecache *wc, sector_t n_sectors) | ||
| 935 | { | ||
| 936 | struct dm_io_region region; | ||
| 937 | struct dm_io_request req; | ||
| 938 | |||
| 939 | region.bdev = wc->ssd_dev->bdev; | ||
| 940 | region.sector = wc->start_sector; | ||
| 941 | region.count = n_sectors; | ||
| 942 | req.bi_op = REQ_OP_READ; | ||
| 943 | req.bi_op_flags = REQ_SYNC; | ||
| 944 | req.mem.type = DM_IO_VMA; | ||
| 945 | req.mem.ptr.vma = (char *)wc->memory_map; | ||
| 946 | req.client = wc->dm_io; | ||
| 947 | req.notify.fn = NULL; | ||
| 948 | |||
| 949 | return dm_io(&req, 1, ®ion, NULL); | ||
| 950 | } | ||
| 951 | |||
| 934 | static void writecache_resume(struct dm_target *ti) | 952 | static void writecache_resume(struct dm_target *ti) |
| 935 | { | 953 | { |
| 936 | struct dm_writecache *wc = ti->private; | 954 | struct dm_writecache *wc = ti->private; |
| @@ -941,8 +959,18 @@ static void writecache_resume(struct dm_target *ti) · 4 unmodified lines | |||
| 941 | 959 | ||
| 942 | wc_lock(wc); | 960 | wc_lock(wc); |
| 943 | 961 | ||
| 944 | if (WC_MODE_PMEM(wc)) | 962 | if (WC_MODE_PMEM(wc)) { |
| 945 | persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size); | 963 | persistent_memory_invalidate_cache(wc->memory_map, wc->memory_map_size); |
| 964 | } else { | ||
| 965 | r = writecache_read_metadata(wc, wc->metadata_sectors); | ||
| 966 | if (r) { | ||
| 967 | size_t sb_entries_offset; | ||
| 968 | writecache_error(wc, r, "unable to read metadata: %d", r); | ||
| 969 | sb_entries_offset = offsetof(struct wc_memory_superblock, entries); | ||
| 970 | memset((char *)wc->memory_map + sb_entries_offset, -1, | ||
| 971 | (wc->metadata_sectors << SECTOR_SHIFT) - sb_entries_offset); | ||
| 972 | } | ||
| 973 | } | ||
| 946 | 974 | ||
| 947 | wc->tree = RB_ROOT; | 975 | wc->tree = RB_ROOT; |
| 948 | INIT_LIST_HEAD(&wc->lru); | 976 | INIT_LIST_HEAD(&wc->lru); |
| @@ -2102,6 +2130,12 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) · 1153 unmodified lines | |||
| 2102 | ti->error = "Invalid block size"; | 2130 | ti->error = "Invalid block size"; |
| 2103 | goto bad; | 2131 | goto bad; |
| 2104 | } | 2132 | } |
| 2133 | if (wc->block_size < bdev_logical_block_size(wc->dev->bdev) || | ||
| 2134 | wc->block_size < bdev_logical_block_size(wc->ssd_dev->bdev)) { | ||
| 2135 | r = -EINVAL; | ||
| 2136 | ti->error = "Block size is smaller than device logical block size"; | ||
| 2137 | goto bad; | ||
| 2138 | } | ||
| 2105 | wc->block_size_bits = __ffs(wc->block_size); | 2139 | wc->block_size_bits = __ffs(wc->block_size); |
| 2106 | 2140 | ||
| 2107 | wc->max_writeback_jobs = MAX_WRITEBACK_JOBS; | 2141 | wc->max_writeback_jobs = MAX_WRITEBACK_JOBS; |
| @@ -2200,8 +2234,6 @@ invalid_optional: · 92 unmodified lines | |||
| 2200 | goto bad; | 2234 | goto bad; |
| 2201 | } | 2235 | } |
| 2202 | } else { | 2236 | } else { |
| 2203 | struct dm_io_region region; | ||
| 2204 | struct dm_io_request req; | ||
| 2205 | size_t n_blocks, n_metadata_blocks; | 2237 | size_t n_blocks, n_metadata_blocks; |
| 2206 | uint64_t n_bitmap_bits; | 2238 | uint64_t n_bitmap_bits; |
| 2207 | 2239 | ||
| @@ -2258,19 +2290,9 @@ invalid_optional: · 50 unmodified lines | |||
| 2258 | goto bad; | 2290 | goto bad; |
| 2259 | } | 2291 | } |
| 2260 | 2292 | ||
| 2261 | region.bdev = wc->ssd_dev->bdev; | 2293 | r = writecache_read_metadata(wc, wc->block_size >> SECTOR_SHIFT); |
| 2262 | region.sector = wc->start_sector; | ||
| 2263 | region.count = wc->metadata_sectors; | ||
| 2264 | req.bi_op = REQ_OP_READ; | ||
| 2265 | req.bi_op_flags = REQ_SYNC; | ||
| 2266 | req.mem.type = DM_IO_VMA; | ||
| 2267 | req.mem.ptr.vma = (char *)wc->memory_map; | ||
| 2268 | req.client = wc->dm_io; | ||
| 2269 | req.notify.fn = NULL; | ||
| 2270 | |||
| 2271 | r = dm_io(&req, 1, ®ion, NULL); | ||
| 2272 | if (r) { | 2294 | if (r) { |
| 2273 | ti->error = "Unable to read metadata"; | 2295 | ti->error = "Unable to read first block of metadata"; |
| 2274 | goto bad; | 2296 | goto bad; |
| 2275 | } | 2297 | } |
| 2276 | } | 2298 | } |
| @@ -878,7 +878,7 @@ static int mmc_send_hpi_cmd(struct mmc_card *card) · 877 unmodified lines | |||
| 878 | * Issued High Priority Interrupt, and check for card status | 878 | * Issued High Priority Interrupt, and check for card status |
| 879 | * until out-of prg-state. | 879 | * until out-of prg-state. |
| 880 | */ | 880 | */ |
| 881 | int mmc_interrupt_hpi(struct mmc_card *card) | 881 | static int mmc_interrupt_hpi(struct mmc_card *card) |
| 882 | { | 882 | { |
| 883 | int err; | 883 | int err; |
| 884 | u32 status; | 884 | u32 status; |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | |||
| 5 | #include <linux/delay.h> | 5 | #include <linux/delay.h> |
| 6 | #include <linux/highmem.h> | 6 | #include <linux/highmem.h> |
| 7 | #include <linux/io.h> | 7 | #include <linux/io.h> |
| 8 | #include <linux/iopoll.h> | ||
| 8 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 9 | #include <linux/dma-mapping.h> | 10 | #include <linux/dma-mapping.h> |
| 10 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
| @@ -349,12 +350,16 @@ static int cqhci_enable(struct mmc_host *mmc, struct mmc_card *card) · 338 unmodified lines | |||
| 349 | /* CQHCI is idle and should halt immediately, so set a small timeout */ | 350 | /* CQHCI is idle and should halt immediately, so set a small timeout */ |
| 350 | #define CQHCI_OFF_TIMEOUT 100 | 351 | #define CQHCI_OFF_TIMEOUT 100 |
| 351 | 352 | ||
| 353 | static u32 cqhci_read_ctl(struct cqhci_host *cq_host) | ||
| 354 | { | ||
| 355 | return cqhci_readl(cq_host, CQHCI_CTL); | ||
| 356 | } | ||
| 357 | |||
| 352 | static void cqhci_off(struct mmc_host *mmc) | 358 | static void cqhci_off(struct mmc_host *mmc) |
| 353 | { | 359 | { |
| 354 | struct cqhci_host *cq_host = mmc->cqe_private; | 360 | struct cqhci_host *cq_host = mmc->cqe_private; |
| 355 | ktime_t timeout; | ||
| 356 | bool timed_out; | ||
| 357 | u32 reg; | 361 | u32 reg; |
| 362 | int err; | ||
| 358 | 363 | ||
| 359 | if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt) | 364 | if (!cq_host->enabled || !mmc->cqe_on || cq_host->recovery_halt) |
| 360 | return; | 365 | return; |
| @@ -364,15 +369,9 @@ static void cqhci_off(struct mmc_host *mmc) · 3 unmodified lines | |||
| 364 | 369 | ||
| 365 | cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL); | 370 | cqhci_writel(cq_host, CQHCI_HALT, CQHCI_CTL); |
| 366 | 371 | ||
| 367 | timeout = ktime_add_us(ktime_get(), CQHCI_OFF_TIMEOUT); | 372 | err = readx_poll_timeout(cqhci_read_ctl, cq_host, reg, |
| 368 | while (1) { | 373 | reg & CQHCI_HALT, 0, CQHCI_OFF_TIMEOUT); |
| 369 | timed_out = ktime_compare(ktime_get(), timeout) > 0; | 374 | if (err < 0) |
| 370 | reg = cqhci_readl(cq_host, CQHCI_CTL); | ||
| 371 | if ((reg & CQHCI_HALT) || timed_out) | ||
| 372 | break; | ||
| 373 | } | ||
| 374 | |||
| 375 | if (timed_out) | ||
| 376 | pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc)); | 375 | pr_err("%s: cqhci: CQE stuck on\n", mmc_hostname(mmc)); |
| 377 | else | 376 | else |
| 378 | pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc)); | 377 | pr_debug("%s: cqhci: CQE off\n", mmc_hostname(mmc)); |
| @@ -357,14 +357,6 @@ static void meson_mx_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) · 356 unmodified lines | |||
| 357 | meson_mx_mmc_start_cmd(mmc, mrq->cmd); | 357 | meson_mx_mmc_start_cmd(mmc, mrq->cmd); |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | static int meson_mx_mmc_card_busy(struct mmc_host *mmc) | ||
| 361 | { | ||
| 362 | struct meson_mx_mmc_host *host = mmc_priv(mmc); | ||
| 363 | u32 irqc = readl(host->base + MESON_MX_SDIO_IRQC); | ||
| 364 | |||
| 365 | return !!(irqc & MESON_MX_SDIO_IRQC_FORCE_DATA_DAT_MASK); | ||
| 366 | } | ||
| 367 | |||
| 368 | static void meson_mx_mmc_read_response(struct mmc_host *mmc, | 360 | static void meson_mx_mmc_read_response(struct mmc_host *mmc, |
| 369 | struct mmc_command *cmd) | 361 | struct mmc_command *cmd) |
| 370 | { | 362 | { |
| @@ -506,7 +498,6 @@ static void meson_mx_mmc_timeout(struct timer_list *t) · 135 unmodified lines | |||
| 506 | static struct mmc_host_ops meson_mx_mmc_ops = { | 498 | static struct mmc_host_ops meson_mx_mmc_ops = { |
| 507 | .request = meson_mx_mmc_request, | 499 | .request = meson_mx_mmc_request, |
| 508 | .set_ios = meson_mx_mmc_set_ios, | 500 | .set_ios = meson_mx_mmc_set_ios, |
| 509 | .card_busy = meson_mx_mmc_card_busy, | ||
| 510 | .get_cd = mmc_gpio_get_cd, | 501 | .get_cd = mmc_gpio_get_cd, |
| 511 | .get_ro = mmc_gpio_get_ro, | 502 | .get_ro = mmc_gpio_get_ro, |
| 512 | }; | 503 | }; |
| @@ -570,7 +561,7 @@ static int meson_mx_mmc_add_host(struct meson_mx_mmc_host *host) · 57 unmodified lines | |||
| 570 | mmc->f_max = clk_round_rate(host->cfg_div_clk, | 561 | mmc->f_max = clk_round_rate(host->cfg_div_clk, |
| 571 | clk_get_rate(host->parent_clk)); | 562 | clk_get_rate(host->parent_clk)); |
| 572 | 563 | ||
| 573 | mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; | 564 | mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23 | MMC_CAP_WAIT_WHILE_BUSY; |
| 574 | mmc->ops = &meson_mx_mmc_ops; | 565 | mmc->ops = &meson_mx_mmc_ops; |
| 575 | 566 | ||
| 576 | ret = mmc_of_parse(mmc); | 567 | ret = mmc_of_parse(mmc); |
| @@ -2087,6 +2087,8 @@ static int sdhci_msm_probe(struct platform_device *pdev) · 2086 unmodified lines | |||
| 2087 | goto clk_disable; | 2087 | goto clk_disable; |
| 2088 | } | 2088 | } |
| 2089 | 2089 | ||
| 2090 | msm_host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; | ||
| 2091 | |||
| 2090 | pm_runtime_get_noresume(&pdev->dev); | 2092 | pm_runtime_get_noresume(&pdev->dev); |
| 2091 | pm_runtime_set_active(&pdev->dev); | 2093 | pm_runtime_set_active(&pdev->dev); |
| 2092 | pm_runtime_enable(&pdev->dev); | 2094 | pm_runtime_enable(&pdev->dev); |
| @@ -601,6 +601,9 @@ static int intel_select_drive_strength(struct mmc_card *card, · 600 unmodified lines | |||
| 601 | struct sdhci_pci_slot *slot = sdhci_priv(host); | 601 | struct sdhci_pci_slot *slot = sdhci_priv(host); |
| 602 | struct intel_host *intel_host = sdhci_pci_priv(slot); | 602 | struct intel_host *intel_host = sdhci_pci_priv(slot); |
| 603 | 603 | ||
| 604 | if (!(mmc_driver_type_mask(intel_host->drv_strength) & card_drv)) | ||
| 605 | return 0; | ||
| 606 | |||
| 604 | return intel_host->drv_strength; | 607 | return intel_host->drv_strength; |
| 605 | } | 608 | } |
| 606 | 609 | ||
| @@ -235,6 +235,16 @@ static void xenon_voltage_switch(struct sdhci_host *host) · 234 unmodified lines | |||
| 235 | { | 235 | { |
| 236 | /* Wait for 5ms after set 1.8V signal enable bit */ | 236 | /* Wait for 5ms after set 1.8V signal enable bit */ |
| 237 | usleep_range(5000, 5500); | 237 | usleep_range(5000, 5500); |
| 238 | |||
| 239 | /* | ||
| 240 | * For some reason the controller's Host Control2 register reports | ||
| 241 | * the bit representing 1.8V signaling as 0 when read after it was | ||
| 242 | * written as 1. Subsequent read reports 1. | ||
| 243 | * | ||
| 244 | * Since this may cause some issues, do an empty read of the Host | ||
| 245 | * Control2 register here to circumvent this. | ||
| 246 | */ | ||
| 247 | sdhci_readw(host, SDHCI_HOST_CONTROL2); | ||
| 238 | } | 248 | } |
| 239 | 249 | ||
| 240 | static const struct sdhci_ops sdhci_xenon_ops = { | 250 | static const struct sdhci_ops sdhci_xenon_ops = { |
| @@ -3642,6 +3642,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid) · 3641 unmodified lines | |||
| 3642 | 3642 | ||
| 3643 | return; | 3643 | return; |
| 3644 | out_put_disk: | 3644 | out_put_disk: |
| 3645 | /* prevent double queue cleanup */ | ||
| 3646 | ns->disk->queue = NULL; | ||
| 3645 | put_disk(ns->disk); | 3647 | put_disk(ns->disk); |
| 3646 | out_unlink_ns: | 3648 | out_unlink_ns: |
| 3647 | mutex_lock(&ctrl->subsys->lock); | 3649 | mutex_lock(&ctrl->subsys->lock); |
| @@ -3732,6 +3732,13 @@ qla2x00_remove_one(struct pci_dev *pdev) · 3731 unmodified lines | |||
| 3732 | } | 3732 | } |
| 3733 | qla2x00_wait_for_hba_ready(base_vha); | 3733 | qla2x00_wait_for_hba_ready(base_vha); |
| 3734 | 3734 | ||
| 3735 | /* | ||
| 3736 | * if UNLOADING flag is already set, then continue unload, | ||
| 3737 | * where it was set first. | ||
| 3738 | */ | ||
| 3739 | if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) | ||
| 3740 | return; | ||
| 3741 | |||
| 3735 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || | 3742 | if (IS_QLA25XX(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) || |
| 3736 | IS_QLA28XX(ha)) { | 3743 | IS_QLA28XX(ha)) { |
| 3737 | if (ha->flags.fw_started) | 3744 | if (ha->flags.fw_started) |
| @@ -3750,15 +3757,6 @@ qla2x00_remove_one(struct pci_dev *pdev) · 12 unmodified lines | |||
| 3750 | 3757 | ||
| 3751 | qla2x00_wait_for_sess_deletion(base_vha); | 3758 | qla2x00_wait_for_sess_deletion(base_vha); |
| 3752 | 3759 | ||
| 3753 | /* | ||
| 3754 | * if UNLOAD flag is already set, then continue unload, | ||
| 3755 | * where it was set first. | ||
| 3756 | */ | ||
| 3757 | if (test_bit(UNLOADING, &base_vha->dpc_flags)) | ||
| 3758 | return; | ||
| 3759 | |||
| 3760 | set_bit(UNLOADING, &base_vha->dpc_flags); | ||
| 3761 | |||
| 3762 | qla_nvme_delete(base_vha); | 3760 | qla_nvme_delete(base_vha); |
| 3763 | 3761 | ||
| 3764 | dma_free_coherent(&ha->pdev->dev, | 3762 | dma_free_coherent(&ha->pdev->dev, |
| @@ -4864,6 +4862,9 @@ qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type) · 1099 unmodified lines | |||
| 4864 | struct qla_work_evt *e; | 4862 | struct qla_work_evt *e; |
| 4865 | uint8_t bail; | 4863 | uint8_t bail; |
| 4866 | 4864 | ||
| 4865 | if (test_bit(UNLOADING, &vha->dpc_flags)) | ||
| 4866 | return NULL; | ||
| 4867 | |||
| 4867 | QLA_VHA_MARK_BUSY(vha, bail); | 4868 | QLA_VHA_MARK_BUSY(vha, bail); |
| 4868 | if (bail) | 4869 | if (bail) |
| 4869 | return NULL; | 4870 | return NULL; |
| @@ -6628,13 +6629,6 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) · 1758 unmodified lines | |||
| 6628 | struct pci_dev *pdev = ha->pdev; | 6629 | struct pci_dev *pdev = ha->pdev; |
| 6629 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | 6630 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); |
| 6630 | 6631 | ||
| 6631 | /* | ||
| 6632 | * if UNLOAD flag is already set, then continue unload, | ||
| 6633 | * where it was set first. | ||
| 6634 | */ | ||
| 6635 | if (test_bit(UNLOADING, &base_vha->dpc_flags)) | ||
| 6636 | return; | ||
| 6637 | |||
| 6638 | ql_log(ql_log_warn, base_vha, 0x015b, | 6632 | ql_log(ql_log_warn, base_vha, 0x015b, |
| 6639 | "Disabling adapter.\n"); | 6633 | "Disabling adapter.\n"); |
| 6640 | 6634 | ||
| @@ -6645,9 +6639,14 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work) · 4 unmodified lines | |||
| 6645 | return; | 6639 | return; |
| 6646 | } | 6640 | } |
| 6647 | 6641 | ||
| 6648 | qla2x00_wait_for_sess_deletion(base_vha); | 6642 | /* |
| 6643 | * if UNLOADING flag is already set, then continue unload, | ||
| 6644 | * where it was set first. | ||
| 6645 | */ | ||
| 6646 | if (test_and_set_bit(UNLOADING, &base_vha->dpc_flags)) | ||
| 6647 | return; | ||
| 6649 | 6648 | ||
| 6650 | set_bit(UNLOADING, &base_vha->dpc_flags); | 6649 | qla2x00_wait_for_sess_deletion(base_vha); |
| 6651 | 6650 | ||
| 6652 | qla2x00_delete_all_vps(ha, base_vha); | 6651 | qla2x00_delete_all_vps(ha, base_vha); |
| 6653 | 6652 | ||
| @@ -2284,6 +2284,7 @@ scsi_device_set_state(struct scsi_device *sdev, enum scsi_device_state state) · 2283 unmodified lines | |||
| 2284 | switch (oldstate) { | 2284 | switch (oldstate) { |
| 2285 | case SDEV_RUNNING: | 2285 | case SDEV_RUNNING: |
| 2286 | case SDEV_CREATED_BLOCK: | 2286 | case SDEV_CREATED_BLOCK: |
| 2287 | case SDEV_QUIESCE: | ||
| 2287 | case SDEV_OFFLINE: | 2288 | case SDEV_OFFLINE: |
| 2288 | break; | 2289 | break; |
| 2289 | default: | 2290 | default: |
| @@ -432,7 +432,7 @@ iblock_execute_zero_out(struct block_device *bdev, struct se_cmd *cmd) · 431 unmodified lines | |||
| 432 | target_to_linux_sector(dev, cmd->t_task_lba), | 432 | target_to_linux_sector(dev, cmd->t_task_lba), |
| 433 | target_to_linux_sector(dev, | 433 | target_to_linux_sector(dev, |
| 434 | sbc_get_write_same_sectors(cmd)), | 434 | sbc_get_write_same_sectors(cmd)), |
| 435 | GFP_KERNEL, false); | 435 | GFP_KERNEL, BLKDEV_ZERO_NOUNMAP); |
| 436 | if (ret) | 436 | if (ret) |
| 437 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 437 | return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
| 438 | 438 | ||
| @@ -88,7 +88,7 @@ config HVC_DCC · 87 unmodified lines | |||
| 88 | 88 | ||
| 89 | config HVC_RISCV_SBI | 89 | config HVC_RISCV_SBI |
| 90 | bool "RISC-V SBI console support" | 90 | bool "RISC-V SBI console support" |
| 91 | depends on RISCV_SBI | 91 | depends on RISCV_SBI_V01 |
| 92 | select HVC_DRIVER | 92 | select HVC_DRIVER |
| 93 | help | 93 | help |
| 94 | This enables support for console output via RISC-V SBI calls, which | 94 | This enables support for console output via RISC-V SBI calls, which |
| @@ -86,7 +86,7 @@ config SERIAL_EARLYCON_ARM_SEMIHOST · 85 unmodified lines | |||
| 86 | 86 | ||
| 87 | config SERIAL_EARLYCON_RISCV_SBI | 87 | config SERIAL_EARLYCON_RISCV_SBI |
| 88 | bool "Early console using RISC-V SBI" | 88 | bool "Early console using RISC-V SBI" |
| 89 | depends on RISCV_SBI | 89 | depends on RISCV_SBI_V01 |
| 90 | select SERIAL_CORE | 90 | select SERIAL_CORE |
| 91 | select SERIAL_CORE_CONSOLE | 91 | select SERIAL_CORE_CONSOLE |
| 92 | select SERIAL_EARLYCON | 92 | select SERIAL_EARLYCON |
| @@ -342,8 +342,8 @@ static int vaddr_get_pfn(struct mm_struct *mm, unsigned long vaddr, · 341 unmodified lines | |||
| 342 | vma = find_vma_intersection(mm, vaddr, vaddr + 1); | 342 | vma = find_vma_intersection(mm, vaddr, vaddr + 1); |
| 343 | 343 | ||
| 344 | if (vma && vma->vm_flags & VM_PFNMAP) { | 344 | if (vma && vma->vm_flags & VM_PFNMAP) { |
| 345 | *pfn = ((vaddr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; | 345 | if (!follow_pfn(vma, vaddr, pfn) && |
| 346 | if (is_invalid_reserved_pfn(*pfn)) | 346 | is_invalid_reserved_pfn(*pfn)) |
| 347 | ret = 0; | 347 | ret = 0; |
| 348 | } | 348 | } |
| 349 | done: | 349 | done: |
| @@ -555,7 +555,7 @@ static int vfio_iommu_type1_pin_pages(void *iommu_data, · 205 unmodified lines | |||
| 555 | continue; | 555 | continue; |
| 556 | } | 556 | } |
| 557 | 557 | ||
| 558 | remote_vaddr = dma->vaddr + iova - dma->iova; | 558 | remote_vaddr = dma->vaddr + (iova - dma->iova); |
| 559 | ret = vfio_pin_page_external(dma, remote_vaddr, &phys_pfn[i], | 559 | ret = vfio_pin_page_external(dma, remote_vaddr, &phys_pfn[i], |
| 560 | do_accounting); | 560 | do_accounting); |
| 561 | if (ret) | 561 | if (ret) |
| @@ -2345,10 +2345,10 @@ static int vfio_iommu_type1_dma_rw_chunk(struct vfio_iommu *iommu, · 1783 unmodified lines | |||
| 2345 | vaddr = dma->vaddr + offset; | 2345 | vaddr = dma->vaddr + offset; |
| 2346 | 2346 | ||
| 2347 | if (write) | 2347 | if (write) |
| 2348 | *copied = __copy_to_user((void __user *)vaddr, data, | 2348 | *copied = copy_to_user((void __user *)vaddr, data, |
| 2349 | count) ? 0 : count; | 2349 | count) ? 0 : count; |
| 2350 | else | 2350 | else |
| 2351 | *copied = __copy_from_user(data, (void __user *)vaddr, | 2351 | *copied = copy_from_user(data, (void __user *)vaddr, |
| 2352 | count) ? 0 : count; | 2352 | count) ? 0 : count; |
| 2353 | if (kthread) | 2353 | if (kthread) |
| 2354 | unuse_mm(mm); | 2354 | unuse_mm(mm); |
| @@ -391,7 +391,7 @@ static int is_shared_data_backref(struct preftrees *preftrees, u64 bytenr) · 390 unmodified lines | |||
| 391 | struct rb_node **p = &preftrees->direct.root.rb_root.rb_node; | 391 | struct rb_node **p = &preftrees->direct.root.rb_root.rb_node; |
| 392 | struct rb_node *parent = NULL; | 392 | struct rb_node *parent = NULL; |
| 393 | struct prelim_ref *ref = NULL; | 393 | struct prelim_ref *ref = NULL; |
| 394 | struct prelim_ref target = {0}; | 394 | struct prelim_ref target = {}; |
| 395 | int result; | 395 | int result; |
| 396 | 396 | ||
| 397 | target.parent = bytenr; | 397 | target.parent = bytenr; |
| @@ -916,7 +916,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 915 unmodified lines | |||
| 916 | path = btrfs_alloc_path(); | 916 | path = btrfs_alloc_path(); |
| 917 | if (!path) { | 917 | if (!path) { |
| 918 | ret = -ENOMEM; | 918 | ret = -ENOMEM; |
| 919 | goto out; | 919 | goto out_put_group; |
| 920 | } | 920 | } |
| 921 | 921 | ||
| 922 | /* | 922 | /* |
| @@ -954,7 +954,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 31 unmodified lines | |||
| 954 | ret = btrfs_orphan_add(trans, BTRFS_I(inode)); | 954 | ret = btrfs_orphan_add(trans, BTRFS_I(inode)); |
| 955 | if (ret) { | 955 | if (ret) { |
| 956 | btrfs_add_delayed_iput(inode); | 956 | btrfs_add_delayed_iput(inode); |
| 957 | goto out; | 957 | goto out_put_group; |
| 958 | } | 958 | } |
| 959 | clear_nlink(inode); | 959 | clear_nlink(inode); |
| 960 | /* One for the block groups ref */ | 960 | /* One for the block groups ref */ |
| @@ -977,13 +977,13 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 16 unmodified lines | |||
| 977 | 977 | ||
| 978 | ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); | 978 | ret = btrfs_search_slot(trans, tree_root, &key, path, -1, 1); |
| 979 | if (ret < 0) | 979 | if (ret < 0) |
| 980 | goto out; | 980 | goto out_put_group; |
| 981 | if (ret > 0) | 981 | if (ret > 0) |
| 982 | btrfs_release_path(path); | 982 | btrfs_release_path(path); |
| 983 | if (ret == 0) { | 983 | if (ret == 0) { |
| 984 | ret = btrfs_del_item(trans, tree_root, path); | 984 | ret = btrfs_del_item(trans, tree_root, path); |
| 985 | if (ret) | 985 | if (ret) |
| 986 | goto out; | 986 | goto out_put_group; |
| 987 | btrfs_release_path(path); | 987 | btrfs_release_path(path); |
| 988 | } | 988 | } |
| 989 | 989 | ||
| @@ -1102,9 +1102,9 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 112 unmodified lines | |||
| 1102 | 1102 | ||
| 1103 | ret = remove_block_group_free_space(trans, block_group); | 1103 | ret = remove_block_group_free_space(trans, block_group); |
| 1104 | if (ret) | 1104 | if (ret) |
| 1105 | goto out; | 1105 | goto out_put_group; |
| 1106 | 1106 | ||
| 1107 | btrfs_put_block_group(block_group); | 1107 | /* Once for the block groups rbtree */ |
| 1108 | btrfs_put_block_group(block_group); | 1108 | btrfs_put_block_group(block_group); |
| 1109 | 1109 | ||
| 1110 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 1110 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
| @@ -1127,6 +1127,10 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, · 16 unmodified lines | |||
| 1127 | /* once for the tree */ | 1127 | /* once for the tree */ |
| 1128 | free_extent_map(em); | 1128 | free_extent_map(em); |
| 1129 | } | 1129 | } |
| 1130 | |||
| 1131 | out_put_group: | ||
| 1132 | /* Once for the lookup reference */ | ||
| 1133 | btrfs_put_block_group(block_group); | ||
| 1130 | out: | 1134 | out: |
| 1131 | if (remove_rsv) | 1135 | if (remove_rsv) |
| 1132 | btrfs_delayed_refs_rsv_release(fs_info, 1); | 1136 | btrfs_delayed_refs_rsv_release(fs_info, 1); |
| @@ -1288,11 +1292,15 @@ static bool clean_pinned_extents(struct btrfs_trans_handle *trans, · 155 unmodified lines | |||
| 1288 | if (ret) | 1292 | if (ret) |
| 1289 | goto err; | 1293 | goto err; |
| 1290 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); | 1294 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); |
| 1295 | if (prev_trans) | ||
| 1296 | btrfs_put_transaction(prev_trans); | ||
| 1291 | 1297 | ||
| 1292 | return true; | 1298 | return true; |
| 1293 | 1299 | ||
| 1294 | err: | 1300 | err: |
| 1295 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); | 1301 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); |
| 1302 | if (prev_trans) | ||
| 1303 | btrfs_put_transaction(prev_trans); | ||
| 1296 | btrfs_dec_block_group_ro(bg); | 1304 | btrfs_dec_block_group_ro(bg); |
| 1297 | return false; | 1305 | return false; |
| 1298 | } | 1306 | } |
| @@ -1,4 +1,4 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | ||
| 3 | #ifndef BTRFS_DISCARD_H | 3 | #ifndef BTRFS_DISCARD_H |
| 4 | #define BTRFS_DISCARD_H | 4 | #define BTRFS_DISCARD_H |
| @@ -2036,9 +2036,6 @@ void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info) · 2035 unmodified lines | |||
| 2036 | for (i = 0; i < ret; i++) | 2036 | for (i = 0; i < ret; i++) |
| 2037 | btrfs_drop_and_free_fs_root(fs_info, gang[i]); | 2037 | btrfs_drop_and_free_fs_root(fs_info, gang[i]); |
| 2038 | } | 2038 | } |
| 2039 | |||
| 2040 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) | ||
| 2041 | btrfs_free_log_root_tree(NULL, fs_info); | ||
| 2042 | } | 2039 | } |
| 2043 | 2040 | ||
| 2044 | static void btrfs_init_scrub(struct btrfs_fs_info *fs_info) | 2041 | static void btrfs_init_scrub(struct btrfs_fs_info *fs_info) |
| @@ -3888,7 +3885,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, · 1843 unmodified lines | |||
| 3888 | spin_unlock(&fs_info->fs_roots_radix_lock); | 3885 | spin_unlock(&fs_info->fs_roots_radix_lock); |
| 3889 | 3886 | ||
| 3890 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { | 3887 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { |
| 3891 | btrfs_free_log(NULL, root); | 3888 | ASSERT(root->log_root == NULL); |
| 3892 | if (root->reloc_root) { | 3889 | if (root->reloc_root) { |
| 3893 | btrfs_put_root(root->reloc_root); | 3890 | btrfs_put_root(root->reloc_root); |
| 3894 | root->reloc_root = NULL; | 3891 | root->reloc_root = NULL; |
| @@ -4211,6 +4208,36 @@ static void btrfs_error_commit_super(struct btrfs_fs_info *fs_info) · 316 unmodified lines | |||
| 4211 | up_write(&fs_info->cleanup_work_sem); | 4208 | up_write(&fs_info->cleanup_work_sem); |
| 4212 | } | 4209 | } |
| 4213 | 4210 | ||
| 4211 | static void btrfs_drop_all_logs(struct btrfs_fs_info *fs_info) | ||
| 4212 | { | ||
| 4213 | struct btrfs_root *gang[8]; | ||
| 4214 | u64 root_objectid = 0; | ||
| 4215 | int ret; | ||
| 4216 | |||
| 4217 | spin_lock(&fs_info->fs_roots_radix_lock); | ||
| 4218 | while ((ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, | ||
| 4219 | (void **)gang, root_objectid, | ||
| 4220 | ARRAY_SIZE(gang))) != 0) { | ||
| 4221 | int i; | ||
| 4222 | |||
| 4223 | for (i = 0; i < ret; i++) | ||
| 4224 | gang[i] = btrfs_grab_root(gang[i]); | ||
| 4225 | spin_unlock(&fs_info->fs_roots_radix_lock); | ||
| 4226 | |||
| 4227 | for (i = 0; i < ret; i++) { | ||
| 4228 | if (!gang[i]) | ||
| 4229 | continue; | ||
| 4230 | root_objectid = gang[i]->root_key.objectid; | ||
| 4231 | btrfs_free_log(NULL, gang[i]); | ||
| 4232 | btrfs_put_root(gang[i]); | ||
| 4233 | } | ||
| 4234 | root_objectid++; | ||
| 4235 | spin_lock(&fs_info->fs_roots_radix_lock); | ||
| 4236 | } | ||
| 4237 | spin_unlock(&fs_info->fs_roots_radix_lock); | ||
| 4238 | btrfs_free_log_root_tree(NULL, fs_info); | ||
| 4239 | } | ||
| 4240 | |||
| 4214 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root) | 4241 | static void btrfs_destroy_ordered_extents(struct btrfs_root *root) |
| 4215 | { | 4242 | { |
| 4216 | struct btrfs_ordered_extent *ordered; | 4243 | struct btrfs_ordered_extent *ordered; |
| @@ -4603,6 +4630,7 @@ static int btrfs_cleanup_transaction(struct btrfs_fs_info *fs_info) · 386 unmodified lines | |||
| 4603 | btrfs_destroy_delayed_inodes(fs_info); | 4630 | btrfs_destroy_delayed_inodes(fs_info); |
| 4604 | btrfs_assert_delayed_root_empty(fs_info); | 4631 | btrfs_assert_delayed_root_empty(fs_info); |
| 4605 | btrfs_destroy_all_delalloc_inodes(fs_info); | 4632 | btrfs_destroy_all_delalloc_inodes(fs_info); |
| 4633 | btrfs_drop_all_logs(fs_info); | ||
| 4606 | mutex_unlock(&fs_info->transaction_kthread_mutex); | 4634 | mutex_unlock(&fs_info->transaction_kthread_mutex); |
| 4607 | 4635 | ||
| 4608 | return 0; | 4636 | return 0; |
| @@ -4559,6 +4559,7 @@ int btrfs_recover_relocation(struct btrfs_root *root) · 4558 unmodified lines | |||
| 4559 | if (IS_ERR(fs_root)) { | 4559 | if (IS_ERR(fs_root)) { |
| 4560 | err = PTR_ERR(fs_root); | 4560 | err = PTR_ERR(fs_root); |
| 4561 | list_add_tail(&reloc_root->root_list, &reloc_roots); | 4561 | list_add_tail(&reloc_root->root_list, &reloc_roots); |
| 4562 | btrfs_end_transaction(trans); | ||
| 4562 | goto out_unset; | 4563 | goto out_unset; |
| 4563 | } | 4564 | } |
| 4564 | 4565 | ||
| @@ -662,10 +662,19 @@ again: · 661 unmodified lines | |||
| 662 | } | 662 | } |
| 663 | 663 | ||
| 664 | got_it: | 664 | got_it: |
| 665 | btrfs_record_root_in_trans(h, root); | ||
| 666 | |||
| 667 | if (!current->journal_info) | 665 | if (!current->journal_info) |
| 668 | current->journal_info = h; | 666 | current->journal_info = h; |
| 667 | |||
| 668 | /* | ||
| 669 | * btrfs_record_root_in_trans() needs to alloc new extents, and may | ||
| 670 | * call btrfs_join_transaction() while we're also starting a | ||
| 671 | * transaction. | ||
| 672 | * | ||
| 673 | * Thus it need to be called after current->journal_info initialized, | ||
| 674 | * or we can deadlock. | ||
| 675 | */ | ||
| 676 | btrfs_record_root_in_trans(h, root); | ||
| 677 | |||
| 669 | return h; | 678 | return h; |
| 670 | 679 | ||
| 671 | join_fail: | 680 | join_fail: |
| @@ -4226,6 +4226,9 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 4225 unmodified lines | |||
| 4226 | const u64 ino = btrfs_ino(inode); | 4226 | const u64 ino = btrfs_ino(inode); |
| 4227 | struct btrfs_path *dst_path = NULL; | 4227 | struct btrfs_path *dst_path = NULL; |
| 4228 | bool dropped_extents = false; | 4228 | bool dropped_extents = false; |
| 4229 | u64 truncate_offset = i_size; | ||
| 4230 | struct extent_buffer *leaf; | ||
| 4231 | int slot; | ||
| 4229 | int ins_nr = 0; | 4232 | int ins_nr = 0; |
| 4230 | int start_slot; | 4233 | int start_slot; |
| 4231 | int ret; | 4234 | int ret; |
| @@ -4240,9 +4243,43 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 8 unmodified lines | |||
| 4240 | if (ret < 0) | 4243 | if (ret < 0) |
| 4241 | goto out; | 4244 | goto out; |
| 4242 | 4245 | ||
| 4246 | /* | ||
| 4247 | * We must check if there is a prealloc extent that starts before the | ||
| 4248 | * i_size and crosses the i_size boundary. This is to ensure later we | ||
| 4249 | * truncate down to the end of that extent and not to the i_size, as | ||
| 4250 | * otherwise we end up losing part of the prealloc extent after a log | ||
| 4251 | * replay and with an implicit hole if there is another prealloc extent | ||
| 4252 | * that starts at an offset beyond i_size. | ||
| 4253 | */ | ||
| 4254 | ret = btrfs_previous_item(root, path, ino, BTRFS_EXTENT_DATA_KEY); | ||
| 4255 | if (ret < 0) | ||
| 4256 | goto out; | ||
| 4257 | |||
| 4258 | if (ret == 0) { | ||
| 4259 | struct btrfs_file_extent_item *ei; | ||
| 4260 | |||
| 4261 | leaf = path->nodes[0]; | ||
| 4262 | slot = path->slots[0]; | ||
| 4263 | ei = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | ||
| 4264 | |||
| 4265 | if (btrfs_file_extent_type(leaf, ei) == | ||
| 4266 | BTRFS_FILE_EXTENT_PREALLOC) { | ||
| 4267 | u64 extent_end; | ||
| 4268 | |||
| 4269 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
| 4270 | extent_end = key.offset + | ||
| 4271 | btrfs_file_extent_num_bytes(leaf, ei); | ||
| 4272 | |||
| 4273 | if (extent_end > i_size) | ||
| 4274 | truncate_offset = extent_end; | ||
| 4275 | } | ||
| 4276 | } else { | ||
| 4277 | ret = 0; | ||
| 4278 | } | ||
| 4279 | |||
| 4243 | while (true) { | 4280 | while (true) { |
| 4244 | struct extent_buffer *leaf = path->nodes[0]; | 4281 | leaf = path->nodes[0]; |
| 4245 | int slot = path->slots[0]; | 4282 | slot = path->slots[0]; |
| 4246 | 4283 | ||
| 4247 | if (slot >= btrfs_header_nritems(leaf)) { | 4284 | if (slot >= btrfs_header_nritems(leaf)) { |
| 4248 | if (ins_nr > 0) { | 4285 | if (ins_nr > 0) { |
| @@ -4280,7 +4317,7 @@ static int btrfs_log_prealloc_extents(struct btrfs_trans_handle *trans, · 31 unmodified lines | |||
| 4280 | ret = btrfs_truncate_inode_items(trans, | 4317 | ret = btrfs_truncate_inode_items(trans, |
| 4281 | root->log_root, | 4318 | root->log_root, |
| 4282 | &inode->vfs_inode, | 4319 | &inode->vfs_inode, |
| 4283 | i_size, | 4320 | truncate_offset, |
| 4284 | BTRFS_EXTENT_DATA_KEY); | 4321 | BTRFS_EXTENT_DATA_KEY); |
| 4285 | } while (ret == -EAGAIN); | 4322 | } while (ret == -EAGAIN); |
| 4286 | if (ret) | 4323 | if (ret) |
| @@ -524,6 +524,7 @@ enum { · 523 unmodified lines | |||
| 524 | REQ_F_OVERFLOW_BIT, | 524 | REQ_F_OVERFLOW_BIT, |
| 525 | REQ_F_POLLED_BIT, | 525 | REQ_F_POLLED_BIT, |
| 526 | REQ_F_BUFFER_SELECTED_BIT, | 526 | REQ_F_BUFFER_SELECTED_BIT, |
| 527 | REQ_F_NO_FILE_TABLE_BIT, | ||
| 527 | 528 | ||
| 528 | /* not a real bit, just to check we're not overflowing the space */ | 529 | /* not a real bit, just to check we're not overflowing the space */ |
| 529 | __REQ_F_LAST_BIT, | 530 | __REQ_F_LAST_BIT, |
| @@ -577,6 +578,8 @@ enum { · 47 unmodified lines | |||
| 577 | REQ_F_POLLED = BIT(REQ_F_POLLED_BIT), | 578 | REQ_F_POLLED = BIT(REQ_F_POLLED_BIT), |
| 578 | /* buffer already selected */ | 579 | /* buffer already selected */ |
| 579 | REQ_F_BUFFER_SELECTED = BIT(REQ_F_BUFFER_SELECTED_BIT), | 580 | REQ_F_BUFFER_SELECTED = BIT(REQ_F_BUFFER_SELECTED_BIT), |
| 581 | /* doesn't need file table for this request */ | ||
| 582 | REQ_F_NO_FILE_TABLE = BIT(REQ_F_NO_FILE_TABLE_BIT), | ||
| 580 | }; | 583 | }; |
| 581 | 584 | ||
| 582 | struct async_poll { | 585 | struct async_poll { |
| @@ -799,6 +802,7 @@ static const struct io_op_def io_op_defs[] = { · 216 unmodified lines | |||
| 799 | .needs_file = 1, | 802 | .needs_file = 1, |
| 800 | .fd_non_neg = 1, | 803 | .fd_non_neg = 1, |
| 801 | .needs_fs = 1, | 804 | .needs_fs = 1, |
| 805 | .file_table = 1, | ||
| 802 | }, | 806 | }, |
| 803 | [IORING_OP_READ] = { | 807 | [IORING_OP_READ] = { |
| 804 | .needs_mm = 1, | 808 | .needs_mm = 1, |
| @@ -1291,7 +1295,7 @@ static struct io_kiocb *io_get_fallback_req(struct io_ring_ctx *ctx) · 486 unmodified lines | |||
| 1291 | struct io_kiocb *req; | 1295 | struct io_kiocb *req; |
| 1292 | 1296 | ||
| 1293 | req = ctx->fallback_req; | 1297 | req = ctx->fallback_req; |
| 1294 | if (!test_and_set_bit_lock(0, (unsigned long *) ctx->fallback_req)) | 1298 | if (!test_and_set_bit_lock(0, (unsigned long *) &ctx->fallback_req)) |
| 1295 | return req; | 1299 | return req; |
| 1296 | 1300 | ||
| 1297 | return NULL; | 1301 | return NULL; |
| @@ -1378,7 +1382,7 @@ static void __io_free_req(struct io_kiocb *req) · 80 unmodified lines | |||
| 1378 | if (likely(!io_is_fallback_req(req))) | 1382 | if (likely(!io_is_fallback_req(req))) |
| 1379 | kmem_cache_free(req_cachep, req); | 1383 | kmem_cache_free(req_cachep, req); |
| 1380 | else | 1384 | else |
| 1381 | clear_bit_unlock(0, (unsigned long *) req->ctx->fallback_req); | 1385 | clear_bit_unlock(0, (unsigned long *) &req->ctx->fallback_req); |
| 1382 | } | 1386 | } |
| 1383 | 1387 | ||
| 1384 | struct req_batch { | 1388 | struct req_batch { |
| @@ -2034,7 +2038,7 @@ static struct file *__io_file_get(struct io_submit_state *state, int fd) · 649 unmodified lines | |||
| 2034 | * any file. For now, just ensure that anything potentially problematic is done | 2038 | * any file. For now, just ensure that anything potentially problematic is done |
| 2035 | * inline. | 2039 | * inline. |
| 2036 | */ | 2040 | */ |
| 2037 | static bool io_file_supports_async(struct file *file) | 2041 | static bool io_file_supports_async(struct file *file, int rw) |
| 2038 | { | 2042 | { |
| 2039 | umode_t mode = file_inode(file)->i_mode; | 2043 | umode_t mode = file_inode(file)->i_mode; |
| 2040 | 2044 | ||
| @@ -2043,7 +2047,13 @@ static bool io_file_supports_async(struct file *file) · 2 unmodified lines | |||
| 2043 | if (S_ISREG(mode) && file->f_op != &io_uring_fops) | 2047 | if (S_ISREG(mode) && file->f_op != &io_uring_fops) |
| 2044 | return true; | 2048 | return true; |
| 2045 | 2049 | ||
| 2046 | return false; | 2050 | if (!(file->f_mode & FMODE_NOWAIT)) |
| 2051 | return false; | ||
| 2052 | |||
| 2053 | if (rw == READ) | ||
| 2054 | return file->f_op->read_iter != NULL; | ||
| 2055 | |||
| 2056 | return file->f_op->write_iter != NULL; | ||
| 2047 | } | 2057 | } |
| 2048 | 2058 | ||
| 2049 | static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe, | 2059 | static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe, |
| @@ -2571,7 +2581,7 @@ static int io_read(struct io_kiocb *req, bool force_nonblock) · 521 unmodified lines | |||
| 2571 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so | 2581 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so |
| 2572 | * we know to async punt it even if it was opened O_NONBLOCK | 2582 | * we know to async punt it even if it was opened O_NONBLOCK |
| 2573 | */ | 2583 | */ |
| 2574 | if (force_nonblock && !io_file_supports_async(req->file)) | 2584 | if (force_nonblock && !io_file_supports_async(req->file, READ)) |
| 2575 | goto copy_iov; | 2585 | goto copy_iov; |
| 2576 | 2586 | ||
| 2577 | iov_count = iov_iter_count(&iter); | 2587 | iov_count = iov_iter_count(&iter); |
| @@ -2594,7 +2604,8 @@ copy_iov: · 16 unmodified lines | |||
| 2594 | if (ret) | 2604 | if (ret) |
| 2595 | goto out_free; | 2605 | goto out_free; |
| 2596 | /* any defer here is final, must blocking retry */ | 2606 | /* any defer here is final, must blocking retry */ |
| 2597 | if (!(req->flags & REQ_F_NOWAIT)) | 2607 | if (!(req->flags & REQ_F_NOWAIT) && |
| 2608 | !file_can_poll(req->file)) | ||
| 2598 | req->flags |= REQ_F_MUST_PUNT; | 2609 | req->flags |= REQ_F_MUST_PUNT; |
| 2599 | return -EAGAIN; | 2610 | return -EAGAIN; |
| 2600 | } | 2611 | } |
| @@ -2662,7 +2673,7 @@ static int io_write(struct io_kiocb *req, bool force_nonblock) · 61 unmodified lines | |||
| 2662 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so | 2673 | * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so |
| 2663 | * we know to async punt it even if it was opened O_NONBLOCK | 2674 | * we know to async punt it even if it was opened O_NONBLOCK |
| 2664 | */ | 2675 | */ |
| 2665 | if (force_nonblock && !io_file_supports_async(req->file)) | 2676 | if (force_nonblock && !io_file_supports_async(req->file, WRITE)) |
| 2666 | goto copy_iov; | 2677 | goto copy_iov; |
| 2667 | 2678 | ||
| 2668 | /* file path doesn't support NOWAIT for non-direct_IO */ | 2679 | /* file path doesn't support NOWAIT for non-direct_IO */ |
| @@ -2716,7 +2727,8 @@ copy_iov: · 47 unmodified lines | |||
| 2716 | if (ret) | 2727 | if (ret) |
| 2717 | goto out_free; | 2728 | goto out_free; |
| 2718 | /* any defer here is final, must blocking retry */ | 2729 | /* any defer here is final, must blocking retry */ |
| 2719 | req->flags |= REQ_F_MUST_PUNT; | 2730 | if (!file_can_poll(req->file)) |
| 2731 | req->flags |= REQ_F_MUST_PUNT; | ||
| 2720 | return -EAGAIN; | 2732 | return -EAGAIN; |
| 2721 | } | 2733 | } |
| 2722 | } | 2734 | } |
| @@ -2756,15 +2768,6 @@ static int io_splice_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 33 unmodified lines | |||
| 2756 | return 0; | 2768 | return 0; |
| 2757 | } | 2769 | } |
| 2758 | 2770 | ||
| 2759 | static bool io_splice_punt(struct file *file) | ||
| 2760 | { | ||
| 2761 | if (get_pipe_info(file)) | ||
| 2762 | return false; | ||
| 2763 | if (!io_file_supports_async(file)) | ||
| 2764 | return true; | ||
| 2765 | return !(file->f_flags & O_NONBLOCK); | ||
| 2766 | } | ||
| 2767 | |||
| 2768 | static int io_splice(struct io_kiocb *req, bool force_nonblock) | 2771 | static int io_splice(struct io_kiocb *req, bool force_nonblock) |
| 2769 | { | 2772 | { |
| 2770 | struct io_splice *sp = &req->splice; | 2773 | struct io_splice *sp = &req->splice; |
| @@ -2774,11 +2777,8 @@ static int io_splice(struct io_kiocb *req, bool force_nonblock) · 3 unmodified lines | |||
| 2774 | loff_t *poff_in, *poff_out; | 2777 | loff_t *poff_in, *poff_out; |
| 2775 | long ret; | 2778 | long ret; |
| 2776 | 2779 | ||
| 2777 | if (force_nonblock) { | 2780 | if (force_nonblock) |
| 2778 | if (io_splice_punt(in) || io_splice_punt(out)) | 2781 | return -EAGAIN; |
| 2779 | return -EAGAIN; | ||
| 2780 | flags |= SPLICE_F_NONBLOCK; | ||
| 2781 | } | ||
| 2782 | 2782 | ||
| 2783 | poff_in = (sp->off_in == -1) ? NULL : &sp->off_in; | 2783 | poff_in = (sp->off_in == -1) ? NULL : &sp->off_in; |
| 2784 | poff_out = (sp->off_out == -1) ? NULL : &sp->off_out; | 2784 | poff_out = (sp->off_out == -1) ? NULL : &sp->off_out; |
| @@ -3355,8 +3355,12 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock) · 570 unmodified lines | |||
| 3355 | struct kstat stat; | 3355 | struct kstat stat; |
| 3356 | int ret; | 3356 | int ret; |
| 3357 | 3357 | ||
| 3358 | if (force_nonblock) | 3358 | if (force_nonblock) { |
| 3359 | /* only need file table for an actual valid fd */ | ||
| 3360 | if (ctx->dfd == -1 || ctx->dfd == AT_FDCWD) | ||
| 3361 | req->flags |= REQ_F_NO_FILE_TABLE; | ||
| 3359 | return -EAGAIN; | 3362 | return -EAGAIN; |
| 3363 | } | ||
| 3360 | 3364 | ||
| 3361 | if (vfs_stat_set_lookup_flags(&lookup_flags, ctx->how.flags)) | 3365 | if (vfs_stat_set_lookup_flags(&lookup_flags, ctx->how.flags)) |
| 3362 | return -EINVAL; | 3366 | return -EINVAL; |
| @@ -3502,7 +3506,7 @@ static void io_sync_file_range_finish(struct io_wq_work **workptr) · 139 unmodified lines | |||
| 3502 | if (io_req_cancelled(req)) | 3506 | if (io_req_cancelled(req)) |
| 3503 | return; | 3507 | return; |
| 3504 | __io_sync_file_range(req); | 3508 | __io_sync_file_range(req); |
| 3505 | io_put_req(req); /* put submission ref */ | 3509 | io_steal_work(req, workptr); |
| 3506 | } | 3510 | } |
| 3507 | 3511 | ||
| 3508 | static int io_sync_file_range(struct io_kiocb *req, bool force_nonblock) | 3512 | static int io_sync_file_range(struct io_kiocb *req, bool force_nonblock) |
| @@ -5015,7 +5019,7 @@ static int io_req_defer(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 1506 unmodified lines | |||
| 5015 | int ret; | 5019 | int ret; |
| 5016 | 5020 | ||
| 5017 | /* Still need defer if there is pending req in defer list. */ | 5021 | /* Still need defer if there is pending req in defer list. */ |
| 5018 | if (!req_need_defer(req) && list_empty(&ctx->defer_list)) | 5022 | if (!req_need_defer(req) && list_empty_careful(&ctx->defer_list)) |
| 5019 | return 0; | 5023 | return 0; |
| 5020 | 5024 | ||
| 5021 | if (!req->io && io_alloc_async_ctx(req)) | 5025 | if (!req->io && io_alloc_async_ctx(req)) |
| @@ -5429,7 +5433,7 @@ static int io_grab_files(struct io_kiocb *req) · 407 unmodified lines | |||
| 5429 | int ret = -EBADF; | 5433 | int ret = -EBADF; |
| 5430 | struct io_ring_ctx *ctx = req->ctx; | 5434 | struct io_ring_ctx *ctx = req->ctx; |
| 5431 | 5435 | ||
| 5432 | if (req->work.files) | 5436 | if (req->work.files || (req->flags & REQ_F_NO_FILE_TABLE)) |
| 5433 | return 0; | 5437 | return 0; |
| 5434 | if (!ctx->ring_file) | 5438 | if (!ctx->ring_file) |
| 5435 | return -EBADF; | 5439 | return -EBADF; |
| @@ -7327,7 +7331,7 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) · 1891 unmodified lines | |||
| 7327 | * it could cause shutdown to hang. | 7331 | * it could cause shutdown to hang. |
| 7328 | */ | 7332 | */ |
| 7329 | while (ctx->sqo_thread && !wq_has_sleeper(&ctx->sqo_wait)) | 7333 | while (ctx->sqo_thread && !wq_has_sleeper(&ctx->sqo_wait)) |
| 7330 | cpu_relax(); | 7334 | cond_resched(); |
| 7331 | 7335 | ||
| 7332 | io_kill_timeouts(ctx); | 7336 | io_kill_timeouts(ctx); |
| 7333 | io_poll_remove_all(ctx); | 7337 | io_poll_remove_all(ctx); |
| @@ -55,6 +55,7 @@ EXPORT_SYMBOL(vfs_ioctl); · 54 unmodified lines | |||
| 55 | static int ioctl_fibmap(struct file *filp, int __user *p) | 55 | static int ioctl_fibmap(struct file *filp, int __user *p) |
| 56 | { | 56 | { |
| 57 | struct inode *inode = file_inode(filp); | 57 | struct inode *inode = file_inode(filp); |
| 58 | struct super_block *sb = inode->i_sb; | ||
| 58 | int error, ur_block; | 59 | int error, ur_block; |
| 59 | sector_t block; | 60 | sector_t block; |
| 60 | 61 | ||
| @@ -71,6 +72,13 @@ static int ioctl_fibmap(struct file *filp, int __user *p) · 10 unmodified lines | |||
| 71 | block = ur_block; | 72 | block = ur_block; |
| 72 | error = bmap(inode, &block); | 73 | error = bmap(inode, &block); |
| 73 | 74 | ||
| 75 | if (block > INT_MAX) { | ||
| 76 | error = -ERANGE; | ||
| 77 | pr_warn_ratelimited("[%s/%d] FS: %s File: %pD4 would truncate fibmap result\n", | ||
| 78 | current->comm, task_pid_nr(current), | ||
| 79 | sb->s_id, filp); | ||
| 80 | } | ||
| 81 | |||
| 74 | if (error) | 82 | if (error) |
| 75 | ur_block = 0; | 83 | ur_block = 0; |
| 76 | else | 84 | else |
| @@ -117,10 +117,7 @@ iomap_bmap_actor(struct inode *inode, loff_t pos, loff_t length, · 116 unmodified lines | |||
| 117 | 117 | ||
| 118 | if (iomap->type == IOMAP_MAPPED) { | 118 | if (iomap->type == IOMAP_MAPPED) { |
| 119 | addr = (pos - iomap->offset + iomap->addr) >> inode->i_blkbits; | 119 | addr = (pos - iomap->offset + iomap->addr) >> inode->i_blkbits; |
| 120 | if (addr > INT_MAX) | 120 | *bno = addr; |
| 121 | WARN(1, "would truncate bmap result\n"); | ||
| 122 | else | ||
| 123 | *bno = addr; | ||
| 124 | } | 121 | } |
| 125 | return 0; | 122 | return 0; |
| 126 | } | 123 | } |
| @@ -253,37 +253,45 @@ int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, · 252 unmodified lines | |||
| 253 | 253 | ||
| 254 | int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) | 254 | int nfs3_set_acl(struct inode *inode, struct posix_acl *acl, int type) |
| 255 | { | 255 | { |
| 256 | struct posix_acl *alloc = NULL, *dfacl = NULL; | 256 | struct posix_acl *orig = acl, *dfacl = NULL, *alloc; |
| 257 | int status; | 257 | int status; |
| 258 | 258 | ||
| 259 | if (S_ISDIR(inode->i_mode)) { | 259 | if (S_ISDIR(inode->i_mode)) { |
| 260 | switch(type) { | 260 | switch(type) { |
| 261 | case ACL_TYPE_ACCESS: | 261 | case ACL_TYPE_ACCESS: |
| 262 | alloc = dfacl = get_acl(inode, ACL_TYPE_DEFAULT); | 262 | alloc = get_acl(inode, ACL_TYPE_DEFAULT); |
| 263 | if (IS_ERR(alloc)) | 263 | if (IS_ERR(alloc)) |
| 264 | goto fail; | 264 | goto fail; |
| 265 | dfacl = alloc; | ||
| 265 | break; | 266 | break; |
| 266 | 267 | ||
| 267 | case ACL_TYPE_DEFAULT: | 268 | case ACL_TYPE_DEFAULT: |
| 268 | dfacl = acl; | 269 | alloc = get_acl(inode, ACL_TYPE_ACCESS); |
| 269 | alloc = acl = get_acl(inode, ACL_TYPE_ACCESS); | ||
| 270 | if (IS_ERR(alloc)) | 270 | if (IS_ERR(alloc)) |
| 271 | goto fail; | 271 | goto fail; |
| 272 | dfacl = acl; | ||
| 273 | acl = alloc; | ||
| 272 | break; | 274 | break; |
| 273 | } | 275 | } |
| 274 | } | 276 | } |
| 275 | 277 | ||
| 276 | if (acl == NULL) { | 278 | if (acl == NULL) { |
| 277 | alloc = acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); | 279 | alloc = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); |
| 278 | if (IS_ERR(alloc)) | 280 | if (IS_ERR(alloc)) |
| 279 | goto fail; | 281 | goto fail; |
| 282 | acl = alloc; | ||
| 280 | } | 283 | } |
| 281 | status = __nfs3_proc_setacls(inode, acl, dfacl); | 284 | status = __nfs3_proc_setacls(inode, acl, dfacl); |
| 282 | posix_acl_release(alloc); | 285 | out: |
| 286 | if (acl != orig) | ||
| 287 | posix_acl_release(acl); | ||
| 288 | if (dfacl != orig) | ||
| 289 | posix_acl_release(dfacl); | ||
| 283 | return status; | 290 | return status; |
| 284 | 291 | ||
| 285 | fail: | 292 | fail: |
| 286 | return PTR_ERR(alloc); | 293 | status = PTR_ERR(alloc); |
| 294 | goto out; | ||
| 287 | } | 295 | } |
| 288 | 296 | ||
| 289 | const struct xattr_handler *nfs3_xattr_handlers[] = { | 297 | const struct xattr_handler *nfs3_xattr_handlers[] = { |
| @@ -7891,6 +7891,7 @@ static void · 7890 unmodified lines | |||
| 7891 | nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) | 7891 | nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) |
| 7892 | { | 7892 | { |
| 7893 | struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp; | 7893 | struct nfs41_bind_conn_to_session_args *args = task->tk_msg.rpc_argp; |
| 7894 | struct nfs41_bind_conn_to_session_res *res = task->tk_msg.rpc_resp; | ||
| 7894 | struct nfs_client *clp = args->client; | 7895 | struct nfs_client *clp = args->client; |
| 7895 | 7896 | ||
| 7896 | switch (task->tk_status) { | 7897 | switch (task->tk_status) { |
| @@ -7899,6 +7900,12 @@ nfs4_bind_one_conn_to_session_done(struct rpc_task *task, void *calldata) · 2 unmodified lines | |||
| 7899 | nfs4_schedule_session_recovery(clp->cl_session, | 7900 | nfs4_schedule_session_recovery(clp->cl_session, |
| 7900 | task->tk_status); | 7901 | task->tk_status); |
| 7901 | } | 7902 | } |
| 7903 | if (args->dir == NFS4_CDFC4_FORE_OR_BOTH && | ||
| 7904 | res->dir != NFS4_CDFS4_BOTH) { | ||
| 7905 | rpc_task_close_connection(task); | ||
| 7906 | if (args->retries++ < MAX_BIND_CONN_TO_SESSION_RETRIES) | ||
| 7907 | rpc_restart_call(task); | ||
| 7908 | } | ||
| 7902 | } | 7909 | } |
| 7903 | 7910 | ||
| 7904 | static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = { | 7911 | static const struct rpc_call_ops nfs4_bind_one_conn_to_session_ops = { |
| @@ -7921,6 +7928,7 @@ int nfs4_proc_bind_one_conn_to_session(struct rpc_clnt *clnt, · 16 unmodified lines | |||
| 7921 | struct nfs41_bind_conn_to_session_args args = { | 7928 | struct nfs41_bind_conn_to_session_args args = { |
| 7922 | .client = clp, | 7929 | .client = clp, |
| 7923 | .dir = NFS4_CDFC4_FORE_OR_BOTH, | 7930 | .dir = NFS4_CDFC4_FORE_OR_BOTH, |
| 7931 | .retries = 0, | ||
| 7924 | }; | 7932 | }; |
| 7925 | struct nfs41_bind_conn_to_session_res res; | 7933 | struct nfs41_bind_conn_to_session_res res; |
| 7926 | struct rpc_message msg = { | 7934 | struct rpc_message msg = { |
| @@ -9191,8 +9199,7 @@ nfs4_proc_layoutget(struct nfs4_layoutget *lgp, long *timeout) · 1264 unmodified lines | |||
| 9191 | nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0, 0); | 9199 | nfs4_init_sequence(&lgp->args.seq_args, &lgp->res.seq_res, 0, 0); |
| 9192 | 9200 | ||
| 9193 | task = rpc_run_task(&task_setup_data); | 9201 | task = rpc_run_task(&task_setup_data); |
| 9194 | if (IS_ERR(task)) | 9202 | |
| 9195 | return ERR_CAST(task); | ||
| 9196 | status = rpc_wait_for_completion_task(task); | 9203 | status = rpc_wait_for_completion_task(task); |
| 9197 | if (status != 0) | 9204 | if (status != 0) |
| 9198 | goto out; | 9205 | goto out; |
| @@ -1332,13 +1332,15 @@ _pnfs_return_layout(struct inode *ino) · 1331 unmodified lines | |||
| 1332 | !valid_layout) { | 1332 | !valid_layout) { |
| 1333 | spin_unlock(&ino->i_lock); | 1333 | spin_unlock(&ino->i_lock); |
| 1334 | dprintk("NFS: %s no layout segments to return\n", __func__); | 1334 | dprintk("NFS: %s no layout segments to return\n", __func__); |
| 1335 | goto out_put_layout_hdr; | 1335 | goto out_wait_layoutreturn; |
| 1336 | } | 1336 | } |
| 1337 | 1337 | ||
| 1338 | send = pnfs_prepare_layoutreturn(lo, &stateid, &cred, NULL); | 1338 | send = pnfs_prepare_layoutreturn(lo, &stateid, &cred, NULL); |
| 1339 | spin_unlock(&ino->i_lock); | 1339 | spin_unlock(&ino->i_lock); |
| 1340 | if (send) | 1340 | if (send) |
| 1341 | status = pnfs_send_layoutreturn(lo, &stateid, &cred, IOMODE_ANY, true); | 1341 | status = pnfs_send_layoutreturn(lo, &stateid, &cred, IOMODE_ANY, true); |
| 1342 | out_wait_layoutreturn: | ||
| 1343 | wait_on_bit(&lo->plh_flags, NFS_LAYOUT_RETURN, TASK_UNINTERRUPTIBLE); | ||
| 1342 | out_put_layout_hdr: | 1344 | out_put_layout_hdr: |
| 1343 | pnfs_free_lseg_list(&tmp_list); | 1345 | pnfs_free_lseg_list(&tmp_list); |
| 1344 | pnfs_put_layout_hdr(lo); | 1346 | pnfs_put_layout_hdr(lo); |
| @@ -1456,18 +1458,15 @@ retry: · 111 unmodified lines | |||
| 1456 | /* lo ref dropped in pnfs_roc_release() */ | 1458 | /* lo ref dropped in pnfs_roc_release() */ |
| 1457 | layoutreturn = pnfs_prepare_layoutreturn(lo, &stateid, &lc_cred, &iomode); | 1459 | layoutreturn = pnfs_prepare_layoutreturn(lo, &stateid, &lc_cred, &iomode); |
| 1458 | /* If the creds don't match, we can't compound the layoutreturn */ | 1460 | /* If the creds don't match, we can't compound the layoutreturn */ |
| 1459 | if (!layoutreturn) | 1461 | if (!layoutreturn || cred_fscmp(cred, lc_cred) != 0) |
| 1460 | goto out_noroc; | 1462 | goto out_noroc; |
| 1461 | if (cred_fscmp(cred, lc_cred) != 0) | ||
| 1462 | goto out_noroc_put_cred; | ||
| 1463 | 1463 | ||
| 1464 | roc = layoutreturn; | 1464 | roc = layoutreturn; |
| 1465 | pnfs_init_layoutreturn_args(args, lo, &stateid, iomode); | 1465 | pnfs_init_layoutreturn_args(args, lo, &stateid, iomode); |
| 1466 | res->lrs_present = 0; | 1466 | res->lrs_present = 0; |
| 1467 | layoutreturn = false; | 1467 | layoutreturn = false; |
| 1468 | |||
| 1469 | out_noroc_put_cred: | ||
| 1470 | put_cred(lc_cred); | 1468 | put_cred(lc_cred); |
| 1469 | |||
| 1471 | out_noroc: | 1470 | out_noroc: |
| 1472 | spin_unlock(&ino->i_lock); | 1471 | spin_unlock(&ino->i_lock); |
| 1473 | rcu_read_unlock(); | 1472 | rcu_read_unlock(); |
| @@ -185,7 +185,7 @@ static int __nfs_list_for_each_server(struct list_head *head, · 184 unmodified lines | |||
| 185 | 185 | ||
| 186 | rcu_read_lock(); | 186 | rcu_read_lock(); |
| 187 | list_for_each_entry_rcu(server, head, client_link) { | 187 | list_for_each_entry_rcu(server, head, client_link) { |
| 188 | if (!nfs_sb_active(server->super)) | 188 | if (!(server->super && nfs_sb_active(server->super))) |
| 189 | continue; | 189 | continue; |
| 190 | rcu_read_unlock(); | 190 | rcu_read_unlock(); |
| 191 | if (last) | 191 | if (last) |
| @@ -275,7 +275,6 @@ static ssize_t dlmfs_file_write(struct file *filp, · 274 unmodified lines | |||
| 275 | loff_t *ppos) | 275 | loff_t *ppos) |
| 276 | { | 276 | { |
| 277 | int bytes_left; | 277 | int bytes_left; |
| 278 | ssize_t writelen; | ||
| 279 | char *lvb_buf; | 278 | char *lvb_buf; |
| 280 | struct inode *inode = file_inode(filp); | 279 | struct inode *inode = file_inode(filp); |
| 281 | 280 | ||
| @@ -285,32 +284,30 @@ static ssize_t dlmfs_file_write(struct file *filp, · 3 unmodified lines | |||
| 285 | if (*ppos >= i_size_read(inode)) | 284 | if (*ppos >= i_size_read(inode)) |
| 286 | return -ENOSPC; | 285 | return -ENOSPC; |
| 287 | 286 | ||
| 287 | /* don't write past the lvb */ | ||
| 288 | if (count > i_size_read(inode) - *ppos) | ||
| 289 | count = i_size_read(inode) - *ppos; | ||
| 290 | |||
| 288 | if (!count) | 291 | if (!count) |
| 289 | return 0; | 292 | return 0; |
| 290 | 293 | ||
| 291 | if (!access_ok(buf, count)) | 294 | if (!access_ok(buf, count)) |
| 292 | return -EFAULT; | 295 | return -EFAULT; |
| 293 | 296 | ||
| 294 | /* don't write past the lvb */ | 297 | lvb_buf = kmalloc(count, GFP_NOFS); |
| 295 | if ((count + *ppos) > i_size_read(inode)) | ||
| 296 | writelen = i_size_read(inode) - *ppos; | ||
| 297 | else | ||
| 298 | writelen = count - *ppos; | ||
| 299 | |||
| 300 | lvb_buf = kmalloc(writelen, GFP_NOFS); | ||
| 301 | if (!lvb_buf) | 298 | if (!lvb_buf) |
| 302 | return -ENOMEM; | 299 | return -ENOMEM; |
| 303 | 300 | ||
| 304 | bytes_left = copy_from_user(lvb_buf, buf, writelen); | 301 | bytes_left = copy_from_user(lvb_buf, buf, count); |
| 305 | writelen -= bytes_left; | 302 | count -= bytes_left; |
| 306 | if (writelen) | 303 | if (count) |
| 307 | user_dlm_write_lvb(inode, lvb_buf, writelen); | 304 | user_dlm_write_lvb(inode, lvb_buf, count); |
| 308 | 305 | ||
| 309 | kfree(lvb_buf); | 306 | kfree(lvb_buf); |
| 310 | 307 | ||
| 311 | *ppos = *ppos + writelen; | 308 | *ppos = *ppos + count; |
| 312 | mlog(0, "wrote %zd bytes\n", writelen); | 309 | mlog(0, "wrote %zu bytes\n", count); |
| 313 | return writelen; | 310 | return count; |
| 314 | } | 311 | } |
| 315 | 312 | ||
| 316 | static void dlmfs_init_once(void *foo) | 313 | static void dlmfs_init_once(void *foo) |
| @@ -261,14 +261,13 @@ static int propagate_one(struct mount *m) · 260 unmodified lines | |||
| 261 | child = copy_tree(last_source, last_source->mnt.mnt_root, type); | 261 | child = copy_tree(last_source, last_source->mnt.mnt_root, type); |
| 262 | if (IS_ERR(child)) | 262 | if (IS_ERR(child)) |
| 263 | return PTR_ERR(child); | 263 | return PTR_ERR(child); |
| 264 | read_seqlock_excl(&mount_lock); | ||
| 264 | mnt_set_mountpoint(m, mp, child); | 265 | mnt_set_mountpoint(m, mp, child); |
| 266 | if (m->mnt_master != dest_master) | ||
| 267 | SET_MNT_MARK(m->mnt_master); | ||
| 268 | read_sequnlock_excl(&mount_lock); | ||
| 265 | last_dest = m; | 269 | last_dest = m; |
| 266 | last_source = child; | 270 | last_source = child; |
| 267 | if (m->mnt_master != dest_master) { | ||
| 268 | read_seqlock_excl(&mount_lock); | ||
| 269 | SET_MNT_MARK(m->mnt_master); | ||
| 270 | read_sequnlock_excl(&mount_lock); | ||
| 271 | } | ||
| 272 | hlist_add_head(&child->mnt_hash, list); | 271 | hlist_add_head(&child->mnt_hash, list); |
| 273 | return count_mounts(m->mnt_ns, child); | 272 | return count_mounts(m->mnt_ns, child); |
| 274 | } | 273 | } |
| @@ -1302,8 +1302,8 @@ int get_tree_bdev(struct fs_context *fc, · 1301 unmodified lines | |||
| 1302 | mutex_lock(&bdev->bd_fsfreeze_mutex); | 1302 | mutex_lock(&bdev->bd_fsfreeze_mutex); |
| 1303 | if (bdev->bd_fsfreeze_count > 0) { | 1303 | if (bdev->bd_fsfreeze_count > 0) { |
| 1304 | mutex_unlock(&bdev->bd_fsfreeze_mutex); | 1304 | mutex_unlock(&bdev->bd_fsfreeze_mutex); |
| 1305 | blkdev_put(bdev, mode); | ||
| 1306 | warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev); | 1305 | warnf(fc, "%pg: Can't mount, blockdev is frozen", bdev); |
| 1306 | blkdev_put(bdev, mode); | ||
| 1307 | return -EBUSY; | 1307 | return -EBUSY; |
| 1308 | } | 1308 | } |
| 1309 | 1309 | ||
| @@ -329,13 +329,12 @@ struct dma_buf { · 328 unmodified lines | |||
| 329 | 329 | ||
| 330 | /** | 330 | /** |
| 331 | * struct dma_buf_attach_ops - importer operations for an attachment | 331 | * struct dma_buf_attach_ops - importer operations for an attachment |
| 332 | * @move_notify: [optional] notification that the DMA-buf is moving | ||
| 333 | * | 332 | * |
| 334 | * Attachment operations implemented by the importer. | 333 | * Attachment operations implemented by the importer. |
| 335 | */ | 334 | */ |
| 336 | struct dma_buf_attach_ops { | 335 | struct dma_buf_attach_ops { |
| 337 | /** | 336 | /** |
| 338 | * @move_notify | 337 | * @move_notify: [optional] notification that the DMA-buf is moving |
| 339 | * | 338 | * |
| 340 | * If this callback is provided the framework can avoid pinning the | 339 | * If this callback is provided the framework can avoid pinning the |
| 341 | * backing store while mappings exists. | 340 | * backing store while mappings exists. |
| @@ -83,9 +83,9 @@ enum dma_transfer_direction { · 82 unmodified lines | |||
| 83 | /** | 83 | /** |
| 84 | * Interleaved Transfer Request | 84 | * Interleaved Transfer Request |
| 85 | * ---------------------------- | 85 | * ---------------------------- |
| 86 | * A chunk is collection of contiguous bytes to be transfered. | 86 | * A chunk is collection of contiguous bytes to be transferred. |
| 87 | * The gap(in bytes) between two chunks is called inter-chunk-gap(ICG). | 87 | * The gap(in bytes) between two chunks is called inter-chunk-gap(ICG). |
| 88 | * ICGs may or maynot change between chunks. | 88 | * ICGs may or may not change between chunks. |
| 89 | * A FRAME is the smallest series of contiguous {chunk,icg} pairs, | 89 | * A FRAME is the smallest series of contiguous {chunk,icg} pairs, |
| 90 | * that when repeated an integral number of times, specifies the transfer. | 90 | * that when repeated an integral number of times, specifies the transfer. |
| 91 | * A transfer template is specification of a Frame, the number of times | 91 | * A transfer template is specification of a Frame, the number of times |
| @@ -341,13 +341,11 @@ struct dma_chan { · 249 unmodified lines | |||
| 341 | * @chan: driver channel device | 341 | * @chan: driver channel device |
| 342 | * @device: sysfs device | 342 | * @device: sysfs device |
| 343 | * @dev_id: parent dma_device dev_id | 343 | * @dev_id: parent dma_device dev_id |
| 344 | * @idr_ref: reference count to gate release of dma_device dev_id | ||
| 345 | */ | 344 | */ |
| 346 | struct dma_chan_dev { | 345 | struct dma_chan_dev { |
| 347 | struct dma_chan *chan; | 346 | struct dma_chan *chan; |
| 348 | struct device device; | 347 | struct device device; |
| 349 | int dev_id; | 348 | int dev_id; |
| 350 | atomic_t *idr_ref; | ||
| 351 | }; | 349 | }; |
| 352 | 350 | ||
| 353 | /** | 351 | /** |
| @@ -835,6 +833,8 @@ struct dma_device { · 481 unmodified lines | |||
| 835 | int dev_id; | 833 | int dev_id; |
| 836 | struct device *dev; | 834 | struct device *dev; |
| 837 | struct module *owner; | 835 | struct module *owner; |
| 836 | struct ida chan_ida; | ||
| 837 | struct mutex chan_mutex; /* to protect chan_ida */ | ||
| 838 | 838 | ||
| 839 | u32 src_addr_widths; | 839 | u32 src_addr_widths; |
| 840 | u32 dst_addr_widths; | 840 | u32 dst_addr_widths; |
| @@ -1069,7 +1069,7 @@ static inline int dmaengine_terminate_all(struct dma_chan *chan) · 228 unmodified lines | |||
| 1069 | * dmaengine_synchronize() needs to be called before it is safe to free | 1069 | * dmaengine_synchronize() needs to be called before it is safe to free |
| 1070 | * any memory that is accessed by previously submitted descriptors or before | 1070 | * any memory that is accessed by previously submitted descriptors or before |
| 1071 | * freeing any resources accessed from within the completion callback of any | 1071 | * freeing any resources accessed from within the completion callback of any |
| 1072 | * perviously submitted descriptors. | 1072 | * previously submitted descriptors. |
| 1073 | * | 1073 | * |
| 1074 | * This function can be called from atomic context as well as from within a | 1074 | * This function can be called from atomic context as well as from within a |
| 1075 | * complete callback of a descriptor submitted on the same channel. | 1075 | * complete callback of a descriptor submitted on the same channel. |
| @@ -1091,7 +1091,7 @@ static inline int dmaengine_terminate_async(struct dma_chan *chan) · 15 unmodified lines | |||
| 1091 | * | 1091 | * |
| 1092 | * Synchronizes to the DMA channel termination to the current context. When this | 1092 | * Synchronizes to the DMA channel termination to the current context. When this |
| 1093 | * function returns it is guaranteed that all transfers for previously issued | 1093 | * function returns it is guaranteed that all transfers for previously issued |
| 1094 | * descriptors have stopped and and it is safe to free the memory assoicated | 1094 | * descriptors have stopped and it is safe to free the memory associated |
| 1095 | * with them. Furthermore it is guaranteed that all complete callback functions | 1095 | * with them. Furthermore it is guaranteed that all complete callback functions |
| 1096 | * for a previously submitted descriptor have finished running and it is safe to | 1096 | * for a previously submitted descriptor have finished running and it is safe to |
| 1097 | * free resources accessed from within the complete callbacks. | 1097 | * free resources accessed from within the complete callbacks. |
| @@ -1317,11 +1317,13 @@ struct nfs41_impl_id { · 1316 unmodified lines | |||
| 1317 | struct nfstime4 date; | 1317 | struct nfstime4 date; |
| 1318 | }; | 1318 | }; |
| 1319 | 1319 | ||
| 1320 | #define MAX_BIND_CONN_TO_SESSION_RETRIES 3 | ||
| 1320 | struct nfs41_bind_conn_to_session_args { | 1321 | struct nfs41_bind_conn_to_session_args { |
| 1321 | struct nfs_client *client; | 1322 | struct nfs_client *client; |
| 1322 | struct nfs4_sessionid sessionid; | 1323 | struct nfs4_sessionid sessionid; |
| 1323 | u32 dir; | 1324 | u32 dir; |
| 1324 | bool use_conn_in_rdma_mode; | 1325 | bool use_conn_in_rdma_mode; |
| 1326 | int retries; | ||
| 1325 | }; | 1327 | }; |
| 1326 | 1328 | ||
| 1327 | struct nfs41_bind_conn_to_session_res { | 1329 | struct nfs41_bind_conn_to_session_res { |
| @@ -71,7 +71,13 @@ struct rpc_clnt { · 70 unmodified lines | |||
| 71 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | 71 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
| 72 | struct dentry *cl_debugfs; /* debugfs directory */ | 72 | struct dentry *cl_debugfs; /* debugfs directory */ |
| 73 | #endif | 73 | #endif |
| 74 | struct rpc_xprt_iter cl_xpi; | 74 | /* cl_work is only needed after cl_xpi is no longer used, |
| 75 | * and that are of similar size | ||
| 76 | */ | ||
| 77 | union { | ||
| 78 | struct rpc_xprt_iter cl_xpi; | ||
| 79 | struct work_struct cl_work; | ||
| 80 | }; | ||
| 75 | const struct cred *cl_cred; | 81 | const struct cred *cl_cred; |
| 76 | }; | 82 | }; |
| 77 | 83 | ||
| @@ -236,4 +242,9 @@ static inline int rpc_reply_expected(struct rpc_task *task) · 158 unmodified lines | |||
| 236 | (task->tk_msg.rpc_proc->p_decode != NULL); | 242 | (task->tk_msg.rpc_proc->p_decode != NULL); |
| 237 | } | 243 | } |
| 238 | 244 | ||
| 245 | static inline void rpc_task_close_connection(struct rpc_task *task) | ||
| 246 | { | ||
| 247 | if (task->tk_xprt) | ||
| 248 | xprt_force_disconnect(task->tk_xprt); | ||
| 249 | } | ||
| 239 | #endif /* _LINUX_SUNRPC_CLNT_H */ | 250 | #endif /* _LINUX_SUNRPC_CLNT_H */ |
| @@ -692,11 +692,10 @@ TRACE_EVENT(xprtrdma_prepsend_failed, · 691 unmodified lines | |||
| 692 | 692 | ||
| 693 | TRACE_EVENT(xprtrdma_post_send, | 693 | TRACE_EVENT(xprtrdma_post_send, |
| 694 | TP_PROTO( | 694 | TP_PROTO( |
| 695 | const struct rpcrdma_req *req, | 695 | const struct rpcrdma_req *req |
| 696 | int status | ||
| 697 | ), | 696 | ), |
| 698 | 697 | ||
| 699 | TP_ARGS(req, status), | 698 | TP_ARGS(req), |
| 700 | 699 | ||
| 701 | TP_STRUCT__entry( | 700 | TP_STRUCT__entry( |
| 702 | __field(const void *, req) | 701 | __field(const void *, req) |
| @@ -705,7 +704,6 @@ TRACE_EVENT(xprtrdma_post_send, · 2 unmodified lines | |||
| 705 | __field(unsigned int, client_id) | 704 | __field(unsigned int, client_id) |
| 706 | __field(int, num_sge) | 705 | __field(int, num_sge) |
| 707 | __field(int, signaled) | 706 | __field(int, signaled) |
| 708 | __field(int, status) | ||
| 709 | ), | 707 | ), |
| 710 | 708 | ||
| 711 | TP_fast_assign( | 709 | TP_fast_assign( |
| @@ -718,15 +716,13 @@ TRACE_EVENT(xprtrdma_post_send, · 6 unmodified lines | |||
| 718 | __entry->sc = req->rl_sendctx; | 716 | __entry->sc = req->rl_sendctx; |
| 719 | __entry->num_sge = req->rl_wr.num_sge; | 717 | __entry->num_sge = req->rl_wr.num_sge; |
| 720 | __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED; | 718 | __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED; |
| 721 | __entry->status = status; | ||
| 722 | ), | 719 | ), |
| 723 | 720 | ||
| 724 | TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %sstatus=%d", | 721 | TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %s", |
| 725 | __entry->task_id, __entry->client_id, | 722 | __entry->task_id, __entry->client_id, |
| 726 | __entry->req, __entry->sc, __entry->num_sge, | 723 | __entry->req, __entry->sc, __entry->num_sge, |
| 727 | (__entry->num_sge == 1 ? "" : "s"), | 724 | (__entry->num_sge == 1 ? "" : "s"), |
| 728 | (__entry->signaled ? "signaled " : ""), | 725 | (__entry->signaled ? "signaled" : "") |
| 729 | __entry->status | ||
| 730 | ) | 726 | ) |
| 731 | ); | 727 | ); |
| 732 | 728 | ||
| @@ -346,6 +346,10 @@ struct drm_amdgpu_gem_userptr { · 345 unmodified lines | |||
| 346 | #define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF | 346 | #define AMDGPU_TILING_DCC_PITCH_MAX_MASK 0x3FFF |
| 347 | #define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43 | 347 | #define AMDGPU_TILING_DCC_INDEPENDENT_64B_SHIFT 43 |
| 348 | #define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1 | 348 | #define AMDGPU_TILING_DCC_INDEPENDENT_64B_MASK 0x1 |
| 349 | #define AMDGPU_TILING_DCC_INDEPENDENT_128B_SHIFT 44 | ||
| 350 | #define AMDGPU_TILING_DCC_INDEPENDENT_128B_MASK 0x1 | ||
| 351 | #define AMDGPU_TILING_SCANOUT_SHIFT 63 | ||
| 352 | #define AMDGPU_TILING_SCANOUT_MASK 0x1 | ||
| 349 | 353 | ||
| 350 | /* Set/Get helpers for tiling flags. */ | 354 | /* Set/Get helpers for tiling flags. */ |
| 351 | #define AMDGPU_TILING_SET(field, value) \ | 355 | #define AMDGPU_TILING_SET(field, value) \ |
| @@ -39,6 +39,12 @@ struct dma_buf_sync { · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | #define DMA_BUF_BASE 'b' | 40 | #define DMA_BUF_BASE 'b' |
| 41 | #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) | 41 | #define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync) |
| 42 | |||
| 43 | /* 32/64bitness of this uapi was botched in android, there's no difference | ||
| 44 | * between them in actual uapi, they're just different numbers. | ||
| 45 | */ | ||
| 42 | #define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *) | 46 | #define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *) |
| 47 | #define DMA_BUF_SET_NAME_A _IOW(DMA_BUF_BASE, 1, u32) | ||
| 48 | #define DMA_BUF_SET_NAME_B _IOW(DMA_BUF_BASE, 1, u64) | ||
| 43 | 49 | ||
| 44 | #endif | 50 | #endif |
| @@ -119,8 +119,8 @@ enum hv_fcopy_op { · 118 unmodified lines | |||
| 119 | 119 | ||
| 120 | struct hv_fcopy_hdr { | 120 | struct hv_fcopy_hdr { |
| 121 | __u32 operation; | 121 | __u32 operation; |
| 122 | uuid_le service_id0; /* currently unused */ | 122 | __u8 service_id0[16]; /* currently unused */ |
| 123 | uuid_le service_id1; /* currently unused */ | 123 | __u8 service_id1[16]; /* currently unused */ |
| 124 | } __attribute__((packed)); | 124 | } __attribute__((packed)); |
| 125 | 125 | ||
| 126 | #define OVER_WRITE 0x1 | 126 | #define OVER_WRITE 0x1 |
| @@ -898,6 +898,13 @@ static int software_resume(void) · 897 unmodified lines | |||
| 898 | error = freeze_processes(); | 898 | error = freeze_processes(); |
| 899 | if (error) | 899 | if (error) |
| 900 | goto Close_Finish; | 900 | goto Close_Finish; |
| 901 | |||
| 902 | error = freeze_kernel_threads(); | ||
| 903 | if (error) { | ||
| 904 | thaw_processes(); | ||
| 905 | goto Close_Finish; | ||
| 906 | } | ||
| 907 | |||
| 901 | error = load_image_and_restore(); | 908 | error = load_image_and_restore(); |
| 902 | thaw_processes(); | 909 | thaw_processes(); |
| 903 | Finish: | 910 | Finish: |
| @@ -93,7 +93,7 @@ static void kunit_print_ok_not_ok(void *test_or_suite, · 92 unmodified lines | |||
| 93 | * representation. | 93 | * representation. |
| 94 | */ | 94 | */ |
| 95 | if (suite) | 95 | if (suite) |
| 96 | pr_info("%s %zd - %s", | 96 | pr_info("%s %zd - %s\n", |
| 97 | kunit_status_to_string(is_ok), | 97 | kunit_status_to_string(is_ok), |
| 98 | test_number, description); | 98 | test_number, description); |
| 99 | else | 99 | else |
| @@ -880,6 +880,20 @@ EXPORT_SYMBOL_GPL(rpc_shutdown_client); · 879 unmodified lines | |||
| 880 | /* | 880 | /* |
| 881 | * Free an RPC client | 881 | * Free an RPC client |
| 882 | */ | 882 | */ |
| 883 | static void rpc_free_client_work(struct work_struct *work) | ||
| 884 | { | ||
| 885 | struct rpc_clnt *clnt = container_of(work, struct rpc_clnt, cl_work); | ||
| 886 | |||
| 887 | /* These might block on processes that might allocate memory, | ||
| 888 | * so they cannot be called in rpciod, so they are handled separately | ||
| 889 | * here. | ||
| 890 | */ | ||
| 891 | rpc_clnt_debugfs_unregister(clnt); | ||
| 892 | rpc_clnt_remove_pipedir(clnt); | ||
| 893 | |||
| 894 | kfree(clnt); | ||
| 895 | rpciod_down(); | ||
| 896 | } | ||
| 883 | static struct rpc_clnt * | 897 | static struct rpc_clnt * |
| 884 | rpc_free_client(struct rpc_clnt *clnt) | 898 | rpc_free_client(struct rpc_clnt *clnt) |
| 885 | { | 899 | { |
| @@ -890,17 +904,16 @@ rpc_free_client(struct rpc_clnt *clnt) · 4 unmodified lines | |||
| 890 | rcu_dereference(clnt->cl_xprt)->servername); | 904 | rcu_dereference(clnt->cl_xprt)->servername); |
| 891 | if (clnt->cl_parent != clnt) | 905 | if (clnt->cl_parent != clnt) |
| 892 | parent = clnt->cl_parent; | 906 | parent = clnt->cl_parent; |
| 893 | rpc_clnt_debugfs_unregister(clnt); | ||
| 894 | rpc_clnt_remove_pipedir(clnt); | ||
| 895 | rpc_unregister_client(clnt); | 907 | rpc_unregister_client(clnt); |
| 896 | rpc_free_iostats(clnt->cl_metrics); | 908 | rpc_free_iostats(clnt->cl_metrics); |
| 897 | clnt->cl_metrics = NULL; | 909 | clnt->cl_metrics = NULL; |
| 898 | xprt_put(rcu_dereference_raw(clnt->cl_xprt)); | 910 | xprt_put(rcu_dereference_raw(clnt->cl_xprt)); |
| 899 | xprt_iter_destroy(&clnt->cl_xpi); | 911 | xprt_iter_destroy(&clnt->cl_xpi); |
| 900 | rpciod_down(); | ||
| 901 | put_cred(clnt->cl_cred); | 912 | put_cred(clnt->cl_cred); |
| 902 | rpc_free_clid(clnt); | 913 | rpc_free_clid(clnt); |
| 903 | kfree(clnt); | 914 | |
| 915 | INIT_WORK(&clnt->cl_work, rpc_free_client_work); | ||
| 916 | schedule_work(&clnt->cl_work); | ||
| 904 | return parent; | 917 | return parent; |
| 905 | } | 918 | } |
| 906 | 919 | ||
| @@ -2808,8 +2821,7 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, · 1901 unmodified lines | |||
| 2808 | task = rpc_call_null_helper(clnt, xprt, NULL, | 2821 | task = rpc_call_null_helper(clnt, xprt, NULL, |
| 2809 | RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC|RPC_TASK_NULLCREDS, | 2822 | RPC_TASK_SOFT|RPC_TASK_SOFTCONN|RPC_TASK_ASYNC|RPC_TASK_NULLCREDS, |
| 2810 | &rpc_cb_add_xprt_call_ops, data); | 2823 | &rpc_cb_add_xprt_call_ops, data); |
| 2811 | if (IS_ERR(task)) | 2824 | |
| 2812 | return PTR_ERR(task); | ||
| 2813 | rpc_put_task(task); | 2825 | rpc_put_task(task); |
| 2814 | success: | 2826 | success: |
| 2815 | return 1; | 2827 | return 1; |
| @@ -388,7 +388,9 @@ static int rpcrdma_encode_read_list(struct rpcrdma_xprt *r_xprt, · 387 unmodified lines | |||
| 388 | } while (nsegs); | 388 | } while (nsegs); |
| 389 | 389 | ||
| 390 | done: | 390 | done: |
| 391 | return xdr_stream_encode_item_absent(xdr); | 391 | if (xdr_stream_encode_item_absent(xdr) < 0) |
| 392 | return -EMSGSIZE; | ||
| 393 | return 0; | ||
| 392 | } | 394 | } |
| 393 | 395 | ||
| 394 | /* Register and XDR encode the Write list. Supports encoding a list | 396 | /* Register and XDR encode the Write list. Supports encoding a list |
| @@ -454,7 +456,9 @@ static int rpcrdma_encode_write_list(struct rpcrdma_xprt *r_xprt, · 59 unmodified lines | |||
| 454 | *segcount = cpu_to_be32(nchunks); | 456 | *segcount = cpu_to_be32(nchunks); |
| 455 | 457 | ||
| 456 | done: | 458 | done: |
| 457 | return xdr_stream_encode_item_absent(xdr); | 459 | if (xdr_stream_encode_item_absent(xdr) < 0) |
| 460 | return -EMSGSIZE; | ||
| 461 | return 0; | ||
| 458 | } | 462 | } |
| 459 | 463 | ||
| 460 | /* Register and XDR encode the Reply chunk. Supports encoding an array | 464 | /* Register and XDR encode the Reply chunk. Supports encoding an array |
| @@ -480,8 +484,11 @@ static int rpcrdma_encode_reply_chunk(struct rpcrdma_xprt *r_xprt, · 19 unmodified lines | |||
| 480 | int nsegs, nchunks; | 484 | int nsegs, nchunks; |
| 481 | __be32 *segcount; | 485 | __be32 *segcount; |
| 482 | 486 | ||
| 483 | if (wtype != rpcrdma_replych) | 487 | if (wtype != rpcrdma_replych) { |
| 484 | return xdr_stream_encode_item_absent(xdr); | 488 | if (xdr_stream_encode_item_absent(xdr) < 0) |
| 489 | return -EMSGSIZE; | ||
| 490 | return 0; | ||
| 491 | } | ||
| 485 | 492 | ||
| 486 | seg = req->rl_segments; | 493 | seg = req->rl_segments; |
| 487 | nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_rcv_buf, 0, wtype, seg); | 494 | nsegs = rpcrdma_convert_iovs(r_xprt, &rqst->rq_rcv_buf, 0, wtype, seg); |
| @@ -289,6 +289,7 @@ rpcrdma_cm_event_handler(struct rdma_cm_id *id, struct rdma_cm_event *event) · 288 unmodified lines | |||
| 289 | case RDMA_CM_EVENT_DISCONNECTED: | 289 | case RDMA_CM_EVENT_DISCONNECTED: |
| 290 | ep->re_connect_status = -ECONNABORTED; | 290 | ep->re_connect_status = -ECONNABORTED; |
| 291 | disconnected: | 291 | disconnected: |
| 292 | xprt_force_disconnect(xprt); | ||
| 292 | return rpcrdma_ep_destroy(ep); | 293 | return rpcrdma_ep_destroy(ep); |
| 293 | default: | 294 | default: |
| 294 | break; | 295 | break; |
| @@ -1355,8 +1356,8 @@ int rpcrdma_post_sends(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req) · 1060 unmodified lines | |||
| 1355 | --ep->re_send_count; | 1356 | --ep->re_send_count; |
| 1356 | } | 1357 | } |
| 1357 | 1358 | ||
| 1359 | trace_xprtrdma_post_send(req); | ||
| 1358 | rc = frwr_send(r_xprt, req); | 1360 | rc = frwr_send(r_xprt, req); |
| 1359 | trace_xprtrdma_post_send(req, rc); | ||
| 1360 | if (rc) | 1361 | if (rc) |
| 1361 | return -ENOTCONN; | 1362 | return -ENOTCONN; |
| 1362 | return 0; | 1363 | return 0; |
| @@ -5842,40 +5842,60 @@ static unsigned int selinux_ipv6_postroute(void *priv, · 5841 unmodified lines | |||
| 5842 | 5842 | ||
| 5843 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | 5843 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 5844 | { | 5844 | { |
| 5845 | int err = 0; | 5845 | int rc = 0; |
| 5846 | u32 perm; | 5846 | unsigned int msg_len; |
| 5847 | unsigned int data_len = skb->len; | ||
| 5848 | unsigned char *data = skb->data; | ||
| 5847 | struct nlmsghdr *nlh; | 5849 | struct nlmsghdr *nlh; |
| 5848 | struct sk_security_struct *sksec = sk->sk_security; | 5850 | struct sk_security_struct *sksec = sk->sk_security; |
| 5851 | u16 sclass = sksec->sclass; | ||
| 5852 | u32 perm; | ||
| 5849 | 5853 | ||
| 5850 | if (skb->len < NLMSG_HDRLEN) { | 5854 | while (data_len >= nlmsg_total_size(0)) { |
| 5851 | err = -EINVAL; | 5855 | nlh = (struct nlmsghdr *)data; |
| 5852 | goto out; | 5856 | |
| 5853 | } | 5857 | /* NOTE: the nlmsg_len field isn't reliably set by some netlink |
| 5854 | nlh = nlmsg_hdr(skb); | 5858 | * users which means we can't reject skb's with bogus |
| 5859 | * length fields; our solution is to follow what | ||
| 5860 | * netlink_rcv_skb() does and simply skip processing at | ||
| 5861 | * messages with length fields that are clearly junk | ||
| 5862 | */ | ||
| 5863 | if (nlh->nlmsg_len < NLMSG_HDRLEN || nlh->nlmsg_len > data_len) | ||
| 5864 | return 0; | ||
| 5855 | 5865 | ||
| 5856 | err = selinux_nlmsg_lookup(sksec->sclass, nlh->nlmsg_type, &perm); | 5866 | rc = selinux_nlmsg_lookup(sclass, nlh->nlmsg_type, &perm); |
| 5857 | if (err) { | 5867 | if (rc == 0) { |
| 5858 | if (err == -EINVAL) { | 5868 | rc = sock_has_perm(sk, perm); |
| 5869 | if (rc) | ||
| 5870 | return rc; | ||
| 5871 | } else if (rc == -EINVAL) { | ||
| 5872 | /* -EINVAL is a missing msg/perm mapping */ | ||
| 5859 | pr_warn_ratelimited("SELinux: unrecognized netlink" | 5873 | pr_warn_ratelimited("SELinux: unrecognized netlink" |
| 5860 | " message: protocol=%hu nlmsg_type=%hu sclass=%s" | 5874 | " message: protocol=%hu nlmsg_type=%hu sclass=%s" |
| 5861 | " pid=%d comm=%s\n", | 5875 | " pid=%d comm=%s\n", |
| 5862 | sk->sk_protocol, nlh->nlmsg_type, | 5876 | sk->sk_protocol, nlh->nlmsg_type, |
| 5863 | secclass_map[sksec->sclass - 1].name, | 5877 | secclass_map[sclass - 1].name, |
| 5864 | task_pid_nr(current), current->comm); | 5878 | task_pid_nr(current), current->comm); |
| 5865 | if (!enforcing_enabled(&selinux_state) || | 5879 | if (enforcing_enabled(&selinux_state) && |
| 5866 | security_get_allow_unknown(&selinux_state)) | 5880 | !security_get_allow_unknown(&selinux_state)) |
| 5867 | err = 0; | 5881 | return rc; |
| 5882 | rc = 0; | ||
| 5883 | } else if (rc == -ENOENT) { | ||
| 5884 | /* -ENOENT is a missing socket/class mapping, ignore */ | ||
| 5885 | rc = 0; | ||
| 5886 | } else { | ||
| 5887 | return rc; | ||
| 5868 | } | 5888 | } |
| 5869 | 5889 | ||
| 5870 | /* Ignore */ | 5890 | /* move to the next message after applying netlink padding */ |
| 5871 | if (err == -ENOENT) | 5891 | msg_len = NLMSG_ALIGN(nlh->nlmsg_len); |
| 5872 | err = 0; | 5892 | if (msg_len >= data_len) |
| 5873 | goto out; | 5893 | return 0; |
| 5894 | data_len -= msg_len; | ||
| 5895 | data += msg_len; | ||
| 5874 | } | 5896 | } |
| 5875 | 5897 | ||
| 5876 | err = sock_has_perm(sk, perm); | 5898 | return rc; |
| 5877 | out: | ||
| 5878 | return err; | ||
| 5879 | } | 5899 | } |
| 5880 | 5900 | ||
| 5881 | static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) | 5901 | static void ipc_init_security(struct ipc_security_struct *isec, u16 sclass) |
| @@ -429,7 +429,7 @@ int cond_read_list(struct policydb *p, void *fp) · 428 unmodified lines | |||
| 429 | 429 | ||
| 430 | p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL); | 430 | p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL); |
| 431 | if (!p->cond_list) | 431 | if (!p->cond_list) |
| 432 | return rc; | 432 | return -ENOMEM; |
| 433 | 433 | ||
| 434 | rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel); | 434 | rc = avtab_alloc(&(p->te_cond_avtab), p->te_avtab.nel); |
| 435 | if (rc) | 435 | if (rc) |
| @@ -205,13 +205,14 @@ static snd_pcm_sframes_t calc_dst_frames(struct snd_pcm_substream *plug, · 204 unmodified lines | |||
| 205 | plugin = snd_pcm_plug_first(plug); | 205 | plugin = snd_pcm_plug_first(plug); |
| 206 | while (plugin && frames > 0) { | 206 | while (plugin && frames > 0) { |
| 207 | plugin_next = plugin->next; | 207 | plugin_next = plugin->next; |
| 208 | if (check_size && plugin->buf_frames && | ||
| 209 | frames > plugin->buf_frames) | ||
| 210 | frames = plugin->buf_frames; | ||
| 208 | if (plugin->dst_frames) { | 211 | if (plugin->dst_frames) { |
| 209 | frames = plugin->dst_frames(plugin, frames); | 212 | frames = plugin->dst_frames(plugin, frames); |
| 210 | if (frames < 0) | 213 | if (frames < 0) |
| 211 | return frames; | 214 | return frames; |
| 212 | } | 215 | } |
| 213 | if (check_size && frames > plugin->buf_frames) | ||
| 214 | frames = plugin->buf_frames; | ||
| 215 | plugin = plugin_next; | 216 | plugin = plugin_next; |
| 216 | } | 217 | } |
| 217 | return frames; | 218 | return frames; |
| @@ -225,14 +226,15 @@ static snd_pcm_sframes_t calc_src_frames(struct snd_pcm_substream *plug, · 7 unmodified lines | |||
| 225 | 226 | ||
| 226 | plugin = snd_pcm_plug_last(plug); | 227 | plugin = snd_pcm_plug_last(plug); |
| 227 | while (plugin && frames > 0) { | 228 | while (plugin && frames > 0) { |
| 228 | if (check_size && frames > plugin->buf_frames) | ||
| 229 | frames = plugin->buf_frames; | ||
| 230 | plugin_prev = plugin->prev; | 229 | plugin_prev = plugin->prev; |
| 231 | if (plugin->src_frames) { | 230 | if (plugin->src_frames) { |
| 232 | frames = plugin->src_frames(plugin, frames); | 231 | frames = plugin->src_frames(plugin, frames); |
| 233 | if (frames < 0) | 232 | if (frames < 0) |
| 234 | return frames; | 233 | return frames; |
| 235 | } | 234 | } |
| 235 | if (check_size && plugin->buf_frames && | ||
| 236 | frames > plugin->buf_frames) | ||
| 237 | frames = plugin->buf_frames; | ||
| 236 | plugin = plugin_prev; | 238 | plugin = plugin_prev; |
| 237 | } | 239 | } |
| 238 | return frames; | 240 | return frames; |
| @@ -867,10 +867,13 @@ static void snd_miro_write(struct snd_miro *chip, unsigned char reg, · 866 unmodified lines | |||
| 867 | spin_unlock_irqrestore(&chip->lock, flags); | 867 | spin_unlock_irqrestore(&chip->lock, flags); |
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | static inline void snd_miro_write_mask(struct snd_miro *chip, | ||
| 871 | unsigned char reg, unsigned char value, unsigned char mask) | ||
| 872 | { | ||
| 873 | unsigned char oldval = snd_miro_read(chip, reg); | ||
| 870 | 874 | ||
| 871 | #define snd_miro_write_mask(chip, reg, value, mask) \ | 875 | snd_miro_write(chip, reg, (oldval & ~mask) | (value & mask)); |
| 872 | snd_miro_write(chip, reg, \ | 876 | } |
| 873 | (snd_miro_read(chip, reg) & ~(mask)) | ((value) & (mask))) | ||
| 874 | 877 | ||
| 875 | /* | 878 | /* |
| 876 | * Proc Interface | 879 | * Proc Interface |
| @@ -317,10 +317,13 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, · 316 unmodified lines | |||
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | 319 | ||
| 320 | #define snd_opti9xx_write_mask(chip, reg, value, mask) \ | 320 | static inline void snd_opti9xx_write_mask(struct snd_opti9xx *chip, |
| 321 | snd_opti9xx_write(chip, reg, \ | 321 | unsigned char reg, unsigned char value, unsigned char mask) |
| 322 | (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) | 322 | { |
| 323 | unsigned char oldval = snd_opti9xx_read(chip, reg); | ||
| 323 | 324 | ||
| 325 | snd_opti9xx_write(chip, reg, (oldval & ~mask) | (value & mask)); | ||
| 326 | } | ||
| 324 | 327 | ||
| 325 | static int snd_opti9xx_configure(struct snd_opti9xx *chip, | 328 | static int snd_opti9xx_configure(struct snd_opti9xx *chip, |
| 326 | long port, | 329 | long port, |
| @@ -2078,9 +2078,10 @@ static void pcm_mmap_prepare(struct snd_pcm_substream *substream, · 2077 unmodified lines | |||
| 2078 | * some HD-audio PCI entries are exposed without any codecs, and such devices | 2078 | * some HD-audio PCI entries are exposed without any codecs, and such devices |
| 2079 | * should be ignored from the beginning. | 2079 | * should be ignored from the beginning. |
| 2080 | */ | 2080 | */ |
| 2081 | static const struct snd_pci_quirk driver_blacklist[] = { | 2081 | static const struct pci_device_id driver_blacklist[] = { |
| 2082 | SND_PCI_QUIRK(0x1462, 0xcb59, "MSI TRX40 Creator", 0), | 2082 | { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1043, 0x874f) }, /* ASUS ROG Zenith II / Strix */ |
| 2083 | SND_PCI_QUIRK(0x1462, 0xcb60, "MSI TRX40", 0), | 2083 | { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb59) }, /* MSI TRX40 Creator */ |
| 2084 | { PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb60) }, /* MSI TRX40 */ | ||
| 2084 | {} | 2085 | {} |
| 2085 | }; | 2086 | }; |
| 2086 | 2087 | ||
| @@ -2100,7 +2101,7 @@ static int azx_probe(struct pci_dev *pci, · 13 unmodified lines | |||
| 2100 | bool schedule_probe; | 2101 | bool schedule_probe; |
| 2101 | int err; | 2102 | int err; |
| 2102 | 2103 | ||
| 2103 | if (snd_pci_quirk_lookup(pci, driver_blacklist)) { | 2104 | if (pci_match_id(driver_blacklist, pci)) { |
| 2104 | dev_info(&pci->dev, "Skipping the blacklisted device\n"); | 2105 | dev_info(&pci->dev, "Skipping the blacklisted device\n"); |
| 2105 | return -ENODEV; | 2106 | return -ENODEV; |
| 2106 | } | 2107 | } |
| @@ -1848,8 +1848,10 @@ static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) · 1847 unmodified lines | |||
| 1848 | /* Add sanity check to pass klockwork check. | 1848 | /* Add sanity check to pass klockwork check. |
| 1849 | * This should never happen. | 1849 | * This should never happen. |
| 1850 | */ | 1850 | */ |
| 1851 | if (WARN_ON(spdif == NULL)) | 1851 | if (WARN_ON(spdif == NULL)) { |
| 1852 | mutex_unlock(&codec->spdif_mutex); | ||
| 1852 | return true; | 1853 | return true; |
| 1854 | } | ||
| 1853 | non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO); | 1855 | non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO); |
| 1854 | mutex_unlock(&codec->spdif_mutex); | 1856 | mutex_unlock(&codec->spdif_mutex); |
| 1855 | return non_pcm; | 1857 | return non_pcm; |
| @@ -2198,7 +2200,9 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) · 342 unmodified lines | |||
| 2198 | 2200 | ||
| 2199 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 2201 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
| 2200 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | 2202 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
| 2203 | struct hdmi_eld *pin_eld = &per_pin->sink_eld; | ||
| 2201 | 2204 | ||
| 2205 | pin_eld->eld_valid = false; | ||
| 2202 | hdmi_present_sense(per_pin, 0); | 2206 | hdmi_present_sense(per_pin, 0); |
| 2203 | } | 2207 | } |
| 2204 | 2208 | ||
| @@ -7420,6 +7420,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { · 7419 unmodified lines | |||
| 7420 | SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), | 7420 | SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), |
| 7421 | SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), | 7421 | SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC), |
| 7422 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), | 7422 | SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS), |
| 7423 | SND_PCI_QUIRK(0x17aa, 0x1048, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC), | ||
| 7423 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 7424 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
| 7424 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), | 7425 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
| 7425 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), | 7426 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
| @@ -21,8 +21,7 @@ · 20 unmodified lines | |||
| 21 | enum { | 21 | enum { |
| 22 | LINE6_PODHD300, | 22 | LINE6_PODHD300, |
| 23 | LINE6_PODHD400, | 23 | LINE6_PODHD400, |
| 24 | LINE6_PODHD500_0, | 24 | LINE6_PODHD500, |
| 25 | LINE6_PODHD500_1, | ||
| 26 | LINE6_PODX3, | 25 | LINE6_PODX3, |
| 27 | LINE6_PODX3LIVE, | 26 | LINE6_PODX3LIVE, |
| 28 | LINE6_PODHD500X, | 27 | LINE6_PODHD500X, |
| @@ -318,8 +317,7 @@ static const struct usb_device_id podhd_id_table[] = { · 289 unmodified lines | |||
| 318 | /* TODO: no need to alloc data interfaces when only audio is used */ | 317 | /* TODO: no need to alloc data interfaces when only audio is used */ |
| 319 | { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, | 318 | { LINE6_DEVICE(0x5057), .driver_info = LINE6_PODHD300 }, |
| 320 | { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, | 319 | { LINE6_DEVICE(0x5058), .driver_info = LINE6_PODHD400 }, |
| 321 | { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500_0 }, | 320 | { LINE6_IF_NUM(0x414D, 0), .driver_info = LINE6_PODHD500 }, |
| 322 | { LINE6_IF_NUM(0x414D, 1), .driver_info = LINE6_PODHD500_1 }, | ||
| 323 | { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, | 321 | { LINE6_IF_NUM(0x414A, 0), .driver_info = LINE6_PODX3 }, |
| 324 | { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, | 322 | { LINE6_IF_NUM(0x414B, 0), .driver_info = LINE6_PODX3LIVE }, |
| 325 | { LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X }, | 323 | { LINE6_IF_NUM(0x4159, 0), .driver_info = LINE6_PODHD500X }, |
| @@ -352,23 +350,13 @@ static const struct line6_properties podhd_properties_table[] = { · 26 unmodified lines | |||
| 352 | .ep_audio_r = 0x82, | 350 | .ep_audio_r = 0x82, |
| 353 | .ep_audio_w = 0x01, | 351 | .ep_audio_w = 0x01, |
| 354 | }, | 352 | }, |
| 355 | [LINE6_PODHD500_0] = { | 353 | [LINE6_PODHD500] = { |
| 356 | .id = "PODHD500", | 354 | .id = "PODHD500", |
| 357 | .name = "POD HD500", | 355 | .name = "POD HD500", |
| 358 | .capabilities = LINE6_CAP_PCM | 356 | .capabilities = LINE6_CAP_PCM | LINE6_CAP_CONTROL |
| 359 | | LINE6_CAP_HWMON, | 357 | | LINE6_CAP_HWMON, |
| 360 | .altsetting = 1, | 358 | .altsetting = 1, |
| 361 | .ep_ctrl_r = 0x81, | 359 | .ctrl_if = 1, |
| 362 | .ep_ctrl_w = 0x01, | ||
| 363 | .ep_audio_r = 0x86, | ||
| 364 | .ep_audio_w = 0x02, | ||
| 365 | }, | ||
| 366 | [LINE6_PODHD500_1] = { | ||
| 367 | .id = "PODHD500", | ||
| 368 | .name = "POD HD500", | ||
| 369 | .capabilities = LINE6_CAP_PCM | ||
| 370 | | LINE6_CAP_HWMON, | ||
| 371 | .altsetting = 0, | ||
| 372 | .ep_ctrl_r = 0x81, | 360 | .ep_ctrl_r = 0x81, |
| 373 | .ep_ctrl_w = 0x01, | 361 | .ep_ctrl_w = 0x01, |
| 374 | .ep_audio_r = 0x86, | 362 | .ep_audio_r = 0x86, |
| @@ -1687,7 +1687,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, · 1686 unmodified lines | |||
| 1687 | 1687 | ||
| 1688 | case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ | 1688 | case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ |
| 1689 | case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */ | 1689 | case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */ |
| 1690 | case USB_ID(0x16b0, 0x06b2): /* NuPrime DAC-10 */ | 1690 | case USB_ID(0x16d0, 0x06b2): /* NuPrime DAC-10 */ |
| 1691 | case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ | 1691 | case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ |
| 1692 | case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */ | 1692 | case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */ |
| 1693 | case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ | 1693 | case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ |
| @@ -10,10 +10,7 @@ if ! grep -q function_graph available_tracers; then · 9 unmodified lines | |||
| 10 | exit_unsupported | 10 | exit_unsupported |
| 11 | fi | 11 | fi |
| 12 | 12 | ||
| 13 | if [ ! -f set_ftrace_filter ]; then | 13 | check_filter_file set_ftrace_filter |
| 14 | echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | ||
| 15 | exit_unsupported | ||
| 16 | fi | ||
| 17 | 14 | ||
| 18 | do_reset() { | 15 | do_reset() { |
| 19 | if [ -e /proc/sys/kernel/stack_tracer_enabled ]; then | 16 | if [ -e /proc/sys/kernel/stack_tracer_enabled ]; then |
| @@ -9,6 +9,8 @@ if ! grep -q function_graph available_tracers; then · 8 unmodified lines | |||
| 9 | exit_unsupported | 9 | exit_unsupported |
| 10 | fi | 10 | fi |
| 11 | 11 | ||
| 12 | check_filter_file set_ftrace_filter | ||
| 13 | |||
| 12 | fail() { # msg | 14 | fail() { # msg |
| 13 | echo $1 | 15 | echo $1 |
| 14 | exit_fail | 16 | exit_fail |
| @@ -9,6 +9,8 @@ if ! grep -q function available_tracers; then · 8 unmodified lines | |||
| 9 | exit_unsupported | 9 | exit_unsupported |
| 10 | fi | 10 | fi |
| 11 | 11 | ||
| 12 | check_filter_file set_ftrace_filter | ||
| 13 | |||
| 12 | disable_tracing | 14 | disable_tracing |
| 13 | clear_trace | 15 | clear_trace |
| 14 | 16 | ||
| @@ -15,10 +15,7 @@ if [ ! -f set_ftrace_notrace_pid ]; then · 14 unmodified lines | |||
| 15 | exit_unsupported | 15 | exit_unsupported |
| 16 | fi | 16 | fi |
| 17 | 17 | ||
| 18 | if [ ! -f set_ftrace_filter ]; then | 18 | check_filter_file set_ftrace_filter |
| 19 | echo "set_ftrace_filter not found? Is function tracer not set?" | ||
| 20 | exit_unsupported | ||
| 21 | fi | ||
| 22 | 19 | ||
| 23 | do_function_fork=1 | 20 | do_function_fork=1 |
| 24 | 21 | ||
| @@ -16,10 +16,7 @@ if [ ! -f set_ftrace_pid ]; then · 15 unmodified lines | |||
| 16 | exit_unsupported | 16 | exit_unsupported |
| 17 | fi | 17 | fi |
| 18 | 18 | ||
| 19 | if [ ! -f set_ftrace_filter ]; then | 19 | check_filter_file set_ftrace_filter |
| 20 | echo "set_ftrace_filter not found? Is function tracer not set?" | ||
| 21 | exit_unsupported | ||
| 22 | fi | ||
| 23 | 20 | ||
| 24 | do_function_fork=1 | 21 | do_function_fork=1 |
| 25 | 22 | ||
| @@ -3,7 +3,7 @@ · 2 unmodified lines | |||
| 3 | # description: ftrace - stacktrace filter command | 3 | # description: ftrace - stacktrace filter command |
| 4 | # flags: instance | 4 | # flags: instance |
| 5 | 5 | ||
| 6 | [ ! -f set_ftrace_filter ] && exit_unsupported | 6 | check_filter_file set_ftrace_filter |
| 7 | 7 | ||
| 8 | echo _do_fork:stacktrace >> set_ftrace_filter | 8 | echo _do_fork:stacktrace >> set_ftrace_filter |
| 9 | 9 | ||
| @@ -11,10 +11,7 @@ · 10 unmodified lines | |||
| 11 | # | 11 | # |
| 12 | 12 | ||
| 13 | # The triggers are set within the set_ftrace_filter file | 13 | # The triggers are set within the set_ftrace_filter file |
| 14 | if [ ! -f set_ftrace_filter ]; then | 14 | check_filter_file set_ftrace_filter |
| 15 | echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | ||
| 16 | exit_unsupported | ||
| 17 | fi | ||
| 18 | 15 | ||
| 19 | do_reset() { | 16 | do_reset() { |
| 20 | reset_ftrace_filter | 17 | reset_ftrace_filter |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | # description: ftrace - function trace on module | 3 | # description: ftrace - function trace on module |
| 4 | 4 | ||
| 5 | [ ! -f set_ftrace_filter ] && exit_unsupported | 5 | check_filter_file set_ftrace_filter |
| 6 | 6 | ||
| 7 | : "mod: allows to filter a non exist function" | 7 | : "mod: allows to filter a non exist function" |
| 8 | echo 'non_exist_func:mod:non_exist_module' > set_ftrace_filter | 8 | echo 'non_exist_func:mod:non_exist_module' > set_ftrace_filter |
| @@ -18,10 +18,7 @@ if ! grep -q function_graph available_tracers; then · 17 unmodified lines | |||
| 18 | exit_unsupported; | 18 | exit_unsupported; |
| 19 | fi | 19 | fi |
| 20 | 20 | ||
| 21 | if [ ! -f set_ftrace_filter ]; then | 21 | check_filter_file set_ftrace_filter |
| 22 | echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | ||
| 23 | exit_unsupported | ||
| 24 | fi | ||
| 25 | 22 | ||
| 26 | if [ ! -f function_profile_enabled ]; then | 23 | if [ ! -f function_profile_enabled ]; then |
| 27 | echo "function_profile_enabled not found, function profiling enabled?" | 24 | echo "function_profile_enabled not found, function profiling enabled?" |
| @@ -10,10 +10,7 @@ · 9 unmodified lines | |||
| 10 | # | 10 | # |
| 11 | 11 | ||
| 12 | # The triggers are set within the set_ftrace_filter file | 12 | # The triggers are set within the set_ftrace_filter file |
| 13 | if [ ! -f set_ftrace_filter ]; then | 13 | check_filter_file set_ftrace_filter |
| 14 | echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | ||
| 15 | exit_unsupported | ||
| 16 | fi | ||
| 17 | 14 | ||
| 18 | fail() { # mesg | 15 | fail() { # mesg |
| 19 | echo $1 | 16 | echo $1 |
| @@ -8,6 +8,8 @@ if [ ! -f stack_trace ]; then · 7 unmodified lines | |||
| 8 | exit_unsupported | 8 | exit_unsupported |
| 9 | fi | 9 | fi |
| 10 | 10 | ||
| 11 | check_filter_file stack_trace_filter | ||
| 12 | |||
| 11 | echo > stack_trace_filter | 13 | echo > stack_trace_filter |
| 12 | echo 0 > stack_max_size | 14 | echo 0 > stack_max_size |
| 13 | echo 1 > /proc/sys/kernel/stack_tracer_enabled | 15 | echo 1 > /proc/sys/kernel/stack_tracer_enabled |
| @@ -11,10 +11,7 @@ · 10 unmodified lines | |||
| 11 | # | 11 | # |
| 12 | 12 | ||
| 13 | # The triggers are set within the set_ftrace_filter file | 13 | # The triggers are set within the set_ftrace_filter file |
| 14 | if [ ! -f set_ftrace_filter ]; then | 14 | check_filter_file set_ftrace_filter |
| 15 | echo "set_ftrace_filter not found? Is dynamic ftrace not set?" | ||
| 16 | exit_unsupported | ||
| 17 | fi | ||
| 18 | 15 | ||
| 19 | fail() { # mesg | 16 | fail() { # mesg |
| 20 | echo $1 | 17 | echo $1 |
| @@ -1,3 +1,9 @@ | |||
| 1 | check_filter_file() { # check filter file introduced by dynamic ftrace | ||
| 2 | if [ ! -f "$1" ]; then | ||
| 3 | echo "$1 not found? Is dynamic ftrace not set?" | ||
| 4 | exit_unsupported | ||
| 5 | fi | ||
| 6 | } | ||
| 1 | 7 | ||
| 2 | clear_trace() { # reset trace output | 8 | clear_trace() { # reset trace output |
| 3 | echo > trace | 9 | echo > trace |
| @@ -38,7 +38,7 @@ for width in 64 32 16 8; do · 37 unmodified lines | |||
| 38 | echo 0 > events/kprobes/testprobe/enable | 38 | echo 0 > events/kprobes/testprobe/enable |
| 39 | 39 | ||
| 40 | : "Confirm the arguments is recorded in given types correctly" | 40 | : "Confirm the arguments is recorded in given types correctly" |
| 41 | ARGS=`grep "testprobe" trace | sed -e 's/.* arg1=\(.*\) arg2=\(.*\) arg3=\(.*\) arg4=\(.*\)/\1 \2 \3 \4/'` | 41 | ARGS=`grep "testprobe" trace | head -n 1 | sed -e 's/.* arg1=\(.*\) arg2=\(.*\) arg3=\(.*\) arg4=\(.*\)/\1 \2 \3 \4/'` |
| 42 | check_types $ARGS $width | 42 | check_types $ARGS $width |
| 43 | 43 | ||
| 44 | : "Clear event for next loop" | 44 | : "Clear event for next loop" |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | |||
| 5 | [ -f kprobe_events ] || exit_unsupported # this is configurable | 5 | [ -f kprobe_events ] || exit_unsupported # this is configurable |
| 6 | grep "function" available_tracers || exit_unsupported # this is configurable | 6 | grep "function" available_tracers || exit_unsupported # this is configurable |
| 7 | 7 | ||
| 8 | check_filter_file set_ftrace_filter | ||
| 9 | |||
| 8 | # prepare | 10 | # prepare |
| 9 | echo nop > current_tracer | 11 | echo nop > current_tracer |
| 10 | echo _do_fork > set_ftrace_filter | 12 | echo _do_fork > set_ftrace_filter |
| @@ -1,13 +1,13 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | ||
| 3 | MOUNT_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null) | 3 | VAR_CFLAGS := $(shell pkg-config --cflags mount 2>/dev/null) |
| 4 | MOUNT_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null) | 4 | VAR_LDLIBS := $(shell pkg-config --libs mount 2>/dev/null) |
| 5 | ifeq ($(MOUNT_LDLIBS),) | 5 | ifeq ($(VAR_LDLIBS),) |
| 6 | MOUNT_LDLIBS := -lmount -I/usr/include/libmount | 6 | VAR_LDLIBS := -lmount -I/usr/include/libmount |
| 7 | endif | 7 | endif |
| 8 | 8 | ||
| 9 | CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(MOUNT_CFLAGS) | 9 | CFLAGS += -O2 -g -std=gnu99 -Wall -I../../../../usr/include/ $(VAR_CFLAGS) |
| 10 | LDLIBS += $(MOUNT_LDLIBS) | 10 | LDLIBS += $(VAR_LDLIBS) |
| 11 | 11 | ||
| 12 | TEST_PROGS := gpio-mockup.sh | 12 | TEST_PROGS := gpio-mockup.sh |
| 13 | TEST_FILES := gpio-mockup-sysfs.sh | 13 | TEST_FILES := gpio-mockup-sysfs.sh |
| @@ -1,6 +1,6 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE | 2 | CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE |
| 3 | LDLIBS := $(LDLIBS) -lm | 3 | LDLIBS += -lm |
| 4 | 4 | ||
| 5 | uname_M := $(shell uname -m 2>/dev/null || echo not) | 5 | uname_M := $(shell uname -m 2>/dev/null || echo not) |
| 6 | ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) | 6 | ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) |
| @@ -0,0 +1,272 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | # SPDX-License-Identifier: GPL-2.0 | ||
| 3 | # kselftest_deps.sh | ||
| 4 | # | ||
| 5 | # Checks for kselftest build dependencies on the build system. | ||
| 6 | # Copyright (c) 2020 Shuah Khan <skhan@linuxfoundation.org> | ||
| 7 | # | ||
| 8 | # | ||
| 9 | |||
| 10 | usage() | ||
| 11 | { | ||
| 12 | |||
| 13 | echo -e "Usage: $0 -[p] <compiler> [test_name]\n" | ||
| 14 | echo -e "\tkselftest_deps.sh [-p] gcc" | ||
| 15 | echo -e "\tkselftest_deps.sh [-p] gcc vm" | ||
| 16 | echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc" | ||
| 17 | echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc vm\n" | ||
| 18 | echo "- Should be run in selftests directory in the kernel repo." | ||
| 19 | echo "- Checks if Kselftests can be built/cross-built on a system." | ||
| 20 | echo "- Parses all test/sub-test Makefile to find library dependencies." | ||
| 21 | echo "- Runs compile test on a trivial C file with LDLIBS specified" | ||
| 22 | echo " in the test Makefiles to identify missing library dependencies." | ||
| 23 | echo "- Prints suggested target list for a system filtering out tests" | ||
| 24 | echo " failed the build dependency check from the TARGETS in Selftests" | ||
| 25 | echo " main Makefile when optional -p is specified." | ||
| 26 | echo "- Prints pass/fail dependency check for each tests/sub-test." | ||
| 27 | echo "- Prints pass/fail targets and libraries." | ||
| 28 | echo "- Default: runs dependency checks on all tests." | ||
| 29 | echo "- Optional test name can be specified to check dependencies for it." | ||
| 30 | exit 1 | ||
| 31 | |||
| 32 | } | ||
| 33 | |||
| 34 | # Start main() | ||
| 35 | main() | ||
| 36 | { | ||
| 37 | |||
| 38 | base_dir=`pwd` | ||
| 39 | # Make sure we're in the selftests top-level directory. | ||
| 40 | if [ $(basename "$base_dir") != "selftests" ]; then | ||
| 41 | echo -e "\tPlease run $0 in" | ||
| 42 | echo -e "\ttools/testing/selftests directory ..." | ||
| 43 | exit 1 | ||
| 44 | fi | ||
| 45 | |||
| 46 | print_targets=0 | ||
| 47 | |||
| 48 | while getopts "p" arg; do | ||
| 49 | case $arg in | ||
| 50 | p) | ||
| 51 | print_targets=1 | ||
| 52 | shift;; | ||
| 53 | esac | ||
| 54 | done | ||
| 55 | |||
| 56 | if [ $# -eq 0 ] | ||
| 57 | then | ||
| 58 | usage | ||
| 59 | fi | ||
| 60 | |||
| 61 | # Compiler | ||
| 62 | CC=$1 | ||
| 63 | |||
| 64 | tmp_file=$(mktemp).c | ||
| 65 | trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT | ||
| 66 | #echo $tmp_file | ||
| 67 | |||
| 68 | pass=$(mktemp).out | ||
| 69 | trap "rm -f $pass" EXIT | ||
| 70 | #echo $pass | ||
| 71 | |||
| 72 | fail=$(mktemp).out | ||
| 73 | trap "rm -f $fail" EXIT | ||
| 74 | #echo $fail | ||
| 75 | |||
| 76 | # Generate tmp source fire for compile test | ||
| 77 | cat << "EOF" > $tmp_file | ||
| 78 | int main() | ||
| 79 | { | ||
| 80 | } | ||
| 81 | EOF | ||
| 82 | |||
| 83 | # Save results | ||
| 84 | total_cnt=0 | ||
| 85 | fail_trgts=() | ||
| 86 | fail_libs=() | ||
| 87 | fail_cnt=0 | ||
| 88 | pass_trgts=() | ||
| 89 | pass_libs=() | ||
| 90 | pass_cnt=0 | ||
| 91 | |||
| 92 | # Get all TARGETS from selftests Makefile | ||
| 93 | targets=$(egrep "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) | ||
| 94 | |||
| 95 | # Single test case | ||
| 96 | if [ $# -eq 2 ] | ||
| 97 | then | ||
| 98 | test=$2/Makefile | ||
| 99 | |||
| 100 | l1_test $test | ||
| 101 | l2_test $test | ||
| 102 | l3_test $test | ||
| 103 | |||
| 104 | print_results $1 $2 | ||
| 105 | exit $? | ||
| 106 | fi | ||
| 107 | |||
| 108 | # Level 1: LDLIBS set static. | ||
| 109 | # | ||
| 110 | # Find all LDLIBS set statically for all executables built by a Makefile | ||
| 111 | # and filter out VAR_LDLIBS to discard the following: | ||
| 112 | # gpio/Makefile:LDLIBS += $(VAR_LDLIBS) | ||
| 113 | # Append space at the end of the list to append more tests. | ||
| 114 | |||
| 115 | l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ | ||
| 116 | grep -v "VAR_LDLIBS" | awk -F: '{print $1}') | ||
| 117 | |||
| 118 | # Level 2: LDLIBS set dynamically. | ||
| 119 | # | ||
| 120 | # Level 2 | ||
| 121 | # Some tests have multiple valid LDLIBS lines for individual sub-tests | ||
| 122 | # that need dependency checks. Find them and append them to the tests | ||
| 123 | # e.g: vm/Makefile:$(OUTPUT)/userfaultfd: LDLIBS += -lpthread | ||
| 124 | # Filter out VAR_LDLIBS to discard the following: | ||
| 125 | # memfd/Makefile:$(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) | ||
| 126 | # Append space at the end of the list to append more tests. | ||
| 127 | |||
| 128 | l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ | ||
| 129 | grep -v "VAR_LDLIBS" | awk -F: '{print $1}') | ||
| 130 | |||
| 131 | # Level 3 | ||
| 132 | # gpio, memfd and others use pkg-config to find mount and fuse libs | ||
| 133 | # respectively and save it in VAR_LDLIBS. If pkg-config doesn't find | ||
| 134 | # any, VAR_LDLIBS set to default. | ||
| 135 | # Use the default value and filter out pkg-config for dependency check. | ||
| 136 | # e.g: | ||
| 137 | # gpio/Makefile | ||
| 138 | # VAR_LDLIBS := $(shell pkg-config --libs mount) 2>/dev/null) | ||
| 139 | # memfd/Makefile | ||
| 140 | # VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) | ||
| 141 | |||
| 142 | l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \ | ||
| 143 | grep -v "pkg-config" | awk -F: '{print $1}') | ||
| 144 | |||
| 145 | #echo $l1_tests | ||
| 146 | #echo $l2_1_tests | ||
| 147 | #echo $l3_tests | ||
| 148 | |||
| 149 | all_tests | ||
| 150 | print_results $1 $2 | ||
| 151 | |||
| 152 | exit $? | ||
| 153 | } | ||
| 154 | # end main() | ||
| 155 | |||
| 156 | all_tests() | ||
| 157 | { | ||
| 158 | for test in $l1_tests; do | ||
| 159 | l1_test $test | ||
| 160 | done | ||
| 161 | |||
| 162 | for test in $l2_tests; do | ||
| 163 | l2_test $test | ||
| 164 | done | ||
| 165 | |||
| 166 | for test in $l3_tests; do | ||
| 167 | l3_test $test | ||
| 168 | done | ||
| 169 | } | ||
| 170 | |||
| 171 | # Use same parsing used for l1_tests and pick libraries this time. | ||
| 172 | l1_test() | ||
| 173 | { | ||
| 174 | test_libs=$(grep --include=Makefile "^LDLIBS" $test | \ | ||
| 175 | grep -v "VAR_LDLIBS" | \ | ||
| 176 | sed -e 's/\:/ /' | \ | ||
| 177 | sed -e 's/+/ /' | cut -d "=" -f 2) | ||
| 178 | |||
| 179 | check_libs $test $test_libs | ||
| 180 | } | ||
| 181 | |||
| 182 | # Use same parsing used for l2__tests and pick libraries this time. | ||
| 183 | l2_test() | ||
| 184 | { | ||
| 185 | test_libs=$(grep --include=Makefile ": LDLIBS" $test | \ | ||
| 186 | grep -v "VAR_LDLIBS" | \ | ||
| 187 | sed -e 's/\:/ /' | sed -e 's/+/ /' | \ | ||
| 188 | cut -d "=" -f 2) | ||
| 189 | |||
| 190 | check_libs $test $test_libs | ||
| 191 | } | ||
| 192 | |||
| 193 | l3_test() | ||
| 194 | { | ||
| 195 | test_libs=$(grep --include=Makefile "^VAR_LDLIBS" $test | \ | ||
| 196 | grep -v "pkg-config" | sed -e 's/\:/ /' | | ||
| 197 | sed -e 's/+/ /' | cut -d "=" -f 2) | ||
| 198 | |||
| 199 | check_libs $test $test_libs | ||
| 200 | } | ||
| 201 | |||
| 202 | check_libs() | ||
| 203 | { | ||
| 204 | |||
| 205 | if [[ ! -z "${test_libs// }" ]] | ||
| 206 | then | ||
| 207 | |||
| 208 | #echo $test_libs | ||
| 209 | |||
| 210 | for lib in $test_libs; do | ||
| 211 | |||
| 212 | let total_cnt+=1 | ||
| 213 | $CC -o $tmp_file.bin $lib $tmp_file > /dev/null 2>&1 | ||
| 214 | if [ $? -ne 0 ]; then | ||
| 215 | echo "FAIL: $test dependency check: $lib" >> $fail | ||
| 216 | let fail_cnt+=1 | ||
| 217 | fail_libs+="$lib " | ||
| 218 | fail_target=$(echo "$test" | cut -d "/" -f1) | ||
| 219 | fail_trgts+="$fail_target " | ||
| 220 | targets=$(echo "$targets" | grep -v "$fail_target") | ||
| 221 | else | ||
| 222 | echo "PASS: $test dependency check passed $lib" >> $pass | ||
| 223 | let pass_cnt+=1 | ||
| 224 | pass_libs+="$lib " | ||
| 225 | pass_trgts+="$(echo "$test" | cut -d "/" -f1) " | ||
| 226 | fi | ||
| 227 | |||
| 228 | done | ||
| 229 | fi | ||
| 230 | } | ||
| 231 | |||
| 232 | print_results() | ||
| 233 | { | ||
| 234 | echo -e "========================================================"; | ||
| 235 | echo -e "Kselftest Dependency Check for [$0 $1 $2] results..." | ||
| 236 | |||
| 237 | if [ $print_targets -ne 0 ] | ||
| 238 | then | ||
| 239 | echo -e "Suggested Selftest Targets for your configuration:" | ||
| 240 | echo -e "$targets"; | ||
| 241 | fi | ||
| 242 | |||
| 243 | echo -e "========================================================"; | ||
| 244 | echo -e "Checked tests defining LDLIBS dependencies" | ||
| 245 | echo -e "--------------------------------------------------------"; | ||
| 246 | echo -e "Total tests with Dependencies:" | ||
| 247 | echo -e "$total_cnt Pass: $pass_cnt Fail: $fail_cnt"; | ||
| 248 | |||
| 249 | if [ $pass_cnt -ne 0 ]; then | ||
| 250 | echo -e "--------------------------------------------------------"; | ||
| 251 | cat $pass | ||
| 252 | echo -e "--------------------------------------------------------"; | ||
| 253 | echo -e "Targets passed build dependency check on system:" | ||
| 254 | echo -e "$(echo "$pass_trgts" | xargs -n1 | sort -u | xargs)" | ||
| 255 | fi | ||
| 256 | |||
| 257 | if [ $fail_cnt -ne 0 ]; then | ||
| 258 | echo -e "--------------------------------------------------------"; | ||
| 259 | cat $fail | ||
| 260 | echo -e "--------------------------------------------------------"; | ||
| 261 | echo -e "Targets failed build dependency check on system:" | ||
| 262 | echo -e "$(echo "$fail_trgts" | xargs -n1 | sort -u | xargs)" | ||
| 263 | echo -e "--------------------------------------------------------"; | ||
| 264 | echo -e "Missing libraries system" | ||
| 265 | echo -e "$(echo "$fail_libs" | xargs -n1 | sort -u | xargs)" | ||
| 266 | fi | ||
| 267 | |||
| 268 | echo -e "--------------------------------------------------------"; | ||
| 269 | echo -e "========================================================"; | ||
| 270 | } | ||
| 271 | |||
| 272 | main "$@" | ||
| @@ -8,11 +8,21 @@ TEST_GEN_PROGS := memfd_test · 7 unmodified lines | |||
| 8 | TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh | 8 | TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh |
| 9 | TEST_GEN_FILES := fuse_test fuse_mnt | 9 | TEST_GEN_FILES := fuse_test fuse_mnt |
| 10 | 10 | ||
| 11 | fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) | 11 | VAR_CFLAGS := $(shell pkg-config fuse --cflags 2>/dev/null) |
| 12 | ifeq ($(VAR_CFLAGS),) | ||
| 13 | VAR_CFLAGS := -D_FILE_OFFSET_BITS=64 -I/usr/include/fuse | ||
| 14 | endif | ||
| 15 | |||
| 16 | VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) | ||
| 17 | ifeq ($(VAR_LDLIBS),) | ||
| 18 | VAR_LDLIBS := -lfuse -pthread | ||
| 19 | endif | ||
| 20 | |||
| 21 | fuse_mnt.o: CFLAGS += $(VAR_CFLAGS) | ||
| 12 | 22 | ||
| 13 | include ../lib.mk | 23 | include ../lib.mk |
| 14 | 24 | ||
| 15 | $(OUTPUT)/fuse_mnt: LDLIBS += $(shell pkg-config fuse --libs) | 25 | $(OUTPUT)/fuse_mnt: LDLIBS += $(VAR_LDLIBS) |
| 16 | 26 | ||
| 17 | $(OUTPUT)/memfd_test: memfd_test.c common.c | 27 | $(OUTPUT)/memfd_test: memfd_test.c common.c |
| 18 | $(OUTPUT)/fuse_test: fuse_test.c common.c | 28 | $(OUTPUT)/fuse_test: fuse_test.c common.c |