diff options
| -rw-r--r-- | arch/x86/xen/enlighten.c | 22 | ||||
| -rw-r--r-- | arch/x86/xen/p2m.c | 20 | ||||
| -rw-r--r-- | arch/x86/xen/setup.c | 42 | ||||
| -rw-r--r-- | arch/x86/xen/time.c | 18 | ||||
| -rw-r--r-- | block/blk-core.c | 21 | ||||
| -rw-r--r-- | block/blk-mq-tag.c | 14 | ||||
| -rw-r--r-- | block/blk-mq-tag.h | 1 | ||||
| -rw-r--r-- | block/blk-mq.c | 75 | ||||
| -rw-r--r-- | block/blk-mq.h | 1 | ||||
| -rw-r--r-- | block/blk-timeout.c | 3 | ||||
| -rw-r--r-- | drivers/acpi/int340x_thermal.c | 11 | ||||
| -rw-r--r-- | drivers/block/null_blk.c | 2 | ||||
| -rw-r--r-- | drivers/block/nvme-core.c | 175 | ||||
| -rw-r--r-- | drivers/block/virtio_blk.c | 2 | ||||
| -rw-r--r-- | drivers/leds/leds-netxbig.c | 12 | ||||
| -rw-r--r-- | drivers/thermal/int340x_thermal/acpi_thermal_rel.c | 16 | ||||
| -rw-r--r-- | drivers/thermal/int340x_thermal/processor_thermal_device.c | 2 | ||||
| -rw-r--r-- | include/linux/blk-mq.h | 8 | ||||
| -rw-r--r-- | include/linux/blk_types.h | 2 | ||||
| -rw-r--r-- | include/linux/compiler.h | 12 | ||||
| -rw-r--r-- | include/xen/interface/nmi.h | 51 | ||||
| -rw-r--r-- | tools/testing/selftests/exec/execveat.c | 19 | ||||
| -rw-r--r-- | tools/testing/selftests/mqueue/mq_perf_tests.c | 3 | ||||
| -rw-r--r-- | tools/testing/selftests/vm/Makefile | 2 |
24 files changed, 387 insertions, 147 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 6bf3a13e3e0f..78a881b7fc41 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | #include <xen/interface/physdev.h> | 40 | #include <xen/interface/physdev.h> |
| 41 | #include <xen/interface/vcpu.h> | 41 | #include <xen/interface/vcpu.h> |
| 42 | #include <xen/interface/memory.h> | 42 | #include <xen/interface/memory.h> |
| 43 | #include <xen/interface/nmi.h> | ||
| 43 | #include <xen/interface/xen-mca.h> | 44 | #include <xen/interface/xen-mca.h> |
| 44 | #include <xen/features.h> | 45 | #include <xen/features.h> |
| 45 | #include <xen/page.h> | 46 | #include <xen/page.h> |
| @@ -66,6 +67,7 @@ | |||
| 66 | #include <asm/reboot.h> | 67 | #include <asm/reboot.h> |
| 67 | #include <asm/stackprotector.h> | 68 | #include <asm/stackprotector.h> |
| 68 | #include <asm/hypervisor.h> | 69 | #include <asm/hypervisor.h> |
| 70 | #include <asm/mach_traps.h> | ||
| 69 | #include <asm/mwait.h> | 71 | #include <asm/mwait.h> |
| 70 | #include <asm/pci_x86.h> | 72 | #include <asm/pci_x86.h> |
| 71 | #include <asm/pat.h> | 73 | #include <asm/pat.h> |
| @@ -1351,6 +1353,21 @@ static const struct machine_ops xen_machine_ops __initconst = { | |||
| 1351 | .emergency_restart = xen_emergency_restart, | 1353 | .emergency_restart = xen_emergency_restart, |
| 1352 | }; | 1354 | }; |
| 1353 | 1355 | ||
| 1356 | static unsigned char xen_get_nmi_reason(void) | ||
| 1357 | { | ||
| 1358 | unsigned char reason = 0; | ||
| 1359 | |||
| 1360 | /* Construct a value which looks like it came from port 0x61. */ | ||
| 1361 | if (test_bit(_XEN_NMIREASON_io_error, | ||
| 1362 | &HYPERVISOR_shared_info->arch.nmi_reason)) | ||
| 1363 | reason |= NMI_REASON_IOCHK; | ||
| 1364 | if (test_bit(_XEN_NMIREASON_pci_serr, | ||
| 1365 | &HYPERVISOR_shared_info->arch.nmi_reason)) | ||
| 1366 | reason |= NMI_REASON_SERR; | ||
| 1367 | |||
| 1368 | return reason; | ||
| 1369 | } | ||
| 1370 | |||
| 1354 | static void __init xen_boot_params_init_edd(void) | 1371 | static void __init xen_boot_params_init_edd(void) |
| 1355 | { | 1372 | { |
| 1356 | #if IS_ENABLED(CONFIG_EDD) | 1373 | #if IS_ENABLED(CONFIG_EDD) |
| @@ -1535,9 +1552,12 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
| 1535 | pv_info = xen_info; | 1552 | pv_info = xen_info; |
| 1536 | pv_init_ops = xen_init_ops; | 1553 | pv_init_ops = xen_init_ops; |
| 1537 | pv_apic_ops = xen_apic_ops; | 1554 | pv_apic_ops = xen_apic_ops; |
| 1538 | if (!xen_pvh_domain()) | 1555 | if (!xen_pvh_domain()) { |
| 1539 | pv_cpu_ops = xen_cpu_ops; | 1556 | pv_cpu_ops = xen_cpu_ops; |
| 1540 | 1557 | ||
| 1558 | x86_platform.get_nmi_reason = xen_get_nmi_reason; | ||
| 1559 | } | ||
| 1560 | |||
| 1541 | if (xen_feature(XENFEAT_auto_translated_physmap)) | 1561 | if (xen_feature(XENFEAT_auto_translated_physmap)) |
| 1542 | x86_init.resources.memory_setup = xen_auto_xlated_memory_setup; | 1562 | x86_init.resources.memory_setup = xen_auto_xlated_memory_setup; |
| 1543 | else | 1563 | else |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index edbc7a63fd73..70fb5075c901 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
| @@ -167,10 +167,13 @@ static void * __ref alloc_p2m_page(void) | |||
| 167 | return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT); | 167 | return (void *)__get_free_page(GFP_KERNEL | __GFP_REPEAT); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | /* Only to be called in case of a race for a page just allocated! */ | 170 | static void __ref free_p2m_page(void *p) |
| 171 | static void free_p2m_page(void *p) | ||
| 172 | { | 171 | { |
| 173 | BUG_ON(!slab_is_available()); | 172 | if (unlikely(!slab_is_available())) { |
| 173 | free_bootmem((unsigned long)p, PAGE_SIZE); | ||
| 174 | return; | ||
| 175 | } | ||
| 176 | |||
| 174 | free_page((unsigned long)p); | 177 | free_page((unsigned long)p); |
| 175 | } | 178 | } |
| 176 | 179 | ||
| @@ -375,7 +378,7 @@ static void __init xen_rebuild_p2m_list(unsigned long *p2m) | |||
| 375 | p2m_missing_pte : p2m_identity_pte; | 378 | p2m_missing_pte : p2m_identity_pte; |
| 376 | for (i = 0; i < PMDS_PER_MID_PAGE; i++) { | 379 | for (i = 0; i < PMDS_PER_MID_PAGE; i++) { |
| 377 | pmdp = populate_extra_pmd( | 380 | pmdp = populate_extra_pmd( |
| 378 | (unsigned long)(p2m + pfn + i * PTRS_PER_PTE)); | 381 | (unsigned long)(p2m + pfn) + i * PMD_SIZE); |
| 379 | set_pmd(pmdp, __pmd(__pa(ptep) | _KERNPG_TABLE)); | 382 | set_pmd(pmdp, __pmd(__pa(ptep) | _KERNPG_TABLE)); |
| 380 | } | 383 | } |
| 381 | } | 384 | } |
| @@ -436,10 +439,9 @@ EXPORT_SYMBOL_GPL(get_phys_to_machine); | |||
| 436 | * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual | 439 | * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual |
| 437 | * pmd. In case of PAE/x86-32 there are multiple pmds to allocate! | 440 | * pmd. In case of PAE/x86-32 there are multiple pmds to allocate! |
| 438 | */ | 441 | */ |
| 439 | static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg) | 442 | static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg) |
| 440 | { | 443 | { |
| 441 | pte_t *ptechk; | 444 | pte_t *ptechk; |
| 442 | pte_t *pteret = ptep; | ||
| 443 | pte_t *pte_newpg[PMDS_PER_MID_PAGE]; | 445 | pte_t *pte_newpg[PMDS_PER_MID_PAGE]; |
| 444 | pmd_t *pmdp; | 446 | pmd_t *pmdp; |
| 445 | unsigned int level; | 447 | unsigned int level; |
| @@ -473,8 +475,6 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg) | |||
| 473 | if (ptechk == pte_pg) { | 475 | if (ptechk == pte_pg) { |
| 474 | set_pmd(pmdp, | 476 | set_pmd(pmdp, |
| 475 | __pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE)); | 477 | __pmd(__pa(pte_newpg[i]) | _KERNPG_TABLE)); |
| 476 | if (vaddr == (addr & ~(PMD_SIZE - 1))) | ||
| 477 | pteret = pte_offset_kernel(pmdp, addr); | ||
| 478 | pte_newpg[i] = NULL; | 478 | pte_newpg[i] = NULL; |
| 479 | } | 479 | } |
| 480 | 480 | ||
| @@ -488,7 +488,7 @@ static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *ptep, pte_t *pte_pg) | |||
| 488 | vaddr += PMD_SIZE; | 488 | vaddr += PMD_SIZE; |
| 489 | } | 489 | } |
| 490 | 490 | ||
| 491 | return pteret; | 491 | return lookup_address(addr, &level); |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | /* | 494 | /* |
| @@ -517,7 +517,7 @@ static bool alloc_p2m(unsigned long pfn) | |||
| 517 | 517 | ||
| 518 | if (pte_pg == p2m_missing_pte || pte_pg == p2m_identity_pte) { | 518 | if (pte_pg == p2m_missing_pte || pte_pg == p2m_identity_pte) { |
| 519 | /* PMD level is missing, allocate a new one */ | 519 | /* PMD level is missing, allocate a new one */ |
| 520 | ptep = alloc_p2m_pmd(addr, ptep, pte_pg); | 520 | ptep = alloc_p2m_pmd(addr, pte_pg); |
| 521 | if (!ptep) | 521 | if (!ptep) |
| 522 | return false; | 522 | return false; |
| 523 | } | 523 | } |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index dfd77dec8e2b..865e56cea7a0 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
| @@ -140,7 +140,7 @@ static void __init xen_del_extra_mem(u64 start, u64 size) | |||
| 140 | unsigned long __ref xen_chk_extra_mem(unsigned long pfn) | 140 | unsigned long __ref xen_chk_extra_mem(unsigned long pfn) |
| 141 | { | 141 | { |
| 142 | int i; | 142 | int i; |
| 143 | unsigned long addr = PFN_PHYS(pfn); | 143 | phys_addr_t addr = PFN_PHYS(pfn); |
| 144 | 144 | ||
| 145 | for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { | 145 | for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { |
| 146 | if (addr >= xen_extra_mem[i].start && | 146 | if (addr >= xen_extra_mem[i].start && |
| @@ -160,6 +160,8 @@ void __init xen_inv_extra_mem(void) | |||
| 160 | int i; | 160 | int i; |
| 161 | 161 | ||
| 162 | for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { | 162 | for (i = 0; i < XEN_EXTRA_MEM_MAX_REGIONS; i++) { |
| 163 | if (!xen_extra_mem[i].size) | ||
| 164 | continue; | ||
| 163 | pfn_s = PFN_DOWN(xen_extra_mem[i].start); | 165 | pfn_s = PFN_DOWN(xen_extra_mem[i].start); |
| 164 | pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size); | 166 | pfn_e = PFN_UP(xen_extra_mem[i].start + xen_extra_mem[i].size); |
| 165 | for (pfn = pfn_s; pfn < pfn_e; pfn++) | 167 | for (pfn = pfn_s; pfn < pfn_e; pfn++) |
| @@ -229,15 +231,14 @@ static int __init xen_free_mfn(unsigned long mfn) | |||
| 229 | * as a fallback if the remapping fails. | 231 | * as a fallback if the remapping fails. |
| 230 | */ | 232 | */ |
| 231 | static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn, | 233 | static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn, |
| 232 | unsigned long end_pfn, unsigned long nr_pages, unsigned long *identity, | 234 | unsigned long end_pfn, unsigned long nr_pages, unsigned long *released) |
| 233 | unsigned long *released) | ||
| 234 | { | 235 | { |
| 235 | unsigned long len = 0; | ||
| 236 | unsigned long pfn, end; | 236 | unsigned long pfn, end; |
| 237 | int ret; | 237 | int ret; |
| 238 | 238 | ||
| 239 | WARN_ON(start_pfn > end_pfn); | 239 | WARN_ON(start_pfn > end_pfn); |
| 240 | 240 | ||
| 241 | /* Release pages first. */ | ||
| 241 | end = min(end_pfn, nr_pages); | 242 | end = min(end_pfn, nr_pages); |
| 242 | for (pfn = start_pfn; pfn < end; pfn++) { | 243 | for (pfn = start_pfn; pfn < end; pfn++) { |
| 243 | unsigned long mfn = pfn_to_mfn(pfn); | 244 | unsigned long mfn = pfn_to_mfn(pfn); |
| @@ -250,16 +251,14 @@ static void __init xen_set_identity_and_release_chunk(unsigned long start_pfn, | |||
| 250 | WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); | 251 | WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); |
| 251 | 252 | ||
| 252 | if (ret == 1) { | 253 | if (ret == 1) { |
| 254 | (*released)++; | ||
| 253 | if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY)) | 255 | if (!__set_phys_to_machine(pfn, INVALID_P2M_ENTRY)) |
| 254 | break; | 256 | break; |
| 255 | len++; | ||
| 256 | } else | 257 | } else |
| 257 | break; | 258 | break; |
| 258 | } | 259 | } |
| 259 | 260 | ||
| 260 | /* Need to release pages first */ | 261 | set_phys_range_identity(start_pfn, end_pfn); |
| 261 | *released += len; | ||
| 262 | *identity += set_phys_range_identity(start_pfn, end_pfn); | ||
| 263 | } | 262 | } |
| 264 | 263 | ||
| 265 | /* | 264 | /* |
| @@ -287,7 +286,7 @@ static void __init xen_update_mem_tables(unsigned long pfn, unsigned long mfn) | |||
| 287 | } | 286 | } |
| 288 | 287 | ||
| 289 | /* Update kernel mapping, but not for highmem. */ | 288 | /* Update kernel mapping, but not for highmem. */ |
| 290 | if ((pfn << PAGE_SHIFT) >= __pa(high_memory)) | 289 | if (pfn >= PFN_UP(__pa(high_memory - 1))) |
| 291 | return; | 290 | return; |
| 292 | 291 | ||
| 293 | if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT), | 292 | if (HYPERVISOR_update_va_mapping((unsigned long)__va(pfn << PAGE_SHIFT), |
| @@ -318,7 +317,6 @@ static void __init xen_do_set_identity_and_remap_chunk( | |||
| 318 | unsigned long ident_pfn_iter, remap_pfn_iter; | 317 | unsigned long ident_pfn_iter, remap_pfn_iter; |
| 319 | unsigned long ident_end_pfn = start_pfn + size; | 318 | unsigned long ident_end_pfn = start_pfn + size; |
| 320 | unsigned long left = size; | 319 | unsigned long left = size; |
| 321 | unsigned long ident_cnt = 0; | ||
| 322 | unsigned int i, chunk; | 320 | unsigned int i, chunk; |
| 323 | 321 | ||
| 324 | WARN_ON(size == 0); | 322 | WARN_ON(size == 0); |
| @@ -347,8 +345,7 @@ static void __init xen_do_set_identity_and_remap_chunk( | |||
| 347 | xen_remap_mfn = mfn; | 345 | xen_remap_mfn = mfn; |
| 348 | 346 | ||
| 349 | /* Set identity map */ | 347 | /* Set identity map */ |
| 350 | ident_cnt += set_phys_range_identity(ident_pfn_iter, | 348 | set_phys_range_identity(ident_pfn_iter, ident_pfn_iter + chunk); |
| 351 | ident_pfn_iter + chunk); | ||
| 352 | 349 | ||
| 353 | left -= chunk; | 350 | left -= chunk; |
| 354 | } | 351 | } |
| @@ -371,7 +368,7 @@ static void __init xen_do_set_identity_and_remap_chunk( | |||
| 371 | static unsigned long __init xen_set_identity_and_remap_chunk( | 368 | static unsigned long __init xen_set_identity_and_remap_chunk( |
| 372 | const struct e820entry *list, size_t map_size, unsigned long start_pfn, | 369 | const struct e820entry *list, size_t map_size, unsigned long start_pfn, |
| 373 | unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn, | 370 | unsigned long end_pfn, unsigned long nr_pages, unsigned long remap_pfn, |
| 374 | unsigned long *identity, unsigned long *released) | 371 | unsigned long *released, unsigned long *remapped) |
| 375 | { | 372 | { |
| 376 | unsigned long pfn; | 373 | unsigned long pfn; |
| 377 | unsigned long i = 0; | 374 | unsigned long i = 0; |
| @@ -386,8 +383,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk( | |||
| 386 | /* Do not remap pages beyond the current allocation */ | 383 | /* Do not remap pages beyond the current allocation */ |
| 387 | if (cur_pfn >= nr_pages) { | 384 | if (cur_pfn >= nr_pages) { |
| 388 | /* Identity map remaining pages */ | 385 | /* Identity map remaining pages */ |
| 389 | *identity += set_phys_range_identity(cur_pfn, | 386 | set_phys_range_identity(cur_pfn, cur_pfn + size); |
| 390 | cur_pfn + size); | ||
| 391 | break; | 387 | break; |
| 392 | } | 388 | } |
| 393 | if (cur_pfn + size > nr_pages) | 389 | if (cur_pfn + size > nr_pages) |
| @@ -398,7 +394,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk( | |||
| 398 | if (!remap_range_size) { | 394 | if (!remap_range_size) { |
| 399 | pr_warning("Unable to find available pfn range, not remapping identity pages\n"); | 395 | pr_warning("Unable to find available pfn range, not remapping identity pages\n"); |
| 400 | xen_set_identity_and_release_chunk(cur_pfn, | 396 | xen_set_identity_and_release_chunk(cur_pfn, |
| 401 | cur_pfn + left, nr_pages, identity, released); | 397 | cur_pfn + left, nr_pages, released); |
| 402 | break; | 398 | break; |
| 403 | } | 399 | } |
| 404 | /* Adjust size to fit in current e820 RAM region */ | 400 | /* Adjust size to fit in current e820 RAM region */ |
| @@ -410,7 +406,7 @@ static unsigned long __init xen_set_identity_and_remap_chunk( | |||
| 410 | /* Update variables to reflect new mappings. */ | 406 | /* Update variables to reflect new mappings. */ |
| 411 | i += size; | 407 | i += size; |
| 412 | remap_pfn += size; | 408 | remap_pfn += size; |
| 413 | *identity += size; | 409 | *remapped += size; |
| 414 | } | 410 | } |
| 415 | 411 | ||
| 416 | /* | 412 | /* |
| @@ -427,13 +423,13 @@ static unsigned long __init xen_set_identity_and_remap_chunk( | |||
| 427 | 423 | ||
| 428 | static void __init xen_set_identity_and_remap( | 424 | static void __init xen_set_identity_and_remap( |
| 429 | const struct e820entry *list, size_t map_size, unsigned long nr_pages, | 425 | const struct e820entry *list, size_t map_size, unsigned long nr_pages, |
| 430 | unsigned long *released) | 426 | unsigned long *released, unsigned long *remapped) |
| 431 | { | 427 | { |
| 432 | phys_addr_t start = 0; | 428 | phys_addr_t start = 0; |
| 433 | unsigned long identity = 0; | ||
| 434 | unsigned long last_pfn = nr_pages; | 429 | unsigned long last_pfn = nr_pages; |
| 435 | const struct e820entry *entry; | 430 | const struct e820entry *entry; |
| 436 | unsigned long num_released = 0; | 431 | unsigned long num_released = 0; |
| 432 | unsigned long num_remapped = 0; | ||
| 437 | int i; | 433 | int i; |
| 438 | 434 | ||
| 439 | /* | 435 | /* |
| @@ -460,14 +456,14 @@ static void __init xen_set_identity_and_remap( | |||
| 460 | last_pfn = xen_set_identity_and_remap_chunk( | 456 | last_pfn = xen_set_identity_and_remap_chunk( |
| 461 | list, map_size, start_pfn, | 457 | list, map_size, start_pfn, |
| 462 | end_pfn, nr_pages, last_pfn, | 458 | end_pfn, nr_pages, last_pfn, |
| 463 | &identity, &num_released); | 459 | &num_released, &num_remapped); |
| 464 | start = end; | 460 | start = end; |
| 465 | } | 461 | } |
| 466 | } | 462 | } |
| 467 | 463 | ||
| 468 | *released = num_released; | 464 | *released = num_released; |
| 465 | *remapped = num_remapped; | ||
| 469 | 466 | ||
| 470 | pr_info("Set %ld page(s) to 1-1 mapping\n", identity); | ||
| 471 | pr_info("Released %ld page(s)\n", num_released); | 467 | pr_info("Released %ld page(s)\n", num_released); |
| 472 | } | 468 | } |
| 473 | 469 | ||
| @@ -586,6 +582,7 @@ char * __init xen_memory_setup(void) | |||
| 586 | struct xen_memory_map memmap; | 582 | struct xen_memory_map memmap; |
| 587 | unsigned long max_pages; | 583 | unsigned long max_pages; |
| 588 | unsigned long extra_pages = 0; | 584 | unsigned long extra_pages = 0; |
| 585 | unsigned long remapped_pages; | ||
| 589 | int i; | 586 | int i; |
| 590 | int op; | 587 | int op; |
| 591 | 588 | ||
| @@ -635,9 +632,10 @@ char * __init xen_memory_setup(void) | |||
| 635 | * underlying RAM. | 632 | * underlying RAM. |
| 636 | */ | 633 | */ |
| 637 | xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn, | 634 | xen_set_identity_and_remap(map, memmap.nr_entries, max_pfn, |
| 638 | &xen_released_pages); | 635 | &xen_released_pages, &remapped_pages); |
| 639 | 636 | ||
| 640 | extra_pages += xen_released_pages; | 637 | extra_pages += xen_released_pages; |
| 638 | extra_pages += remapped_pages; | ||
| 641 | 639 | ||
| 642 | /* | 640 | /* |
| 643 | * Clamp the amount of extra memory to a EXTRA_MEM_RATIO | 641 | * Clamp the amount of extra memory to a EXTRA_MEM_RATIO |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index f473d268d387..69087341d9ae 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
| @@ -391,7 +391,7 @@ static const struct clock_event_device *xen_clockevent = | |||
| 391 | 391 | ||
| 392 | struct xen_clock_event_device { | 392 | struct xen_clock_event_device { |
| 393 | struct clock_event_device evt; | 393 | struct clock_event_device evt; |
| 394 | char *name; | 394 | char name[16]; |
| 395 | }; | 395 | }; |
| 396 | static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 }; | 396 | static DEFINE_PER_CPU(struct xen_clock_event_device, xen_clock_events) = { .evt.irq = -1 }; |
| 397 | 397 | ||
| @@ -420,46 +420,38 @@ void xen_teardown_timer(int cpu) | |||
| 420 | if (evt->irq >= 0) { | 420 | if (evt->irq >= 0) { |
| 421 | unbind_from_irqhandler(evt->irq, NULL); | 421 | unbind_from_irqhandler(evt->irq, NULL); |
| 422 | evt->irq = -1; | 422 | evt->irq = -1; |
| 423 | kfree(per_cpu(xen_clock_events, cpu).name); | ||
| 424 | per_cpu(xen_clock_events, cpu).name = NULL; | ||
| 425 | } | 423 | } |
| 426 | } | 424 | } |
| 427 | 425 | ||
| 428 | void xen_setup_timer(int cpu) | 426 | void xen_setup_timer(int cpu) |
| 429 | { | 427 | { |
| 430 | char *name; | 428 | struct xen_clock_event_device *xevt = &per_cpu(xen_clock_events, cpu); |
| 431 | struct clock_event_device *evt; | 429 | struct clock_event_device *evt = &xevt->evt; |
| 432 | int irq; | 430 | int irq; |
| 433 | 431 | ||
| 434 | evt = &per_cpu(xen_clock_events, cpu).evt; | ||
| 435 | WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu); | 432 | WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu); |
| 436 | if (evt->irq >= 0) | 433 | if (evt->irq >= 0) |
| 437 | xen_teardown_timer(cpu); | 434 | xen_teardown_timer(cpu); |
| 438 | 435 | ||
| 439 | printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); | 436 | printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu); |
| 440 | 437 | ||
| 441 | name = kasprintf(GFP_KERNEL, "timer%d", cpu); | 438 | snprintf(xevt->name, sizeof(xevt->name), "timer%d", cpu); |
| 442 | if (!name) | ||
| 443 | name = "<timer kasprintf failed>"; | ||
| 444 | 439 | ||
| 445 | irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt, | 440 | irq = bind_virq_to_irqhandler(VIRQ_TIMER, cpu, xen_timer_interrupt, |
| 446 | IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER| | 441 | IRQF_PERCPU|IRQF_NOBALANCING|IRQF_TIMER| |
| 447 | IRQF_FORCE_RESUME|IRQF_EARLY_RESUME, | 442 | IRQF_FORCE_RESUME|IRQF_EARLY_RESUME, |
| 448 | name, NULL); | 443 | xevt->name, NULL); |
| 449 | (void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX); | 444 | (void)xen_set_irq_priority(irq, XEN_IRQ_PRIORITY_MAX); |
| 450 | 445 | ||
| 451 | memcpy(evt, xen_clockevent, sizeof(*evt)); | 446 | memcpy(evt, xen_clockevent, sizeof(*evt)); |
| 452 | 447 | ||
| 453 | evt->cpumask = cpumask_of(cpu); | 448 | evt->cpumask = cpumask_of(cpu); |
| 454 | evt->irq = irq; | 449 | evt->irq = irq; |
| 455 | per_cpu(xen_clock_events, cpu).name = name; | ||
| 456 | } | 450 | } |
| 457 | 451 | ||
| 458 | 452 | ||
| 459 | void xen_setup_cpu_clockevents(void) | 453 | void xen_setup_cpu_clockevents(void) |
| 460 | { | 454 | { |
| 461 | BUG_ON(preemptible()); | ||
| 462 | |||
| 463 | clockevents_register_device(this_cpu_ptr(&xen_clock_events.evt)); | 455 | clockevents_register_device(this_cpu_ptr(&xen_clock_events.evt)); |
| 464 | } | 456 | } |
| 465 | 457 | ||
diff --git a/block/blk-core.c b/block/blk-core.c index 30f6153a40c2..3ad405571dcc 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -473,6 +473,25 @@ void blk_queue_bypass_end(struct request_queue *q) | |||
| 473 | } | 473 | } |
| 474 | EXPORT_SYMBOL_GPL(blk_queue_bypass_end); | 474 | EXPORT_SYMBOL_GPL(blk_queue_bypass_end); |
| 475 | 475 | ||
| 476 | void blk_set_queue_dying(struct request_queue *q) | ||
| 477 | { | ||
| 478 | queue_flag_set_unlocked(QUEUE_FLAG_DYING, q); | ||
| 479 | |||
| 480 | if (q->mq_ops) | ||
| 481 | blk_mq_wake_waiters(q); | ||
| 482 | else { | ||
| 483 | struct request_list *rl; | ||
| 484 | |||
| 485 | blk_queue_for_each_rl(rl, q) { | ||
| 486 | if (rl->rq_pool) { | ||
| 487 | wake_up(&rl->wait[BLK_RW_SYNC]); | ||
| 488 | wake_up(&rl->wait[BLK_RW_ASYNC]); | ||
| 489 | } | ||
| 490 | } | ||
| 491 | } | ||
| 492 | } | ||
| 493 | EXPORT_SYMBOL_GPL(blk_set_queue_dying); | ||
| 494 | |||
| 476 | /** | 495 | /** |
| 477 | * blk_cleanup_queue - shutdown a request queue | 496 | * blk_cleanup_queue - shutdown a request queue |
| 478 | * @q: request queue to shutdown | 497 | * @q: request queue to shutdown |
| @@ -486,7 +505,7 @@ void blk_cleanup_queue(struct request_queue *q) | |||
| 486 | 505 | ||
| 487 | /* mark @q DYING, no new request or merges will be allowed afterwards */ | 506 | /* mark @q DYING, no new request or merges will be allowed afterwards */ |
| 488 | mutex_lock(&q->sysfs_lock); | 507 | mutex_lock(&q->sysfs_lock); |
| 489 | queue_flag_set_unlocked(QUEUE_FLAG_DYING, q); | 508 | blk_set_queue_dying(q); |
| 490 | spin_lock_irq(lock); | 509 | spin_lock_irq(lock); |
| 491 | 510 | ||
| 492 | /* | 511 | /* |
diff --git a/block/blk-mq-tag.c b/block/blk-mq-tag.c index 32e8dbb9ad1c..60c9d4a93fe4 100644 --- a/block/blk-mq-tag.c +++ b/block/blk-mq-tag.c | |||
| @@ -68,9 +68,9 @@ bool __blk_mq_tag_busy(struct blk_mq_hw_ctx *hctx) | |||
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | /* | 70 | /* |
| 71 | * Wakeup all potentially sleeping on normal (non-reserved) tags | 71 | * Wakeup all potentially sleeping on tags |
| 72 | */ | 72 | */ |
| 73 | static void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags) | 73 | void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags, bool include_reserve) |
| 74 | { | 74 | { |
| 75 | struct blk_mq_bitmap_tags *bt; | 75 | struct blk_mq_bitmap_tags *bt; |
| 76 | int i, wake_index; | 76 | int i, wake_index; |
| @@ -85,6 +85,12 @@ static void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags) | |||
| 85 | 85 | ||
| 86 | wake_index = bt_index_inc(wake_index); | 86 | wake_index = bt_index_inc(wake_index); |
| 87 | } | 87 | } |
| 88 | |||
| 89 | if (include_reserve) { | ||
| 90 | bt = &tags->breserved_tags; | ||
| 91 | if (waitqueue_active(&bt->bs[0].wait)) | ||
| 92 | wake_up(&bt->bs[0].wait); | ||
| 93 | } | ||
| 88 | } | 94 | } |
| 89 | 95 | ||
| 90 | /* | 96 | /* |
| @@ -100,7 +106,7 @@ void __blk_mq_tag_idle(struct blk_mq_hw_ctx *hctx) | |||
| 100 | 106 | ||
| 101 | atomic_dec(&tags->active_queues); | 107 | atomic_dec(&tags->active_queues); |
| 102 | 108 | ||
| 103 | blk_mq_tag_wakeup_all(tags); | 109 | blk_mq_tag_wakeup_all(tags, false); |
| 104 | } | 110 | } |
| 105 | 111 | ||
| 106 | /* | 112 | /* |
| @@ -584,7 +590,7 @@ int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int tdepth) | |||
| 584 | * static and should never need resizing. | 590 | * static and should never need resizing. |
| 585 | */ | 591 | */ |
| 586 | bt_update_count(&tags->bitmap_tags, tdepth); | 592 | bt_update_count(&tags->bitmap_tags, tdepth); |
| 587 | blk_mq_tag_wakeup_all(tags); | 593 | blk_mq_tag_wakeup_all(tags, false); |
| 588 | return 0; | 594 | return 0; |
| 589 | } | 595 | } |
| 590 | 596 | ||
diff --git a/block/blk-mq-tag.h b/block/blk-mq-tag.h index 6206ed17ef76..a6fa0fc9d41a 100644 --- a/block/blk-mq-tag.h +++ b/block/blk-mq-tag.h | |||
| @@ -54,6 +54,7 @@ extern bool blk_mq_has_free_tags(struct blk_mq_tags *tags); | |||
| 54 | extern ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page); | 54 | extern ssize_t blk_mq_tag_sysfs_show(struct blk_mq_tags *tags, char *page); |
| 55 | extern void blk_mq_tag_init_last_tag(struct blk_mq_tags *tags, unsigned int *last_tag); | 55 | extern void blk_mq_tag_init_last_tag(struct blk_mq_tags *tags, unsigned int *last_tag); |
| 56 | extern int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int depth); | 56 | extern int blk_mq_tag_update_depth(struct blk_mq_tags *tags, unsigned int depth); |
| 57 | extern void blk_mq_tag_wakeup_all(struct blk_mq_tags *tags, bool); | ||
| 57 | 58 | ||
| 58 | enum { | 59 | enum { |
| 59 | BLK_MQ_TAG_CACHE_MIN = 1, | 60 | BLK_MQ_TAG_CACHE_MIN = 1, |
diff --git a/block/blk-mq.c b/block/blk-mq.c index da1ab5641227..2f95747c287e 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c | |||
| @@ -107,7 +107,7 @@ static void blk_mq_usage_counter_release(struct percpu_ref *ref) | |||
| 107 | wake_up_all(&q->mq_freeze_wq); | 107 | wake_up_all(&q->mq_freeze_wq); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | static void blk_mq_freeze_queue_start(struct request_queue *q) | 110 | void blk_mq_freeze_queue_start(struct request_queue *q) |
| 111 | { | 111 | { |
| 112 | bool freeze; | 112 | bool freeze; |
| 113 | 113 | ||
| @@ -120,6 +120,7 @@ static void blk_mq_freeze_queue_start(struct request_queue *q) | |||
| 120 | blk_mq_run_queues(q, false); | 120 | blk_mq_run_queues(q, false); |
| 121 | } | 121 | } |
| 122 | } | 122 | } |
| 123 | EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_start); | ||
| 123 | 124 | ||
| 124 | static void blk_mq_freeze_queue_wait(struct request_queue *q) | 125 | static void blk_mq_freeze_queue_wait(struct request_queue *q) |
| 125 | { | 126 | { |
| @@ -136,7 +137,7 @@ void blk_mq_freeze_queue(struct request_queue *q) | |||
| 136 | blk_mq_freeze_queue_wait(q); | 137 | blk_mq_freeze_queue_wait(q); |
| 137 | } | 138 | } |
| 138 | 139 | ||
| 139 | static void blk_mq_unfreeze_queue(struct request_queue *q) | 140 | void blk_mq_unfreeze_queue(struct request_queue *q) |
| 140 | { | 141 | { |
| 141 | bool wake; | 142 | bool wake; |
| 142 | 143 | ||
| @@ -149,6 +150,24 @@ static void blk_mq_unfreeze_queue(struct request_queue *q) | |||
| 149 | wake_up_all(&q->mq_freeze_wq); | 150 | wake_up_all(&q->mq_freeze_wq); |
| 150 | } | 151 | } |
| 151 | } | 152 | } |
| 153 | EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue); | ||
| 154 | |||
| 155 | void blk_mq_wake_waiters(struct request_queue *q) | ||
| 156 | { | ||
| 157 | struct blk_mq_hw_ctx *hctx; | ||
| 158 | unsigned int i; | ||
| 159 | |||
| 160 | queue_for_each_hw_ctx(q, hctx, i) | ||
| 161 | if (blk_mq_hw_queue_mapped(hctx)) | ||
| 162 | blk_mq_tag_wakeup_all(hctx->tags, true); | ||
| 163 | |||
| 164 | /* | ||
| 165 | * If we are called because the queue has now been marked as | ||
| 166 | * dying, we need to ensure that processes currently waiting on | ||
| 167 | * the queue are notified as well. | ||
| 168 | */ | ||
| 169 | wake_up_all(&q->mq_freeze_wq); | ||
| 170 | } | ||
| 152 | 171 | ||
| 153 | bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx) | 172 | bool blk_mq_can_queue(struct blk_mq_hw_ctx *hctx) |
| 154 | { | 173 | { |
| @@ -258,8 +277,10 @@ struct request *blk_mq_alloc_request(struct request_queue *q, int rw, gfp_t gfp, | |||
| 258 | ctx = alloc_data.ctx; | 277 | ctx = alloc_data.ctx; |
| 259 | } | 278 | } |
| 260 | blk_mq_put_ctx(ctx); | 279 | blk_mq_put_ctx(ctx); |
| 261 | if (!rq) | 280 | if (!rq) { |
| 281 | blk_mq_queue_exit(q); | ||
| 262 | return ERR_PTR(-EWOULDBLOCK); | 282 | return ERR_PTR(-EWOULDBLOCK); |
| 283 | } | ||
| 263 | return rq; | 284 | return rq; |
| 264 | } | 285 | } |
| 265 | EXPORT_SYMBOL(blk_mq_alloc_request); | 286 | EXPORT_SYMBOL(blk_mq_alloc_request); |
| @@ -383,6 +404,12 @@ void blk_mq_complete_request(struct request *rq) | |||
| 383 | } | 404 | } |
| 384 | EXPORT_SYMBOL(blk_mq_complete_request); | 405 | EXPORT_SYMBOL(blk_mq_complete_request); |
| 385 | 406 | ||
| 407 | int blk_mq_request_started(struct request *rq) | ||
| 408 | { | ||
| 409 | return test_bit(REQ_ATOM_STARTED, &rq->atomic_flags); | ||
| 410 | } | ||
| 411 | EXPORT_SYMBOL_GPL(blk_mq_request_started); | ||
| 412 | |||
| 386 | void blk_mq_start_request(struct request *rq) | 413 | void blk_mq_start_request(struct request *rq) |
| 387 | { | 414 | { |
| 388 | struct request_queue *q = rq->q; | 415 | struct request_queue *q = rq->q; |
| @@ -500,12 +527,38 @@ void blk_mq_add_to_requeue_list(struct request *rq, bool at_head) | |||
| 500 | } | 527 | } |
| 501 | EXPORT_SYMBOL(blk_mq_add_to_requeue_list); | 528 | EXPORT_SYMBOL(blk_mq_add_to_requeue_list); |
| 502 | 529 | ||
| 530 | void blk_mq_cancel_requeue_work(struct request_queue *q) | ||
| 531 | { | ||
| 532 | cancel_work_sync(&q->requeue_work); | ||
| 533 | } | ||
| 534 | EXPORT_SYMBOL_GPL(blk_mq_cancel_requeue_work); | ||
| 535 | |||
| 503 | void blk_mq_kick_requeue_list(struct request_queue *q) | 536 | void blk_mq_kick_requeue_list(struct request_queue *q) |
| 504 | { | 537 | { |
| 505 | kblockd_schedule_work(&q->requeue_work); | 538 | kblockd_schedule_work(&q->requeue_work); |
| 506 | } | 539 | } |
| 507 | EXPORT_SYMBOL(blk_mq_kick_requeue_list); | 540 | EXPORT_SYMBOL(blk_mq_kick_requeue_list); |
| 508 | 541 | ||
| 542 | void blk_mq_abort_requeue_list(struct request_queue *q) | ||
| 543 | { | ||
| 544 | unsigned long flags; | ||
| 545 | LIST_HEAD(rq_list); | ||
| 546 | |||
| 547 | spin_lock_irqsave(&q->requeue_lock, flags); | ||
| 548 | list_splice_init(&q->requeue_list, &rq_list); | ||
| 549 | spin_unlock_irqrestore(&q->requeue_lock, flags); | ||
| 550 | |||
| 551 | while (!list_empty(&rq_list)) { | ||
| 552 | struct request *rq; | ||
| 553 | |||
| 554 | rq = list_first_entry(&rq_list, struct request, queuelist); | ||
| 555 | list_del_init(&rq->queuelist); | ||
| 556 | rq->errors = -EIO; | ||
| 557 | blk_mq_end_request(rq, rq->errors); | ||
| 558 | } | ||
| 559 | } | ||
| 560 | EXPORT_SYMBOL(blk_mq_abort_requeue_list); | ||
| 561 | |||
| 509 | static inline bool is_flush_request(struct request *rq, | 562 | static inline bool is_flush_request(struct request *rq, |
| 510 | struct blk_flush_queue *fq, unsigned int tag) | 563 | struct blk_flush_queue *fq, unsigned int tag) |
| 511 | { | 564 | { |
| @@ -566,13 +619,24 @@ void blk_mq_rq_timed_out(struct request *req, bool reserved) | |||
| 566 | break; | 619 | break; |
| 567 | } | 620 | } |
| 568 | } | 621 | } |
| 569 | 622 | ||
| 570 | static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, | 623 | static void blk_mq_check_expired(struct blk_mq_hw_ctx *hctx, |
| 571 | struct request *rq, void *priv, bool reserved) | 624 | struct request *rq, void *priv, bool reserved) |
| 572 | { | 625 | { |
| 573 | struct blk_mq_timeout_data *data = priv; | 626 | struct blk_mq_timeout_data *data = priv; |
| 574 | 627 | ||
| 575 | if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) | 628 | if (!test_bit(REQ_ATOM_STARTED, &rq->atomic_flags)) { |
| 629 | /* | ||
| 630 | * If a request wasn't started before the queue was | ||
| 631 | * marked dying, kill it here or it'll go unnoticed. | ||
| 632 | */ | ||
| 633 | if (unlikely(blk_queue_dying(rq->q))) { | ||
| 634 | rq->errors = -EIO; | ||
| 635 | blk_mq_complete_request(rq); | ||
| 636 | } | ||
| 637 | return; | ||
| 638 | } | ||
| 639 | if (rq->cmd_flags & REQ_NO_TIMEOUT) | ||
| 576 | return; | 640 | return; |
| 577 | 641 | ||
| 578 | if (time_after_eq(jiffies, rq->deadline)) { | 642 | if (time_after_eq(jiffies, rq->deadline)) { |
| @@ -1601,7 +1665,6 @@ static int blk_mq_init_hctx(struct request_queue *q, | |||
| 1601 | hctx->queue = q; | 1665 | hctx->queue = q; |
| 1602 | hctx->queue_num = hctx_idx; | 1666 | hctx->queue_num = hctx_idx; |
| 1603 | hctx->flags = set->flags; | 1667 | hctx->flags = set->flags; |
| 1604 | hctx->cmd_size = set->cmd_size; | ||
| 1605 | 1668 | ||
| 1606 | blk_mq_init_cpu_notifier(&hctx->cpu_notifier, | 1669 | blk_mq_init_cpu_notifier(&hctx->cpu_notifier, |
| 1607 | blk_mq_hctx_notify, hctx); | 1670 | blk_mq_hctx_notify, hctx); |
diff --git a/block/blk-mq.h b/block/blk-mq.h index 206230e64f79..4f4f943c22c3 100644 --- a/block/blk-mq.h +++ b/block/blk-mq.h | |||
| @@ -32,6 +32,7 @@ void blk_mq_free_queue(struct request_queue *q); | |||
| 32 | void blk_mq_clone_flush_request(struct request *flush_rq, | 32 | void blk_mq_clone_flush_request(struct request *flush_rq, |
| 33 | struct request *orig_rq); | 33 | struct request *orig_rq); |
| 34 | int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr); | 34 | int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr); |
| 35 | void blk_mq_wake_waiters(struct request_queue *q); | ||
| 35 | 36 | ||
| 36 | /* | 37 | /* |
| 37 | * CPU hotplug helpers | 38 | * CPU hotplug helpers |
diff --git a/block/blk-timeout.c b/block/blk-timeout.c index 56c025894cdf..246dfb16c3d9 100644 --- a/block/blk-timeout.c +++ b/block/blk-timeout.c | |||
| @@ -190,6 +190,9 @@ void blk_add_timer(struct request *req) | |||
| 190 | struct request_queue *q = req->q; | 190 | struct request_queue *q = req->q; |
| 191 | unsigned long expiry; | 191 | unsigned long expiry; |
| 192 | 192 | ||
| 193 | if (req->cmd_flags & REQ_NO_TIMEOUT) | ||
| 194 | return; | ||
| 195 | |||
| 193 | /* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */ | 196 | /* blk-mq has its own handler, so we don't need ->rq_timed_out_fn */ |
| 194 | if (!q->mq_ops && !q->rq_timed_out_fn) | 197 | if (!q->mq_ops && !q->rq_timed_out_fn) |
| 195 | return; | 198 | return; |
diff --git a/drivers/acpi/int340x_thermal.c b/drivers/acpi/int340x_thermal.c index a27d31d1ba24..9dcf83682e36 100644 --- a/drivers/acpi/int340x_thermal.c +++ b/drivers/acpi/int340x_thermal.c | |||
| @@ -14,10 +14,10 @@ | |||
| 14 | 14 | ||
| 15 | #include "internal.h" | 15 | #include "internal.h" |
| 16 | 16 | ||
| 17 | #define DO_ENUMERATION 0x01 | 17 | #define INT3401_DEVICE 0X01 |
| 18 | static const struct acpi_device_id int340x_thermal_device_ids[] = { | 18 | static const struct acpi_device_id int340x_thermal_device_ids[] = { |
| 19 | {"INT3400", DO_ENUMERATION }, | 19 | {"INT3400"}, |
| 20 | {"INT3401"}, | 20 | {"INT3401", INT3401_DEVICE}, |
| 21 | {"INT3402"}, | 21 | {"INT3402"}, |
| 22 | {"INT3403"}, | 22 | {"INT3403"}, |
| 23 | {"INT3404"}, | 23 | {"INT3404"}, |
| @@ -34,7 +34,10 @@ static int int340x_thermal_handler_attach(struct acpi_device *adev, | |||
| 34 | const struct acpi_device_id *id) | 34 | const struct acpi_device_id *id) |
| 35 | { | 35 | { |
| 36 | #if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE) | 36 | #if defined(CONFIG_INT340X_THERMAL) || defined(CONFIG_INT340X_THERMAL_MODULE) |
| 37 | if (id->driver_data == DO_ENUMERATION) | 37 | acpi_create_platform_device(adev); |
| 38 | #elif defined(INTEL_SOC_DTS_THERMAL) || defined(INTEL_SOC_DTS_THERMAL_MODULE) | ||
| 39 | /* Intel SoC DTS thermal driver needs INT3401 to set IRQ descriptor */ | ||
| 40 | if (id->driver_data == INT3401_DEVICE) | ||
| 38 | acpi_create_platform_device(adev); | 41 | acpi_create_platform_device(adev); |
| 39 | #endif | 42 | #endif |
| 40 | return 1; | 43 | return 1; |
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index ae9f615382f6..aa2224aa7caa 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
| @@ -530,7 +530,7 @@ static int null_add_dev(void) | |||
| 530 | goto out_cleanup_queues; | 530 | goto out_cleanup_queues; |
| 531 | 531 | ||
| 532 | nullb->q = blk_mq_init_queue(&nullb->tag_set); | 532 | nullb->q = blk_mq_init_queue(&nullb->tag_set); |
| 533 | if (!nullb->q) { | 533 | if (IS_ERR(nullb->q)) { |
| 534 | rv = -ENOMEM; | 534 | rv = -ENOMEM; |
| 535 | goto out_cleanup_tags; | 535 | goto out_cleanup_tags; |
| 536 | } | 536 | } |
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c index b1d5d8797315..cb529e9a82dd 100644 --- a/drivers/block/nvme-core.c +++ b/drivers/block/nvme-core.c | |||
| @@ -215,6 +215,7 @@ static void nvme_set_info(struct nvme_cmd_info *cmd, void *ctx, | |||
| 215 | cmd->fn = handler; | 215 | cmd->fn = handler; |
| 216 | cmd->ctx = ctx; | 216 | cmd->ctx = ctx; |
| 217 | cmd->aborted = 0; | 217 | cmd->aborted = 0; |
| 218 | blk_mq_start_request(blk_mq_rq_from_pdu(cmd)); | ||
| 218 | } | 219 | } |
| 219 | 220 | ||
| 220 | /* Special values must be less than 0x1000 */ | 221 | /* Special values must be less than 0x1000 */ |
| @@ -431,8 +432,13 @@ static void req_completion(struct nvme_queue *nvmeq, void *ctx, | |||
| 431 | if (unlikely(status)) { | 432 | if (unlikely(status)) { |
| 432 | if (!(status & NVME_SC_DNR || blk_noretry_request(req)) | 433 | if (!(status & NVME_SC_DNR || blk_noretry_request(req)) |
| 433 | && (jiffies - req->start_time) < req->timeout) { | 434 | && (jiffies - req->start_time) < req->timeout) { |
| 435 | unsigned long flags; | ||
| 436 | |||
| 434 | blk_mq_requeue_request(req); | 437 | blk_mq_requeue_request(req); |
| 435 | blk_mq_kick_requeue_list(req->q); | 438 | spin_lock_irqsave(req->q->queue_lock, flags); |
| 439 | if (!blk_queue_stopped(req->q)) | ||
| 440 | blk_mq_kick_requeue_list(req->q); | ||
| 441 | spin_unlock_irqrestore(req->q->queue_lock, flags); | ||
| 436 | return; | 442 | return; |
| 437 | } | 443 | } |
| 438 | req->errors = nvme_error_status(status); | 444 | req->errors = nvme_error_status(status); |
| @@ -664,8 +670,6 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
| 664 | } | 670 | } |
| 665 | } | 671 | } |
| 666 | 672 | ||
| 667 | blk_mq_start_request(req); | ||
| 668 | |||
| 669 | nvme_set_info(cmd, iod, req_completion); | 673 | nvme_set_info(cmd, iod, req_completion); |
| 670 | spin_lock_irq(&nvmeq->q_lock); | 674 | spin_lock_irq(&nvmeq->q_lock); |
| 671 | if (req->cmd_flags & REQ_DISCARD) | 675 | if (req->cmd_flags & REQ_DISCARD) |
| @@ -835,6 +839,7 @@ static int nvme_submit_async_admin_req(struct nvme_dev *dev) | |||
| 835 | if (IS_ERR(req)) | 839 | if (IS_ERR(req)) |
| 836 | return PTR_ERR(req); | 840 | return PTR_ERR(req); |
| 837 | 841 | ||
| 842 | req->cmd_flags |= REQ_NO_TIMEOUT; | ||
| 838 | cmd_info = blk_mq_rq_to_pdu(req); | 843 | cmd_info = blk_mq_rq_to_pdu(req); |
| 839 | nvme_set_info(cmd_info, req, async_req_completion); | 844 | nvme_set_info(cmd_info, req, async_req_completion); |
| 840 | 845 | ||
| @@ -1016,14 +1021,19 @@ static void nvme_abort_req(struct request *req) | |||
| 1016 | struct nvme_command cmd; | 1021 | struct nvme_command cmd; |
| 1017 | 1022 | ||
| 1018 | if (!nvmeq->qid || cmd_rq->aborted) { | 1023 | if (!nvmeq->qid || cmd_rq->aborted) { |
| 1024 | unsigned long flags; | ||
| 1025 | |||
| 1026 | spin_lock_irqsave(&dev_list_lock, flags); | ||
| 1019 | if (work_busy(&dev->reset_work)) | 1027 | if (work_busy(&dev->reset_work)) |
| 1020 | return; | 1028 | goto out; |
| 1021 | list_del_init(&dev->node); | 1029 | list_del_init(&dev->node); |
| 1022 | dev_warn(&dev->pci_dev->dev, | 1030 | dev_warn(&dev->pci_dev->dev, |
| 1023 | "I/O %d QID %d timeout, reset controller\n", | 1031 | "I/O %d QID %d timeout, reset controller\n", |
| 1024 | req->tag, nvmeq->qid); | 1032 | req->tag, nvmeq->qid); |
| 1025 | dev->reset_workfn = nvme_reset_failed_dev; | 1033 | dev->reset_workfn = nvme_reset_failed_dev; |
| 1026 | queue_work(nvme_workq, &dev->reset_work); | 1034 | queue_work(nvme_workq, &dev->reset_work); |
| 1035 | out: | ||
| 1036 | spin_unlock_irqrestore(&dev_list_lock, flags); | ||
| 1027 | return; | 1037 | return; |
| 1028 | } | 1038 | } |
| 1029 | 1039 | ||
| @@ -1064,15 +1074,22 @@ static void nvme_cancel_queue_ios(struct blk_mq_hw_ctx *hctx, | |||
| 1064 | void *ctx; | 1074 | void *ctx; |
| 1065 | nvme_completion_fn fn; | 1075 | nvme_completion_fn fn; |
| 1066 | struct nvme_cmd_info *cmd; | 1076 | struct nvme_cmd_info *cmd; |
| 1067 | static struct nvme_completion cqe = { | 1077 | struct nvme_completion cqe; |
| 1068 | .status = cpu_to_le16(NVME_SC_ABORT_REQ << 1), | 1078 | |
| 1069 | }; | 1079 | if (!blk_mq_request_started(req)) |
| 1080 | return; | ||
| 1070 | 1081 | ||
| 1071 | cmd = blk_mq_rq_to_pdu(req); | 1082 | cmd = blk_mq_rq_to_pdu(req); |
| 1072 | 1083 | ||
| 1073 | if (cmd->ctx == CMD_CTX_CANCELLED) | 1084 | if (cmd->ctx == CMD_CTX_CANCELLED) |
| 1074 | return; | 1085 | return; |
| 1075 | 1086 | ||
| 1087 | if (blk_queue_dying(req->q)) | ||
| 1088 | cqe.status = cpu_to_le16((NVME_SC_ABORT_REQ | NVME_SC_DNR) << 1); | ||
| 1089 | else | ||
| 1090 | cqe.status = cpu_to_le16(NVME_SC_ABORT_REQ << 1); | ||
| 1091 | |||
| 1092 | |||
| 1076 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", | 1093 | dev_warn(nvmeq->q_dmadev, "Cancelling I/O %d QID %d\n", |
| 1077 | req->tag, nvmeq->qid); | 1094 | req->tag, nvmeq->qid); |
| 1078 | ctx = cancel_cmd_info(cmd, &fn); | 1095 | ctx = cancel_cmd_info(cmd, &fn); |
| @@ -1084,17 +1101,29 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved) | |||
| 1084 | struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); | 1101 | struct nvme_cmd_info *cmd = blk_mq_rq_to_pdu(req); |
| 1085 | struct nvme_queue *nvmeq = cmd->nvmeq; | 1102 | struct nvme_queue *nvmeq = cmd->nvmeq; |
| 1086 | 1103 | ||
| 1087 | dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, | ||
| 1088 | nvmeq->qid); | ||
| 1089 | if (nvmeq->dev->initialized) | ||
| 1090 | nvme_abort_req(req); | ||
| 1091 | |||
| 1092 | /* | 1104 | /* |
| 1093 | * The aborted req will be completed on receiving the abort req. | 1105 | * The aborted req will be completed on receiving the abort req. |
| 1094 | * We enable the timer again. If hit twice, it'll cause a device reset, | 1106 | * We enable the timer again. If hit twice, it'll cause a device reset, |
| 1095 | * as the device then is in a faulty state. | 1107 | * as the device then is in a faulty state. |
| 1096 | */ | 1108 | */ |
| 1097 | return BLK_EH_RESET_TIMER; | 1109 | int ret = BLK_EH_RESET_TIMER; |
| 1110 | |||
| 1111 | dev_warn(nvmeq->q_dmadev, "Timeout I/O %d QID %d\n", req->tag, | ||
| 1112 | nvmeq->qid); | ||
| 1113 | |||
| 1114 | spin_lock_irq(&nvmeq->q_lock); | ||
| 1115 | if (!nvmeq->dev->initialized) { | ||
| 1116 | /* | ||
| 1117 | * Force cancelled command frees the request, which requires we | ||
| 1118 | * return BLK_EH_NOT_HANDLED. | ||
| 1119 | */ | ||
| 1120 | nvme_cancel_queue_ios(nvmeq->hctx, req, nvmeq, reserved); | ||
| 1121 | ret = BLK_EH_NOT_HANDLED; | ||
| 1122 | } else | ||
| 1123 | nvme_abort_req(req); | ||
| 1124 | spin_unlock_irq(&nvmeq->q_lock); | ||
| 1125 | |||
| 1126 | return ret; | ||
| 1098 | } | 1127 | } |
| 1099 | 1128 | ||
| 1100 | static void nvme_free_queue(struct nvme_queue *nvmeq) | 1129 | static void nvme_free_queue(struct nvme_queue *nvmeq) |
| @@ -1131,10 +1160,16 @@ static void nvme_free_queues(struct nvme_dev *dev, int lowest) | |||
| 1131 | */ | 1160 | */ |
| 1132 | static int nvme_suspend_queue(struct nvme_queue *nvmeq) | 1161 | static int nvme_suspend_queue(struct nvme_queue *nvmeq) |
| 1133 | { | 1162 | { |
| 1134 | int vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; | 1163 | int vector; |
| 1135 | 1164 | ||
| 1136 | spin_lock_irq(&nvmeq->q_lock); | 1165 | spin_lock_irq(&nvmeq->q_lock); |
| 1166 | if (nvmeq->cq_vector == -1) { | ||
| 1167 | spin_unlock_irq(&nvmeq->q_lock); | ||
| 1168 | return 1; | ||
| 1169 | } | ||
| 1170 | vector = nvmeq->dev->entry[nvmeq->cq_vector].vector; | ||
| 1137 | nvmeq->dev->online_queues--; | 1171 | nvmeq->dev->online_queues--; |
| 1172 | nvmeq->cq_vector = -1; | ||
| 1138 | spin_unlock_irq(&nvmeq->q_lock); | 1173 | spin_unlock_irq(&nvmeq->q_lock); |
| 1139 | 1174 | ||
| 1140 | irq_set_affinity_hint(vector, NULL); | 1175 | irq_set_affinity_hint(vector, NULL); |
| @@ -1169,11 +1204,13 @@ static void nvme_disable_queue(struct nvme_dev *dev, int qid) | |||
| 1169 | adapter_delete_sq(dev, qid); | 1204 | adapter_delete_sq(dev, qid); |
| 1170 | adapter_delete_cq(dev, qid); | 1205 | adapter_delete_cq(dev, qid); |
| 1171 | } | 1206 | } |
| 1207 | if (!qid && dev->admin_q) | ||
| 1208 | blk_mq_freeze_queue_start(dev->admin_q); | ||
| 1172 | nvme_clear_queue(nvmeq); | 1209 | nvme_clear_queue(nvmeq); |
| 1173 | } | 1210 | } |
| 1174 | 1211 | ||
| 1175 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | 1212 | static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, |
| 1176 | int depth, int vector) | 1213 | int depth) |
| 1177 | { | 1214 | { |
| 1178 | struct device *dmadev = &dev->pci_dev->dev; | 1215 | struct device *dmadev = &dev->pci_dev->dev; |
| 1179 | struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); | 1216 | struct nvme_queue *nvmeq = kzalloc(sizeof(*nvmeq), GFP_KERNEL); |
| @@ -1199,7 +1236,6 @@ static struct nvme_queue *nvme_alloc_queue(struct nvme_dev *dev, int qid, | |||
| 1199 | nvmeq->cq_phase = 1; | 1236 | nvmeq->cq_phase = 1; |
| 1200 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; | 1237 | nvmeq->q_db = &dev->dbs[qid * 2 * dev->db_stride]; |
| 1201 | nvmeq->q_depth = depth; | 1238 | nvmeq->q_depth = depth; |
| 1202 | nvmeq->cq_vector = vector; | ||
| 1203 | nvmeq->qid = qid; | 1239 | nvmeq->qid = qid; |
| 1204 | dev->queue_count++; | 1240 | dev->queue_count++; |
| 1205 | dev->queues[qid] = nvmeq; | 1241 | dev->queues[qid] = nvmeq; |
| @@ -1244,6 +1280,7 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) | |||
| 1244 | struct nvme_dev *dev = nvmeq->dev; | 1280 | struct nvme_dev *dev = nvmeq->dev; |
| 1245 | int result; | 1281 | int result; |
| 1246 | 1282 | ||
| 1283 | nvmeq->cq_vector = qid - 1; | ||
| 1247 | result = adapter_alloc_cq(dev, qid, nvmeq); | 1284 | result = adapter_alloc_cq(dev, qid, nvmeq); |
| 1248 | if (result < 0) | 1285 | if (result < 0) |
| 1249 | return result; | 1286 | return result; |
| @@ -1355,6 +1392,14 @@ static struct blk_mq_ops nvme_mq_ops = { | |||
| 1355 | .timeout = nvme_timeout, | 1392 | .timeout = nvme_timeout, |
| 1356 | }; | 1393 | }; |
| 1357 | 1394 | ||
| 1395 | static void nvme_dev_remove_admin(struct nvme_dev *dev) | ||
| 1396 | { | ||
| 1397 | if (dev->admin_q && !blk_queue_dying(dev->admin_q)) { | ||
| 1398 | blk_cleanup_queue(dev->admin_q); | ||
| 1399 | blk_mq_free_tag_set(&dev->admin_tagset); | ||
| 1400 | } | ||
| 1401 | } | ||
| 1402 | |||
| 1358 | static int nvme_alloc_admin_tags(struct nvme_dev *dev) | 1403 | static int nvme_alloc_admin_tags(struct nvme_dev *dev) |
| 1359 | { | 1404 | { |
| 1360 | if (!dev->admin_q) { | 1405 | if (!dev->admin_q) { |
| @@ -1370,21 +1415,20 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev) | |||
| 1370 | return -ENOMEM; | 1415 | return -ENOMEM; |
| 1371 | 1416 | ||
| 1372 | dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); | 1417 | dev->admin_q = blk_mq_init_queue(&dev->admin_tagset); |
| 1373 | if (!dev->admin_q) { | 1418 | if (IS_ERR(dev->admin_q)) { |
| 1374 | blk_mq_free_tag_set(&dev->admin_tagset); | 1419 | blk_mq_free_tag_set(&dev->admin_tagset); |
| 1375 | return -ENOMEM; | 1420 | return -ENOMEM; |
| 1376 | } | 1421 | } |
| 1377 | } | 1422 | if (!blk_get_queue(dev->admin_q)) { |
| 1423 | nvme_dev_remove_admin(dev); | ||
| 1424 | return -ENODEV; | ||
| 1425 | } | ||
| 1426 | } else | ||
| 1427 | blk_mq_unfreeze_queue(dev->admin_q); | ||
| 1378 | 1428 | ||
| 1379 | return 0; | 1429 | return 0; |
| 1380 | } | 1430 | } |
| 1381 | 1431 | ||
| 1382 | static void nvme_free_admin_tags(struct nvme_dev *dev) | ||
| 1383 | { | ||
| 1384 | if (dev->admin_q) | ||
| 1385 | blk_mq_free_tag_set(&dev->admin_tagset); | ||
| 1386 | } | ||
| 1387 | |||
| 1388 | static int nvme_configure_admin_queue(struct nvme_dev *dev) | 1432 | static int nvme_configure_admin_queue(struct nvme_dev *dev) |
| 1389 | { | 1433 | { |
| 1390 | int result; | 1434 | int result; |
| @@ -1416,7 +1460,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) | |||
| 1416 | 1460 | ||
| 1417 | nvmeq = dev->queues[0]; | 1461 | nvmeq = dev->queues[0]; |
| 1418 | if (!nvmeq) { | 1462 | if (!nvmeq) { |
| 1419 | nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH, 0); | 1463 | nvmeq = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH); |
| 1420 | if (!nvmeq) | 1464 | if (!nvmeq) |
| 1421 | return -ENOMEM; | 1465 | return -ENOMEM; |
| 1422 | } | 1466 | } |
| @@ -1439,18 +1483,13 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) | |||
| 1439 | if (result) | 1483 | if (result) |
| 1440 | goto free_nvmeq; | 1484 | goto free_nvmeq; |
| 1441 | 1485 | ||
| 1442 | result = nvme_alloc_admin_tags(dev); | 1486 | nvmeq->cq_vector = 0; |
| 1443 | if (result) | ||
| 1444 | goto free_nvmeq; | ||
| 1445 | |||
| 1446 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); | 1487 | result = queue_request_irq(dev, nvmeq, nvmeq->irqname); |
| 1447 | if (result) | 1488 | if (result) |
| 1448 | goto free_tags; | 1489 | goto free_nvmeq; |
| 1449 | 1490 | ||
| 1450 | return result; | 1491 | return result; |
| 1451 | 1492 | ||
| 1452 | free_tags: | ||
| 1453 | nvme_free_admin_tags(dev); | ||
| 1454 | free_nvmeq: | 1493 | free_nvmeq: |
| 1455 | nvme_free_queues(dev, 0); | 1494 | nvme_free_queues(dev, 0); |
| 1456 | return result; | 1495 | return result; |
| @@ -1944,7 +1983,7 @@ static void nvme_create_io_queues(struct nvme_dev *dev) | |||
| 1944 | unsigned i; | 1983 | unsigned i; |
| 1945 | 1984 | ||
| 1946 | for (i = dev->queue_count; i <= dev->max_qid; i++) | 1985 | for (i = dev->queue_count; i <= dev->max_qid; i++) |
| 1947 | if (!nvme_alloc_queue(dev, i, dev->q_depth, i - 1)) | 1986 | if (!nvme_alloc_queue(dev, i, dev->q_depth)) |
| 1948 | break; | 1987 | break; |
| 1949 | 1988 | ||
| 1950 | for (i = dev->online_queues; i <= dev->queue_count - 1; i++) | 1989 | for (i = dev->online_queues; i <= dev->queue_count - 1; i++) |
| @@ -2235,13 +2274,18 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev) | |||
| 2235 | break; | 2274 | break; |
| 2236 | if (!schedule_timeout(ADMIN_TIMEOUT) || | 2275 | if (!schedule_timeout(ADMIN_TIMEOUT) || |
| 2237 | fatal_signal_pending(current)) { | 2276 | fatal_signal_pending(current)) { |
| 2277 | /* | ||
| 2278 | * Disable the controller first since we can't trust it | ||
| 2279 | * at this point, but leave the admin queue enabled | ||
| 2280 | * until all queue deletion requests are flushed. | ||
| 2281 | * FIXME: This may take a while if there are more h/w | ||
| 2282 | * queues than admin tags. | ||
| 2283 | */ | ||
| 2238 | set_current_state(TASK_RUNNING); | 2284 | set_current_state(TASK_RUNNING); |
| 2239 | |||
| 2240 | nvme_disable_ctrl(dev, readq(&dev->bar->cap)); | 2285 | nvme_disable_ctrl(dev, readq(&dev->bar->cap)); |
| 2241 | nvme_disable_queue(dev, 0); | 2286 | nvme_clear_queue(dev->queues[0]); |
| 2242 | |||
| 2243 | send_sig(SIGKILL, dq->worker->task, 1); | ||
| 2244 | flush_kthread_worker(dq->worker); | 2287 | flush_kthread_worker(dq->worker); |
| 2288 | nvme_disable_queue(dev, 0); | ||
| 2245 | return; | 2289 | return; |
| 2246 | } | 2290 | } |
| 2247 | } | 2291 | } |
| @@ -2318,7 +2362,6 @@ static void nvme_del_queue_start(struct kthread_work *work) | |||
| 2318 | { | 2362 | { |
| 2319 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, | 2363 | struct nvme_queue *nvmeq = container_of(work, struct nvme_queue, |
| 2320 | cmdinfo.work); | 2364 | cmdinfo.work); |
| 2321 | allow_signal(SIGKILL); | ||
| 2322 | if (nvme_delete_sq(nvmeq)) | 2365 | if (nvme_delete_sq(nvmeq)) |
| 2323 | nvme_del_queue_end(nvmeq); | 2366 | nvme_del_queue_end(nvmeq); |
| 2324 | } | 2367 | } |
| @@ -2376,6 +2419,34 @@ static void nvme_dev_list_remove(struct nvme_dev *dev) | |||
| 2376 | kthread_stop(tmp); | 2419 | kthread_stop(tmp); |
| 2377 | } | 2420 | } |
| 2378 | 2421 | ||
| 2422 | static void nvme_freeze_queues(struct nvme_dev *dev) | ||
| 2423 | { | ||
| 2424 | struct nvme_ns *ns; | ||
| 2425 | |||
| 2426 | list_for_each_entry(ns, &dev->namespaces, list) { | ||
| 2427 | blk_mq_freeze_queue_start(ns->queue); | ||
| 2428 | |||
| 2429 | spin_lock(ns->queue->queue_lock); | ||
| 2430 | queue_flag_set(QUEUE_FLAG_STOPPED, ns->queue); | ||
| 2431 | spin_unlock(ns->queue->queue_lock); | ||
| 2432 | |||
| 2433 | blk_mq_cancel_requeue_work(ns->queue); | ||
| 2434 | blk_mq_stop_hw_queues(ns->queue); | ||
| 2435 | } | ||
| 2436 | } | ||
| 2437 | |||
| 2438 | static void nvme_unfreeze_queues(struct nvme_dev *dev) | ||
| 2439 | { | ||
| 2440 | struct nvme_ns *ns; | ||
| 2441 | |||
| 2442 | list_for_each_entry(ns, &dev->namespaces, list) { | ||
| 2443 | queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, ns->queue); | ||
| 2444 | blk_mq_unfreeze_queue(ns->queue); | ||
| 2445 | blk_mq_start_stopped_hw_queues(ns->queue, true); | ||
| 2446 | blk_mq_kick_requeue_list(ns->queue); | ||
| 2447 | } | ||
| 2448 | } | ||
| 2449 | |||
| 2379 | static void nvme_dev_shutdown(struct nvme_dev *dev) | 2450 | static void nvme_dev_shutdown(struct nvme_dev *dev) |
| 2380 | { | 2451 | { |
| 2381 | int i; | 2452 | int i; |
| @@ -2384,8 +2455,10 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) | |||
| 2384 | dev->initialized = 0; | 2455 | dev->initialized = 0; |
| 2385 | nvme_dev_list_remove(dev); | 2456 | nvme_dev_list_remove(dev); |
| 2386 | 2457 | ||
| 2387 | if (dev->bar) | 2458 | if (dev->bar) { |
| 2459 | nvme_freeze_queues(dev); | ||
| 2388 | csts = readl(&dev->bar->csts); | 2460 | csts = readl(&dev->bar->csts); |
| 2461 | } | ||
| 2389 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { | 2462 | if (csts & NVME_CSTS_CFS || !(csts & NVME_CSTS_RDY)) { |
| 2390 | for (i = dev->queue_count - 1; i >= 0; i--) { | 2463 | for (i = dev->queue_count - 1; i >= 0; i--) { |
| 2391 | struct nvme_queue *nvmeq = dev->queues[i]; | 2464 | struct nvme_queue *nvmeq = dev->queues[i]; |
| @@ -2400,12 +2473,6 @@ static void nvme_dev_shutdown(struct nvme_dev *dev) | |||
| 2400 | nvme_dev_unmap(dev); | 2473 | nvme_dev_unmap(dev); |
| 2401 | } | 2474 | } |
| 2402 | 2475 | ||
| 2403 | static void nvme_dev_remove_admin(struct nvme_dev *dev) | ||
| 2404 | { | ||
| 2405 | if (dev->admin_q && !blk_queue_dying(dev->admin_q)) | ||
| 2406 | blk_cleanup_queue(dev->admin_q); | ||
| 2407 | } | ||
| 2408 | |||
| 2409 | static void nvme_dev_remove(struct nvme_dev *dev) | 2476 | static void nvme_dev_remove(struct nvme_dev *dev) |
| 2410 | { | 2477 | { |
| 2411 | struct nvme_ns *ns; | 2478 | struct nvme_ns *ns; |
| @@ -2413,8 +2480,10 @@ static void nvme_dev_remove(struct nvme_dev *dev) | |||
| 2413 | list_for_each_entry(ns, &dev->namespaces, list) { | 2480 | list_for_each_entry(ns, &dev->namespaces, list) { |
| 2414 | if (ns->disk->flags & GENHD_FL_UP) | 2481 | if (ns->disk->flags & GENHD_FL_UP) |
| 2415 | del_gendisk(ns->disk); | 2482 | del_gendisk(ns->disk); |
| 2416 | if (!blk_queue_dying(ns->queue)) | 2483 | if (!blk_queue_dying(ns->queue)) { |
| 2484 | blk_mq_abort_requeue_list(ns->queue); | ||
| 2417 | blk_cleanup_queue(ns->queue); | 2485 | blk_cleanup_queue(ns->queue); |
| 2486 | } | ||
| 2418 | } | 2487 | } |
| 2419 | } | 2488 | } |
| 2420 | 2489 | ||
| @@ -2495,6 +2564,7 @@ static void nvme_free_dev(struct kref *kref) | |||
| 2495 | nvme_free_namespaces(dev); | 2564 | nvme_free_namespaces(dev); |
| 2496 | nvme_release_instance(dev); | 2565 | nvme_release_instance(dev); |
| 2497 | blk_mq_free_tag_set(&dev->tagset); | 2566 | blk_mq_free_tag_set(&dev->tagset); |
| 2567 | blk_put_queue(dev->admin_q); | ||
| 2498 | kfree(dev->queues); | 2568 | kfree(dev->queues); |
| 2499 | kfree(dev->entry); | 2569 | kfree(dev->entry); |
| 2500 | kfree(dev); | 2570 | kfree(dev); |
| @@ -2591,15 +2661,20 @@ static int nvme_dev_start(struct nvme_dev *dev) | |||
| 2591 | } | 2661 | } |
| 2592 | 2662 | ||
| 2593 | nvme_init_queue(dev->queues[0], 0); | 2663 | nvme_init_queue(dev->queues[0], 0); |
| 2664 | result = nvme_alloc_admin_tags(dev); | ||
| 2665 | if (result) | ||
| 2666 | goto disable; | ||
| 2594 | 2667 | ||
| 2595 | result = nvme_setup_io_queues(dev); | 2668 | result = nvme_setup_io_queues(dev); |
| 2596 | if (result) | 2669 | if (result) |
| 2597 | goto disable; | 2670 | goto free_tags; |
| 2598 | 2671 | ||
| 2599 | nvme_set_irq_hints(dev); | 2672 | nvme_set_irq_hints(dev); |
| 2600 | 2673 | ||
| 2601 | return result; | 2674 | return result; |
| 2602 | 2675 | ||
| 2676 | free_tags: | ||
| 2677 | nvme_dev_remove_admin(dev); | ||
| 2603 | disable: | 2678 | disable: |
| 2604 | nvme_disable_queue(dev, 0); | 2679 | nvme_disable_queue(dev, 0); |
| 2605 | nvme_dev_list_remove(dev); | 2680 | nvme_dev_list_remove(dev); |
| @@ -2639,6 +2714,9 @@ static int nvme_dev_resume(struct nvme_dev *dev) | |||
| 2639 | dev->reset_workfn = nvme_remove_disks; | 2714 | dev->reset_workfn = nvme_remove_disks; |
| 2640 | queue_work(nvme_workq, &dev->reset_work); | 2715 | queue_work(nvme_workq, &dev->reset_work); |
| 2641 | spin_unlock(&dev_list_lock); | 2716 | spin_unlock(&dev_list_lock); |
| 2717 | } else { | ||
| 2718 | nvme_unfreeze_queues(dev); | ||
| 2719 | nvme_set_irq_hints(dev); | ||
| 2642 | } | 2720 | } |
| 2643 | dev->initialized = 1; | 2721 | dev->initialized = 1; |
| 2644 | return 0; | 2722 | return 0; |
| @@ -2776,11 +2854,10 @@ static void nvme_remove(struct pci_dev *pdev) | |||
| 2776 | pci_set_drvdata(pdev, NULL); | 2854 | pci_set_drvdata(pdev, NULL); |
| 2777 | flush_work(&dev->reset_work); | 2855 | flush_work(&dev->reset_work); |
| 2778 | misc_deregister(&dev->miscdev); | 2856 | misc_deregister(&dev->miscdev); |
| 2779 | nvme_dev_remove(dev); | ||
| 2780 | nvme_dev_shutdown(dev); | 2857 | nvme_dev_shutdown(dev); |
| 2858 | nvme_dev_remove(dev); | ||
| 2781 | nvme_dev_remove_admin(dev); | 2859 | nvme_dev_remove_admin(dev); |
| 2782 | nvme_free_queues(dev, 0); | 2860 | nvme_free_queues(dev, 0); |
| 2783 | nvme_free_admin_tags(dev); | ||
| 2784 | nvme_release_prp_pools(dev); | 2861 | nvme_release_prp_pools(dev); |
| 2785 | kref_put(&dev->kref, nvme_free_dev); | 2862 | kref_put(&dev->kref, nvme_free_dev); |
| 2786 | } | 2863 | } |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 7ef7c098708f..cdfbd21e3597 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -638,7 +638,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
| 638 | goto out_put_disk; | 638 | goto out_put_disk; |
| 639 | 639 | ||
| 640 | q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set); | 640 | q = vblk->disk->queue = blk_mq_init_queue(&vblk->tag_set); |
| 641 | if (!q) { | 641 | if (IS_ERR(q)) { |
| 642 | err = -ENOMEM; | 642 | err = -ENOMEM; |
| 643 | goto out_free_tags; | 643 | goto out_free_tags; |
| 644 | } | 644 | } |
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index 26515c27ea8c..25e419752a7b 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c | |||
| @@ -330,18 +330,18 @@ create_netxbig_led(struct platform_device *pdev, | |||
| 330 | led_dat->sata = 0; | 330 | led_dat->sata = 0; |
| 331 | led_dat->cdev.brightness = LED_OFF; | 331 | led_dat->cdev.brightness = LED_OFF; |
| 332 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; | 332 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; |
| 333 | /* | ||
| 334 | * If available, expose the SATA activity blink capability through | ||
| 335 | * a "sata" sysfs attribute. | ||
| 336 | */ | ||
| 337 | if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) | ||
| 338 | led_dat->cdev.groups = netxbig_led_groups; | ||
| 339 | led_dat->mode_addr = template->mode_addr; | 333 | led_dat->mode_addr = template->mode_addr; |
| 340 | led_dat->mode_val = template->mode_val; | 334 | led_dat->mode_val = template->mode_val; |
| 341 | led_dat->bright_addr = template->bright_addr; | 335 | led_dat->bright_addr = template->bright_addr; |
| 342 | led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1; | 336 | led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1; |
| 343 | led_dat->timer = pdata->timer; | 337 | led_dat->timer = pdata->timer; |
| 344 | led_dat->num_timer = pdata->num_timer; | 338 | led_dat->num_timer = pdata->num_timer; |
| 339 | /* | ||
| 340 | * If available, expose the SATA activity blink capability through | ||
| 341 | * a "sata" sysfs attribute. | ||
| 342 | */ | ||
| 343 | if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) | ||
| 344 | led_dat->cdev.groups = netxbig_led_groups; | ||
| 345 | 345 | ||
| 346 | return led_classdev_register(&pdev->dev, &led_dat->cdev); | 346 | return led_classdev_register(&pdev->dev, &led_dat->cdev); |
| 347 | } | 347 | } |
diff --git a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c index 231cabc16e16..2c2ec7666eb1 100644 --- a/drivers/thermal/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/int340x_thermal/acpi_thermal_rel.c | |||
| @@ -119,15 +119,11 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, | |||
| 119 | continue; | 119 | continue; |
| 120 | 120 | ||
| 121 | result = acpi_bus_get_device(trt->source, &adev); | 121 | result = acpi_bus_get_device(trt->source, &adev); |
| 122 | if (!result) | 122 | if (result) |
| 123 | acpi_create_platform_device(adev); | ||
| 124 | else | ||
| 125 | pr_warn("Failed to get source ACPI device\n"); | 123 | pr_warn("Failed to get source ACPI device\n"); |
| 126 | 124 | ||
| 127 | result = acpi_bus_get_device(trt->target, &adev); | 125 | result = acpi_bus_get_device(trt->target, &adev); |
| 128 | if (!result) | 126 | if (result) |
| 129 | acpi_create_platform_device(adev); | ||
| 130 | else | ||
| 131 | pr_warn("Failed to get target ACPI device\n"); | 127 | pr_warn("Failed to get target ACPI device\n"); |
| 132 | } | 128 | } |
| 133 | 129 | ||
| @@ -206,16 +202,12 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp, | |||
| 206 | 202 | ||
| 207 | if (art->source) { | 203 | if (art->source) { |
| 208 | result = acpi_bus_get_device(art->source, &adev); | 204 | result = acpi_bus_get_device(art->source, &adev); |
| 209 | if (!result) | 205 | if (result) |
| 210 | acpi_create_platform_device(adev); | ||
| 211 | else | ||
| 212 | pr_warn("Failed to get source ACPI device\n"); | 206 | pr_warn("Failed to get source ACPI device\n"); |
| 213 | } | 207 | } |
| 214 | if (art->target) { | 208 | if (art->target) { |
| 215 | result = acpi_bus_get_device(art->target, &adev); | 209 | result = acpi_bus_get_device(art->target, &adev); |
| 216 | if (!result) | 210 | if (result) |
| 217 | acpi_create_platform_device(adev); | ||
| 218 | else | ||
| 219 | pr_warn("Failed to get source ACPI device\n"); | 211 | pr_warn("Failed to get source ACPI device\n"); |
| 220 | } | 212 | } |
| 221 | } | 213 | } |
diff --git a/drivers/thermal/int340x_thermal/processor_thermal_device.c b/drivers/thermal/int340x_thermal/processor_thermal_device.c index 31bb553aac26..0fe5dbbea968 100644 --- a/drivers/thermal/int340x_thermal/processor_thermal_device.c +++ b/drivers/thermal/int340x_thermal/processor_thermal_device.c | |||
| @@ -130,6 +130,8 @@ static int proc_thermal_add(struct device *dev, | |||
| 130 | int ret; | 130 | int ret; |
| 131 | 131 | ||
| 132 | adev = ACPI_COMPANION(dev); | 132 | adev = ACPI_COMPANION(dev); |
| 133 | if (!adev) | ||
| 134 | return -ENODEV; | ||
| 133 | 135 | ||
| 134 | status = acpi_evaluate_object(adev->handle, "PPCC", NULL, &buf); | 136 | status = acpi_evaluate_object(adev->handle, "PPCC", NULL, &buf); |
| 135 | if (ACPI_FAILURE(status)) | 137 | if (ACPI_FAILURE(status)) |
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 8aded9ab2e4e..5735e7130d63 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h | |||
| @@ -34,7 +34,6 @@ struct blk_mq_hw_ctx { | |||
| 34 | unsigned long flags; /* BLK_MQ_F_* flags */ | 34 | unsigned long flags; /* BLK_MQ_F_* flags */ |
| 35 | 35 | ||
| 36 | struct request_queue *queue; | 36 | struct request_queue *queue; |
| 37 | unsigned int queue_num; | ||
| 38 | struct blk_flush_queue *fq; | 37 | struct blk_flush_queue *fq; |
| 39 | 38 | ||
| 40 | void *driver_data; | 39 | void *driver_data; |
| @@ -54,7 +53,7 @@ struct blk_mq_hw_ctx { | |||
| 54 | unsigned long dispatched[BLK_MQ_MAX_DISPATCH_ORDER]; | 53 | unsigned long dispatched[BLK_MQ_MAX_DISPATCH_ORDER]; |
| 55 | 54 | ||
| 56 | unsigned int numa_node; | 55 | unsigned int numa_node; |
| 57 | unsigned int cmd_size; /* per-request extra data */ | 56 | unsigned int queue_num; |
| 58 | 57 | ||
| 59 | atomic_t nr_active; | 58 | atomic_t nr_active; |
| 60 | 59 | ||
| @@ -195,13 +194,16 @@ static inline u16 blk_mq_unique_tag_to_tag(u32 unique_tag) | |||
| 195 | struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index); | 194 | struct blk_mq_hw_ctx *blk_mq_map_queue(struct request_queue *, const int ctx_index); |
| 196 | struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int); | 195 | struct blk_mq_hw_ctx *blk_mq_alloc_single_hw_queue(struct blk_mq_tag_set *, unsigned int, int); |
| 197 | 196 | ||
| 197 | int blk_mq_request_started(struct request *rq); | ||
| 198 | void blk_mq_start_request(struct request *rq); | 198 | void blk_mq_start_request(struct request *rq); |
| 199 | void blk_mq_end_request(struct request *rq, int error); | 199 | void blk_mq_end_request(struct request *rq, int error); |
| 200 | void __blk_mq_end_request(struct request *rq, int error); | 200 | void __blk_mq_end_request(struct request *rq, int error); |
| 201 | 201 | ||
| 202 | void blk_mq_requeue_request(struct request *rq); | 202 | void blk_mq_requeue_request(struct request *rq); |
| 203 | void blk_mq_add_to_requeue_list(struct request *rq, bool at_head); | 203 | void blk_mq_add_to_requeue_list(struct request *rq, bool at_head); |
| 204 | void blk_mq_cancel_requeue_work(struct request_queue *q); | ||
| 204 | void blk_mq_kick_requeue_list(struct request_queue *q); | 205 | void blk_mq_kick_requeue_list(struct request_queue *q); |
| 206 | void blk_mq_abort_requeue_list(struct request_queue *q); | ||
| 205 | void blk_mq_complete_request(struct request *rq); | 207 | void blk_mq_complete_request(struct request *rq); |
| 206 | 208 | ||
| 207 | void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx); | 209 | void blk_mq_stop_hw_queue(struct blk_mq_hw_ctx *hctx); |
| @@ -212,6 +214,8 @@ void blk_mq_start_stopped_hw_queues(struct request_queue *q, bool async); | |||
| 212 | void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs); | 214 | void blk_mq_delay_queue(struct blk_mq_hw_ctx *hctx, unsigned long msecs); |
| 213 | void blk_mq_tag_busy_iter(struct blk_mq_hw_ctx *hctx, busy_iter_fn *fn, | 215 | void blk_mq_tag_busy_iter(struct blk_mq_hw_ctx *hctx, busy_iter_fn *fn, |
| 214 | void *priv); | 216 | void *priv); |
| 217 | void blk_mq_unfreeze_queue(struct request_queue *q); | ||
| 218 | void blk_mq_freeze_queue_start(struct request_queue *q); | ||
| 215 | 219 | ||
| 216 | /* | 220 | /* |
| 217 | * Driver command data is immediately after the request. So subtract request | 221 | * Driver command data is immediately after the request. So subtract request |
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index 445d59231bc4..c294e3e25e37 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h | |||
| @@ -190,6 +190,7 @@ enum rq_flag_bits { | |||
| 190 | __REQ_PM, /* runtime pm request */ | 190 | __REQ_PM, /* runtime pm request */ |
| 191 | __REQ_HASHED, /* on IO scheduler merge hash */ | 191 | __REQ_HASHED, /* on IO scheduler merge hash */ |
| 192 | __REQ_MQ_INFLIGHT, /* track inflight for MQ */ | 192 | __REQ_MQ_INFLIGHT, /* track inflight for MQ */ |
| 193 | __REQ_NO_TIMEOUT, /* requests may never expire */ | ||
| 193 | __REQ_NR_BITS, /* stops here */ | 194 | __REQ_NR_BITS, /* stops here */ |
| 194 | }; | 195 | }; |
| 195 | 196 | ||
| @@ -243,5 +244,6 @@ enum rq_flag_bits { | |||
| 243 | #define REQ_PM (1ULL << __REQ_PM) | 244 | #define REQ_PM (1ULL << __REQ_PM) |
| 244 | #define REQ_HASHED (1ULL << __REQ_HASHED) | 245 | #define REQ_HASHED (1ULL << __REQ_HASHED) |
| 245 | #define REQ_MQ_INFLIGHT (1ULL << __REQ_MQ_INFLIGHT) | 246 | #define REQ_MQ_INFLIGHT (1ULL << __REQ_MQ_INFLIGHT) |
| 247 | #define REQ_NO_TIMEOUT (1ULL << __REQ_NO_TIMEOUT) | ||
| 246 | 248 | ||
| 247 | #endif /* __LINUX_BLK_TYPES_H */ | 249 | #endif /* __LINUX_BLK_TYPES_H */ |
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index a1c81f80978e..33063f872ee3 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
| @@ -215,7 +215,7 @@ static __always_inline void __read_once_size(volatile void *p, void *res, int si | |||
| 215 | } | 215 | } |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | static __always_inline void __assign_once_size(volatile void *p, void *res, int size) | 218 | static __always_inline void __write_once_size(volatile void *p, void *res, int size) |
| 219 | { | 219 | { |
| 220 | switch (size) { | 220 | switch (size) { |
| 221 | case 1: *(volatile __u8 *)p = *(__u8 *)res; break; | 221 | case 1: *(volatile __u8 *)p = *(__u8 *)res; break; |
| @@ -235,15 +235,15 @@ static __always_inline void __assign_once_size(volatile void *p, void *res, int | |||
| 235 | /* | 235 | /* |
| 236 | * Prevent the compiler from merging or refetching reads or writes. The | 236 | * Prevent the compiler from merging or refetching reads or writes. The |
| 237 | * compiler is also forbidden from reordering successive instances of | 237 | * compiler is also forbidden from reordering successive instances of |
| 238 | * READ_ONCE, ASSIGN_ONCE and ACCESS_ONCE (see below), but only when the | 238 | * READ_ONCE, WRITE_ONCE and ACCESS_ONCE (see below), but only when the |
| 239 | * compiler is aware of some particular ordering. One way to make the | 239 | * compiler is aware of some particular ordering. One way to make the |
| 240 | * compiler aware of ordering is to put the two invocations of READ_ONCE, | 240 | * compiler aware of ordering is to put the two invocations of READ_ONCE, |
| 241 | * ASSIGN_ONCE or ACCESS_ONCE() in different C statements. | 241 | * WRITE_ONCE or ACCESS_ONCE() in different C statements. |
| 242 | * | 242 | * |
| 243 | * In contrast to ACCESS_ONCE these two macros will also work on aggregate | 243 | * In contrast to ACCESS_ONCE these two macros will also work on aggregate |
| 244 | * data types like structs or unions. If the size of the accessed data | 244 | * data types like structs or unions. If the size of the accessed data |
| 245 | * type exceeds the word size of the machine (e.g., 32 bits or 64 bits) | 245 | * type exceeds the word size of the machine (e.g., 32 bits or 64 bits) |
| 246 | * READ_ONCE() and ASSIGN_ONCE() will fall back to memcpy and print a | 246 | * READ_ONCE() and WRITE_ONCE() will fall back to memcpy and print a |
| 247 | * compile-time warning. | 247 | * compile-time warning. |
| 248 | * | 248 | * |
| 249 | * Their two major use cases are: (1) Mediating communication between | 249 | * Their two major use cases are: (1) Mediating communication between |
| @@ -257,8 +257,8 @@ static __always_inline void __assign_once_size(volatile void *p, void *res, int | |||
| 257 | #define READ_ONCE(x) \ | 257 | #define READ_ONCE(x) \ |
| 258 | ({ typeof(x) __val; __read_once_size(&x, &__val, sizeof(__val)); __val; }) | 258 | ({ typeof(x) __val; __read_once_size(&x, &__val, sizeof(__val)); __val; }) |
| 259 | 259 | ||
| 260 | #define ASSIGN_ONCE(val, x) \ | 260 | #define WRITE_ONCE(x, val) \ |
| 261 | ({ typeof(x) __val; __val = val; __assign_once_size(&x, &__val, sizeof(__val)); __val; }) | 261 | ({ typeof(x) __val; __val = val; __write_once_size(&x, &__val, sizeof(__val)); __val; }) |
| 262 | 262 | ||
| 263 | #endif /* __KERNEL__ */ | 263 | #endif /* __KERNEL__ */ |
| 264 | 264 | ||
diff --git a/include/xen/interface/nmi.h b/include/xen/interface/nmi.h new file mode 100644 index 000000000000..b47d9d06fade --- /dev/null +++ b/include/xen/interface/nmi.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /****************************************************************************** | ||
| 2 | * nmi.h | ||
| 3 | * | ||
| 4 | * NMI callback registration and reason codes. | ||
| 5 | * | ||
| 6 | * Copyright (c) 2005, Keir Fraser <keir@xensource.com> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __XEN_PUBLIC_NMI_H__ | ||
| 10 | #define __XEN_PUBLIC_NMI_H__ | ||
| 11 | |||
| 12 | #include <xen/interface/xen.h> | ||
| 13 | |||
| 14 | /* | ||
| 15 | * NMI reason codes: | ||
| 16 | * Currently these are x86-specific, stored in arch_shared_info.nmi_reason. | ||
| 17 | */ | ||
| 18 | /* I/O-check error reported via ISA port 0x61, bit 6. */ | ||
| 19 | #define _XEN_NMIREASON_io_error 0 | ||
| 20 | #define XEN_NMIREASON_io_error (1UL << _XEN_NMIREASON_io_error) | ||
| 21 | /* PCI SERR reported via ISA port 0x61, bit 7. */ | ||
| 22 | #define _XEN_NMIREASON_pci_serr 1 | ||
| 23 | #define XEN_NMIREASON_pci_serr (1UL << _XEN_NMIREASON_pci_serr) | ||
| 24 | /* Unknown hardware-generated NMI. */ | ||
| 25 | #define _XEN_NMIREASON_unknown 2 | ||
| 26 | #define XEN_NMIREASON_unknown (1UL << _XEN_NMIREASON_unknown) | ||
| 27 | |||
| 28 | /* | ||
| 29 | * long nmi_op(unsigned int cmd, void *arg) | ||
| 30 | * NB. All ops return zero on success, else a negative error code. | ||
| 31 | */ | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Register NMI callback for this (calling) VCPU. Currently this only makes | ||
| 35 | * sense for domain 0, vcpu 0. All other callers will be returned EINVAL. | ||
| 36 | * arg == pointer to xennmi_callback structure. | ||
| 37 | */ | ||
| 38 | #define XENNMI_register_callback 0 | ||
| 39 | struct xennmi_callback { | ||
| 40 | unsigned long handler_address; | ||
| 41 | unsigned long pad; | ||
| 42 | }; | ||
| 43 | DEFINE_GUEST_HANDLE_STRUCT(xennmi_callback); | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Deregister NMI callback for this (calling) VCPU. | ||
| 47 | * arg == NULL. | ||
| 48 | */ | ||
| 49 | #define XENNMI_unregister_callback 1 | ||
| 50 | |||
| 51 | #endif /* __XEN_PUBLIC_NMI_H__ */ | ||
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c index d273624c93a6..e238c9559caf 100644 --- a/tools/testing/selftests/exec/execveat.c +++ b/tools/testing/selftests/exec/execveat.c | |||
| @@ -62,7 +62,7 @@ static int _check_execveat_fail(int fd, const char *path, int flags, | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static int check_execveat_invoked_rc(int fd, const char *path, int flags, | 64 | static int check_execveat_invoked_rc(int fd, const char *path, int flags, |
| 65 | int expected_rc) | 65 | int expected_rc, int expected_rc2) |
| 66 | { | 66 | { |
| 67 | int status; | 67 | int status; |
| 68 | int rc; | 68 | int rc; |
| @@ -98,9 +98,10 @@ static int check_execveat_invoked_rc(int fd, const char *path, int flags, | |||
| 98 | child, status); | 98 | child, status); |
| 99 | return 1; | 99 | return 1; |
| 100 | } | 100 | } |
| 101 | if (WEXITSTATUS(status) != expected_rc) { | 101 | if ((WEXITSTATUS(status) != expected_rc) && |
| 102 | printf("[FAIL] (child %d exited with %d not %d)\n", | 102 | (WEXITSTATUS(status) != expected_rc2)) { |
| 103 | child, WEXITSTATUS(status), expected_rc); | 103 | printf("[FAIL] (child %d exited with %d not %d nor %d)\n", |
| 104 | child, WEXITSTATUS(status), expected_rc, expected_rc2); | ||
| 104 | return 1; | 105 | return 1; |
| 105 | } | 106 | } |
| 106 | printf("[OK]\n"); | 107 | printf("[OK]\n"); |
| @@ -109,7 +110,7 @@ static int check_execveat_invoked_rc(int fd, const char *path, int flags, | |||
| 109 | 110 | ||
| 110 | static int check_execveat(int fd, const char *path, int flags) | 111 | static int check_execveat(int fd, const char *path, int flags) |
| 111 | { | 112 | { |
| 112 | return check_execveat_invoked_rc(fd, path, flags, 99); | 113 | return check_execveat_invoked_rc(fd, path, flags, 99, 99); |
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | static char *concat(const char *left, const char *right) | 116 | static char *concat(const char *left, const char *right) |
| @@ -192,9 +193,15 @@ static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script) | |||
| 192 | * Execute as a long pathname relative to ".". If this is a script, | 193 | * Execute as a long pathname relative to ".". If this is a script, |
| 193 | * the interpreter will launch but fail to open the script because its | 194 | * the interpreter will launch but fail to open the script because its |
| 194 | * name ("/dev/fd/5/xxx....") is bigger than PATH_MAX. | 195 | * name ("/dev/fd/5/xxx....") is bigger than PATH_MAX. |
| 196 | * | ||
| 197 | * The failure code is usually 127 (POSIX: "If a command is not found, | ||
| 198 | * the exit status shall be 127."), but some systems give 126 (POSIX: | ||
| 199 | * "If the command name is found, but it is not an executable utility, | ||
| 200 | * the exit status shall be 126."), so allow either. | ||
| 195 | */ | 201 | */ |
| 196 | if (is_script) | 202 | if (is_script) |
| 197 | fail += check_execveat_invoked_rc(dot_dfd, longpath, 0, 127); | 203 | fail += check_execveat_invoked_rc(dot_dfd, longpath, 0, |
| 204 | 127, 126); | ||
| 198 | else | 205 | else |
| 199 | fail += check_execveat(dot_dfd, longpath, 0); | 206 | fail += check_execveat(dot_dfd, longpath, 0); |
| 200 | 207 | ||
diff --git a/tools/testing/selftests/mqueue/mq_perf_tests.c b/tools/testing/selftests/mqueue/mq_perf_tests.c index 94dae65eea41..8519e9ee97e3 100644 --- a/tools/testing/selftests/mqueue/mq_perf_tests.c +++ b/tools/testing/selftests/mqueue/mq_perf_tests.c | |||
| @@ -536,10 +536,9 @@ int main(int argc, char *argv[]) | |||
| 536 | { | 536 | { |
| 537 | struct mq_attr attr; | 537 | struct mq_attr attr; |
| 538 | char *option, *next_option; | 538 | char *option, *next_option; |
| 539 | int i, cpu; | 539 | int i, cpu, rc; |
| 540 | struct sigaction sa; | 540 | struct sigaction sa; |
| 541 | poptContext popt_context; | 541 | poptContext popt_context; |
| 542 | char rc; | ||
| 543 | void *retval; | 542 | void *retval; |
| 544 | 543 | ||
| 545 | main_thread = pthread_self(); | 544 | main_thread = pthread_self(); |
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index 4c4b1f631ecf..077828c889f1 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile | |||
| @@ -7,7 +7,7 @@ BINARIES += transhuge-stress | |||
| 7 | 7 | ||
| 8 | all: $(BINARIES) | 8 | all: $(BINARIES) |
| 9 | %: %.c | 9 | %: %.c |
| 10 | $(CC) $(CFLAGS) -o $@ $^ | 10 | $(CC) $(CFLAGS) -o $@ $^ -lrt |
| 11 | 11 | ||
| 12 | run_tests: all | 12 | run_tests: all |
| 13 | @/bin/sh ./run_vmtests || (echo "vmtests: [FAIL]"; exit 1) | 13 | @/bin/sh ./run_vmtests || (echo "vmtests: [FAIL]"; exit 1) |
