From c94dec99f9759c41cadf0f2781846da5b40a98f6 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 4 Dec 2007 16:09:01 +0100 Subject: [PATCH 1/5] [S390] cio: Issue SenseID per path. We may receive a unit check for every path when we issue a SenseID. Unfortunately, the channel subsystem will try on a different path every time if we use a lpm of 0xff, which will exhaust our retry counter. Therefore, revert SenseID to its previous per-path behaviour and just leave out the suspend multipath reconnect. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/device_id.c | 37 +++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 2f6bf462425e..156f3f9786b5 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -113,6 +113,7 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) { struct subchannel *sch; struct ccw1 *ccw; + int ret; sch = to_subchannel(cdev->dev.parent); /* Setup sense channel program. */ @@ -124,9 +125,25 @@ __ccw_device_sense_id_start(struct ccw_device *cdev) /* Reset device status. */ memset(&cdev->private->irb, 0, sizeof(struct irb)); - cdev->private->flags.intretry = 0; - return cio_start(sch, ccw, LPM_ANYPATH); + /* Try on every path. */ + ret = -ENODEV; + while (cdev->private->imask != 0) { + if ((sch->opm & cdev->private->imask) != 0 && + cdev->private->iretry > 0) { + cdev->private->iretry--; + /* Reset internal retry indication. */ + cdev->private->flags.intretry = 0; + ret = cio_start (sch, cdev->private->iccws, + cdev->private->imask); + /* ret is 0, -EBUSY, -EACCES or -ENODEV */ + if (ret != -EACCES) + return ret; + } + cdev->private->imask >>= 1; + cdev->private->iretry = 5; + } + return ret; } void @@ -136,7 +153,8 @@ ccw_device_sense_id_start(struct ccw_device *cdev) memset (&cdev->private->senseid, 0, sizeof (struct senseid)); cdev->private->senseid.cu_type = 0xFFFF; - cdev->private->iretry = 3; + cdev->private->imask = 0x80; + cdev->private->iretry = 5; ret = __ccw_device_sense_id_start(cdev); if (ret && ret != -EBUSY) ccw_device_sense_id_done(cdev, ret); @@ -252,13 +270,14 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) ccw_device_sense_id_done(cdev, ret); break; case -EACCES: /* channel is not operational. */ + sch->lpm &= ~cdev->private->imask; + cdev->private->imask >>= 1; + cdev->private->iretry = 5; + /* fall through. */ case -EAGAIN: /* try again. */ - cdev->private->iretry--; - if (cdev->private->iretry > 0) { - ret = __ccw_device_sense_id_start(cdev); - if (ret == 0 || ret == -EBUSY) - break; - } + ret = __ccw_device_sense_id_start(cdev); + if (ret == 0 || ret == -EBUSY) + break; /* fall through. */ default: /* Sense ID failed. Try asking VM. */ if (MACHINE_IS_VM) { From 671756162cfb0b3ccbb6a0047baa3010885561a2 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Tue, 4 Dec 2007 16:09:02 +0100 Subject: [PATCH 2/5] [S390] cio: add missing reprobe loop end statement Add loop end statement to prevent looping over empty subchannel sets. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/css.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 6db31089d2d7..c3df2cd009a4 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -451,6 +451,7 @@ static int reprobe_subchannel(struct subchannel_id schid, void *data) break; case -ENXIO: case -ENOMEM: + case -EIO: /* These should abort looping */ break; default: From 436d1bc7fe6e78e37fe5f5022ea4d5c133d825eb Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 4 Dec 2007 16:09:03 +0100 Subject: [PATCH 3/5] [S390] dcssblk: prevent early access without own make_request function When loading a dcss segment with the dcssblk driver, sometimes the following kind of message appears: bio too big device dcssblk0 (8 > 0) Buffer I/O error on device dcssblk0, logical block 172016 .. The fix is to move the disk registration after setting the make_request function, to avoid calls into generic_make_request for dcssblock without having the make_request function set up properly. Cc: Gerald Schaefer Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- drivers/s390/block/dcssblk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 5e083d1f57e7..15a5789b7734 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -472,11 +472,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char if (rc) goto unregister_dev; - add_disk(dev_info->gd); - blk_queue_make_request(dev_info->dcssblk_queue, dcssblk_make_request); blk_queue_hardsect_size(dev_info->dcssblk_queue, 4096); + add_disk(dev_info->gd); + switch (dev_info->segment_type) { case SEG_TYPE_SR: case SEG_TYPE_ER: From ab1809b4ed9a3aaf3b34133a776a94f9fad54cc4 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 4 Dec 2007 16:09:04 +0100 Subject: [PATCH 4/5] [S390] Fix compile error on 31bit without preemption Commit b8e7a54cd06b0b0174029ef3a7f5a1415a2c28f2 introduced a compile error if CONFIG_PREEMPT is not set: arch/s390/kernel/built-in.o: In function `cleanup_io_leave_insn': /space/kvm/arch/s390/kernel/entry.S:(.text+0xbfce): undefined reference to `preempt_schedule_irq' This patch hides preempt_schedule_irq if CONFIG_PREEMPT is not set. Signed-off-by: Christian Borntraeger Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/entry.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index b2b2edc40eb1..1a6dac8df6fb 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -1079,8 +1079,10 @@ cleanup_io_leave_insn: .Lexecve_tail: .long execve_tail .Ljump_table: .long pgm_check_table .Lschedule: .long schedule +#ifdef CONFIG_PREEMPT .Lpreempt_schedule_irq: .long preempt_schedule_irq +#endif .Ltrace: .long syscall_trace .Lschedtail: .long schedule_tail .Lsysc_table: .long sys_call_table From 7af0d6f753f5adf773f99470666b50490d3379f1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 4 Dec 2007 16:09:05 +0100 Subject: [PATCH 5/5] [S390] Make sure the restore psw masks are initialized. In case of TRACE_IRQFLAGS the restore psw masks will not be initialized if noexec is turned on. This will lead to an immediate system crash. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 50f8f1e3760e..577aa7dd660e 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -486,9 +486,7 @@ static void setup_addressing_mode(void) if (s390_noexec) { printk("S390 execute protection active, "); set_amode_and_uaccess(PSW_ASC_SECONDARY, PSW32_ASC_SECONDARY); - return; - } - if (switch_amode) { + } else if (switch_amode) { printk("S390 address spaces switched, "); set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY); }