Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes from Martin Schwidefsky:

- A couple of bug fixes: memory management, perf, cio, dasd and
scm_blk.

- A larger change in regard to the CPU topology to improve performance
for systems running under z/VM or KVM.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
s390/topology: enable / disable topology dynamically
s390/topology: alternative topology for topology-less machines
s390/mm: fix write access check in gup_huge_pmd()
s390/mm: make pmdp_invalidate() do invalidation only
s390/cio: recover from bad paths
s390/scm_blk: consistently use blk_status_t as error type
s390/dasd: fix race during dasd initialization
s390/perf: fix bug when creating per-thread event

+183 -42
+3 -1
arch/s390/include/asm/pgtable.h
··· 1507 1507 static inline void pmdp_invalidate(struct vm_area_struct *vma, 1508 1508 unsigned long addr, pmd_t *pmdp) 1509 1509 { 1510 - pmdp_xchg_direct(vma->vm_mm, addr, pmdp, __pmd(_SEGMENT_ENTRY_EMPTY)); 1510 + pmd_t pmd = __pmd(pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID); 1511 + 1512 + pmdp_xchg_direct(vma->vm_mm, addr, pmdp, pmd); 1511 1513 } 1512 1514 1513 1515 #define __HAVE_ARCH_PMDP_SET_WRPROTECT
-12
arch/s390/kernel/early.c
··· 404 404 #endif 405 405 } 406 406 407 - static int __init topology_setup(char *str) 408 - { 409 - bool enabled; 410 - int rc; 411 - 412 - rc = kstrtobool(str, &enabled); 413 - if (!rc && !enabled) 414 - S390_lowcore.machine_flags &= ~MACHINE_FLAG_TOPOLOGY; 415 - return rc; 416 - } 417 - early_param("topology", topology_setup); 418 - 419 407 static int __init disable_vector_extension(char *str) 420 408 { 421 409 S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX;
+6 -3
arch/s390/kernel/perf_cpum_sf.c
··· 823 823 } 824 824 825 825 /* Check online status of the CPU to which the event is pinned */ 826 - if ((unsigned int)event->cpu >= nr_cpumask_bits || 827 - (event->cpu >= 0 && !cpu_online(event->cpu))) 828 - return -ENODEV; 826 + if (event->cpu >= 0) { 827 + if ((unsigned int)event->cpu >= nr_cpumask_bits) 828 + return -ENODEV; 829 + if (!cpu_online(event->cpu)) 830 + return -ENODEV; 831 + } 829 832 830 833 /* Force reset of idle/hv excludes regardless of what the 831 834 * user requested.
+135 -13
arch/s390/kernel/topology.c
··· 8 8 9 9 #include <linux/workqueue.h> 10 10 #include <linux/bootmem.h> 11 + #include <linux/uaccess.h> 12 + #include <linux/sysctl.h> 11 13 #include <linux/cpuset.h> 12 14 #include <linux/device.h> 13 15 #include <linux/export.h> ··· 31 29 #define PTF_VERTICAL (1UL) 32 30 #define PTF_CHECK (2UL) 33 31 32 + enum { 33 + TOPOLOGY_MODE_HW, 34 + TOPOLOGY_MODE_SINGLE, 35 + TOPOLOGY_MODE_PACKAGE, 36 + TOPOLOGY_MODE_UNINITIALIZED 37 + }; 38 + 34 39 struct mask_info { 35 40 struct mask_info *next; 36 41 unsigned char id; 37 42 cpumask_t mask; 38 43 }; 39 44 45 + static int topology_mode = TOPOLOGY_MODE_UNINITIALIZED; 40 46 static void set_topology_timer(void); 41 47 static void topology_work_fn(struct work_struct *work); 42 48 static struct sysinfo_15_1_x *tl_info; ··· 69 59 cpumask_t mask; 70 60 71 61 cpumask_copy(&mask, cpumask_of(cpu)); 72 - if (!MACHINE_HAS_TOPOLOGY) 73 - return mask; 74 - for (; info; info = info->next) { 75 - if (cpumask_test_cpu(cpu, &info->mask)) 76 - return info->mask; 62 + switch (topology_mode) { 63 + case TOPOLOGY_MODE_HW: 64 + while (info) { 65 + if (cpumask_test_cpu(cpu, &info->mask)) { 66 + mask = info->mask; 67 + break; 68 + } 69 + info = info->next; 70 + } 71 + if (cpumask_empty(&mask)) 72 + cpumask_copy(&mask, cpumask_of(cpu)); 73 + break; 74 + case TOPOLOGY_MODE_PACKAGE: 75 + cpumask_copy(&mask, cpu_present_mask); 76 + break; 77 + default: 78 + /* fallthrough */ 79 + case TOPOLOGY_MODE_SINGLE: 80 + cpumask_copy(&mask, cpumask_of(cpu)); 81 + break; 77 82 } 78 83 return mask; 79 84 } ··· 99 74 int i; 100 75 101 76 cpumask_copy(&mask, cpumask_of(cpu)); 102 - if (!MACHINE_HAS_TOPOLOGY) 77 + if (topology_mode != TOPOLOGY_MODE_HW) 103 78 return mask; 104 79 cpu -= cpu % (smp_cpu_mtid + 1); 105 80 for (i = 0; i <= smp_cpu_mtid; i++) ··· 209 184 { 210 185 int cpu; 211 186 212 - mutex_lock(&smp_cpu_state_mutex); 213 187 for_each_possible_cpu(cpu) 214 188 smp_cpu_set_polarization(cpu, POLARIZATION_HRZ); 215 - mutex_unlock(&smp_cpu_state_mutex); 216 189 } 217 190 218 191 static int ptf(unsigned long fc) ··· 246 223 static void update_cpu_masks(void) 247 224 { 248 225 struct cpu_topology_s390 *topo; 249 - int cpu; 226 + int cpu, id; 250 227 251 228 for_each_possible_cpu(cpu) { 252 229 topo = &cpu_topology[cpu]; ··· 254 231 topo->core_mask = cpu_group_map(&socket_info, cpu); 255 232 topo->book_mask = cpu_group_map(&book_info, cpu); 256 233 topo->drawer_mask = cpu_group_map(&drawer_info, cpu); 257 - if (!MACHINE_HAS_TOPOLOGY) { 234 + if (topology_mode != TOPOLOGY_MODE_HW) { 235 + id = topology_mode == TOPOLOGY_MODE_PACKAGE ? 0 : cpu; 258 236 topo->thread_id = cpu; 259 237 topo->core_id = cpu; 260 - topo->socket_id = cpu; 261 - topo->book_id = cpu; 262 - topo->drawer_id = cpu; 238 + topo->socket_id = id; 239 + topo->book_id = id; 240 + topo->drawer_id = id; 263 241 if (cpu_present(cpu)) 264 242 cpumask_set_cpu(cpu, &cpus_with_topology); 265 243 } ··· 278 254 struct sysinfo_15_1_x *info = tl_info; 279 255 int rc = 0; 280 256 257 + mutex_lock(&smp_cpu_state_mutex); 281 258 cpumask_clear(&cpus_with_topology); 282 259 if (MACHINE_HAS_TOPOLOGY) { 283 260 rc = 1; ··· 288 263 update_cpu_masks(); 289 264 if (!MACHINE_HAS_TOPOLOGY) 290 265 topology_update_polarization_simple(); 266 + mutex_unlock(&smp_cpu_state_mutex); 291 267 return rc; 292 268 } 293 269 ··· 313 287 void topology_schedule_update(void) 314 288 { 315 289 schedule_work(&topology_work); 290 + } 291 + 292 + static void topology_flush_work(void) 293 + { 294 + flush_work(&topology_work); 316 295 } 317 296 318 297 static void topology_timer_fn(unsigned long ignored) ··· 490 459 struct sysinfo_15_1_x *info; 491 460 492 461 set_sched_topology(s390_topology); 462 + if (topology_mode == TOPOLOGY_MODE_UNINITIALIZED) { 463 + if (MACHINE_HAS_TOPOLOGY) 464 + topology_mode = TOPOLOGY_MODE_HW; 465 + else 466 + topology_mode = TOPOLOGY_MODE_SINGLE; 467 + } 493 468 if (!MACHINE_HAS_TOPOLOGY) 494 469 goto out; 495 470 tl_info = memblock_virt_alloc(PAGE_SIZE, PAGE_SIZE); ··· 511 474 __arch_update_cpu_topology(); 512 475 } 513 476 477 + static inline int topology_get_mode(int enabled) 478 + { 479 + if (!enabled) 480 + return TOPOLOGY_MODE_SINGLE; 481 + return MACHINE_HAS_TOPOLOGY ? TOPOLOGY_MODE_HW : TOPOLOGY_MODE_PACKAGE; 482 + } 483 + 484 + static inline int topology_is_enabled(void) 485 + { 486 + return topology_mode != TOPOLOGY_MODE_SINGLE; 487 + } 488 + 489 + static int __init topology_setup(char *str) 490 + { 491 + bool enabled; 492 + int rc; 493 + 494 + rc = kstrtobool(str, &enabled); 495 + if (rc) 496 + return rc; 497 + topology_mode = topology_get_mode(enabled); 498 + return 0; 499 + } 500 + early_param("topology", topology_setup); 501 + 502 + static int topology_ctl_handler(struct ctl_table *ctl, int write, 503 + void __user *buffer, size_t *lenp, loff_t *ppos) 504 + { 505 + unsigned int len; 506 + int new_mode; 507 + char buf[2]; 508 + 509 + if (!*lenp || *ppos) { 510 + *lenp = 0; 511 + return 0; 512 + } 513 + if (!write) { 514 + strncpy(buf, topology_is_enabled() ? "1\n" : "0\n", 515 + ARRAY_SIZE(buf)); 516 + len = strnlen(buf, ARRAY_SIZE(buf)); 517 + if (len > *lenp) 518 + len = *lenp; 519 + if (copy_to_user(buffer, buf, len)) 520 + return -EFAULT; 521 + goto out; 522 + } 523 + len = *lenp; 524 + if (copy_from_user(buf, buffer, len > sizeof(buf) ? sizeof(buf) : len)) 525 + return -EFAULT; 526 + if (buf[0] != '0' && buf[0] != '1') 527 + return -EINVAL; 528 + mutex_lock(&smp_cpu_state_mutex); 529 + new_mode = topology_get_mode(buf[0] == '1'); 530 + if (topology_mode != new_mode) { 531 + topology_mode = new_mode; 532 + topology_schedule_update(); 533 + } 534 + mutex_unlock(&smp_cpu_state_mutex); 535 + topology_flush_work(); 536 + out: 537 + *lenp = len; 538 + *ppos += len; 539 + return 0; 540 + } 541 + 542 + static struct ctl_table topology_ctl_table[] = { 543 + { 544 + .procname = "topology", 545 + .mode = 0644, 546 + .proc_handler = topology_ctl_handler, 547 + }, 548 + { }, 549 + }; 550 + 551 + static struct ctl_table topology_dir_table[] = { 552 + { 553 + .procname = "s390", 554 + .maxlen = 0, 555 + .mode = 0555, 556 + .child = topology_ctl_table, 557 + }, 558 + { }, 559 + }; 560 + 514 561 static int __init topology_init(void) 515 562 { 516 563 if (MACHINE_HAS_TOPOLOGY) 517 564 set_topology_timer(); 518 565 else 519 566 topology_update_polarization_simple(); 567 + register_sysctl_table(topology_dir_table); 520 568 return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); 521 569 } 522 570 device_initcall(topology_init);
+3 -4
arch/s390/mm/gup.c
··· 56 56 static inline int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, 57 57 unsigned long end, int write, struct page **pages, int *nr) 58 58 { 59 - unsigned long mask, result; 60 59 struct page *head, *page; 60 + unsigned long mask; 61 61 int refs; 62 62 63 - result = write ? 0 : _SEGMENT_ENTRY_PROTECT; 64 - mask = result | _SEGMENT_ENTRY_INVALID; 65 - if ((pmd_val(pmd) & mask) != result) 63 + mask = (write ? _SEGMENT_ENTRY_PROTECT : 0) | _SEGMENT_ENTRY_INVALID; 64 + if ((pmd_val(pmd) & mask) != 0) 66 65 return 0; 67 66 VM_BUG_ON(!pfn_valid(pmd_val(pmd) >> PAGE_SHIFT)); 68 67
+9 -3
drivers/s390/block/dasd.c
··· 1644 1644 dasd_schedule_device_bh(device); 1645 1645 if (device->block) { 1646 1646 dasd_schedule_block_bh(device->block); 1647 - blk_mq_run_hw_queues(device->block->request_queue, true); 1647 + if (device->block->request_queue) 1648 + blk_mq_run_hw_queues(device->block->request_queue, 1649 + true); 1648 1650 } 1649 1651 } 1650 1652 EXPORT_SYMBOL_GPL(dasd_generic_handle_state_change); ··· 3761 3759 dasd_schedule_device_bh(device); 3762 3760 if (device->block) { 3763 3761 dasd_schedule_block_bh(device->block); 3764 - blk_mq_run_hw_queues(device->block->request_queue, true); 3762 + if (device->block->request_queue) 3763 + blk_mq_run_hw_queues(device->block->request_queue, 3764 + true); 3765 3765 } 3766 3766 3767 3767 if (!device->stopped) ··· 4029 4025 4030 4026 if (device->block) { 4031 4027 dasd_schedule_block_bh(device->block); 4032 - blk_mq_run_hw_queues(device->block->request_queue, true); 4028 + if (device->block->request_queue) 4029 + blk_mq_run_hw_queues(device->block->request_queue, 4030 + true); 4033 4031 } 4034 4032 4035 4033 clear_bit(DASD_FLAG_SUSPENDED, &device->flags);
+3 -3
drivers/s390/block/scm_blk.c
··· 249 249 static void scm_request_finish(struct scm_request *scmrq) 250 250 { 251 251 struct scm_blk_dev *bdev = scmrq->bdev; 252 - int *error; 252 + blk_status_t *error; 253 253 int i; 254 254 255 255 for (i = 0; i < nr_requests_per_io && scmrq->request[i]; i++) { ··· 415 415 416 416 static void scm_blk_request_done(struct request *req) 417 417 { 418 - int *error = blk_mq_rq_to_pdu(req); 418 + blk_status_t *error = blk_mq_rq_to_pdu(req); 419 419 420 420 blk_mq_end_request(req, *error); 421 421 } ··· 450 450 atomic_set(&bdev->queued_reqs, 0); 451 451 452 452 bdev->tag_set.ops = &scm_mq_ops; 453 - bdev->tag_set.cmd_size = sizeof(int); 453 + bdev->tag_set.cmd_size = sizeof(blk_status_t); 454 454 bdev->tag_set.nr_hw_queues = nr_requests; 455 455 bdev->tag_set.queue_depth = nr_requests_per_io * nr_requests; 456 456 bdev->tag_set.flags = BLK_MQ_F_SHOULD_MERGE;
+9 -3
drivers/s390/cio/device.c
··· 1225 1225 static int recovery_check(struct device *dev, void *data) 1226 1226 { 1227 1227 struct ccw_device *cdev = to_ccwdev(dev); 1228 + struct subchannel *sch; 1228 1229 int *redo = data; 1229 1230 1230 1231 spin_lock_irq(cdev->ccwlock); 1231 1232 switch (cdev->private->state) { 1233 + case DEV_STATE_ONLINE: 1234 + sch = to_subchannel(cdev->dev.parent); 1235 + if ((sch->schib.pmcw.pam & sch->opm) == sch->vpm) 1236 + break; 1237 + /* fall through */ 1232 1238 case DEV_STATE_DISCONNECTED: 1233 1239 CIO_MSG_EVENT(3, "recovery: trigger 0.%x.%04x\n", 1234 1240 cdev->private->dev_id.ssid, ··· 1266 1260 } 1267 1261 spin_unlock_irq(&recovery_lock); 1268 1262 } else 1269 - CIO_MSG_EVENT(4, "recovery: end\n"); 1263 + CIO_MSG_EVENT(3, "recovery: end\n"); 1270 1264 } 1271 1265 1272 1266 static DECLARE_WORK(recovery_work, recovery_work_func); ··· 1280 1274 schedule_work(&recovery_work); 1281 1275 } 1282 1276 1283 - static void ccw_device_schedule_recovery(void) 1277 + void ccw_device_schedule_recovery(void) 1284 1278 { 1285 1279 unsigned long flags; 1286 1280 1287 - CIO_MSG_EVENT(4, "recovery: schedule\n"); 1281 + CIO_MSG_EVENT(3, "recovery: schedule\n"); 1288 1282 spin_lock_irqsave(&recovery_lock, flags); 1289 1283 if (!timer_pending(&recovery_timer) || (recovery_phase != 0)) { 1290 1284 recovery_phase = 0;
+1
drivers/s390/cio/device.h
··· 134 134 void ccw_device_set_notoper(struct ccw_device *cdev); 135 135 136 136 void ccw_device_set_timeout(struct ccw_device *, int); 137 + void ccw_device_schedule_recovery(void); 137 138 138 139 /* Channel measurement facility related */ 139 140 void retry_set_schib(struct ccw_device *cdev);
+12
drivers/s390/cio/device_fsm.c
··· 476 476 } 477 477 } 478 478 479 + static void ccw_device_handle_broken_paths(struct ccw_device *cdev) 480 + { 481 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 482 + u8 broken_paths = (sch->schib.pmcw.pam & sch->opm) ^ sch->vpm; 483 + 484 + if (broken_paths && (cdev->private->path_broken_mask != broken_paths)) 485 + ccw_device_schedule_recovery(); 486 + 487 + cdev->private->path_broken_mask = broken_paths; 488 + } 489 + 479 490 void ccw_device_verify_done(struct ccw_device *cdev, int err) 480 491 { 481 492 struct subchannel *sch; ··· 519 508 memset(&cdev->private->irb, 0, sizeof(struct irb)); 520 509 } 521 510 ccw_device_report_path_events(cdev); 511 + ccw_device_handle_broken_paths(cdev); 522 512 break; 523 513 case -ETIME: 524 514 case -EUSERS:
+2
drivers/s390/cio/io_sch.h
··· 131 131 not operable */ 132 132 u8 path_gone_mask; /* mask of paths, that became unavailable */ 133 133 u8 path_new_mask; /* mask of paths, that became available */ 134 + u8 path_broken_mask; /* mask of paths, which were found to be 135 + unusable */ 134 136 struct { 135 137 unsigned int fast:1; /* post with "channel end" */ 136 138 unsigned int repall:1; /* report every interrupt status */