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

[S390] ccwreq: add ability to use all paths

Change the ccwrequest infrastructure to use more than one channel
path per start I/O. A flag "singlepath" is added to struct
ccw_request - if set, the old behavior is used. This flag is set
for all exploiters of the ccwrequest infrastructure - so there
is no functional change through this patch.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Sebastian Ott and committed by
Martin Schwidefsky
982bdf81 7cd40314

+22 -7
+11 -3
drivers/s390/cio/ccwreq.c
··· 38 38 { 39 39 struct ccw_request *req = &cdev->private->req; 40 40 41 + if (!req->singlepath) { 42 + req->mask = 0; 43 + goto out; 44 + } 41 45 req->retries = req->maxretries; 42 46 req->mask = lpm_adjust(req->mask >>= 1, req->lpm); 43 - 47 + out: 44 48 return req->mask; 45 49 } 46 50 ··· 117 113 { 118 114 struct ccw_request *req = &cdev->private->req; 119 115 120 - /* Try all paths twice to counter link flapping. */ 121 - req->mask = 0x8080; 116 + if (req->singlepath) { 117 + /* Try all paths twice to counter link flapping. */ 118 + req->mask = 0x8080; 119 + } else 120 + req->mask = req->lpm; 121 + 122 122 req->retries = req->maxretries; 123 123 req->mask = lpm_adjust(req->mask, req->lpm); 124 124 req->drc = 0;
+1
drivers/s390/cio/device_id.c
··· 216 216 req->timeout = SENSE_ID_TIMEOUT; 217 217 req->maxretries = SENSE_ID_RETRIES; 218 218 req->lpm = sch->schib.pmcw.pam & sch->opm; 219 + req->singlepath = 1; 219 220 req->check = snsid_check; 220 221 req->callback = snsid_callback; 221 222 ccw_request_start(cdev);
+4
drivers/s390/cio/device_pgid.c
··· 208 208 req->timeout = PGID_TIMEOUT; 209 209 req->maxretries = PGID_RETRIES; 210 210 req->lpm = 0x80; 211 + req->singlepath = 1; 211 212 req->callback = spid_callback; 212 213 spid_do(cdev); 213 214 } ··· 421 420 req->timeout = PGID_TIMEOUT; 422 421 req->maxretries = PGID_RETRIES; 423 422 req->lpm = 0x80; 423 + req->singlepath = 1; 424 424 if (cdev->private->flags.pgroup) { 425 425 CIO_TRACE_EVENT(4, "snid"); 426 426 CIO_HEX_EVENT(4, devid, sizeof(*devid)); ··· 509 507 req->timeout = PGID_TIMEOUT; 510 508 req->maxretries = PGID_RETRIES; 511 509 req->lpm = sch->schib.pmcw.pam & sch->opm; 510 + req->singlepath = 1; 512 511 req->callback = disband_callback; 513 512 fn = SPID_FUNC_DISBAND; 514 513 if (cdev->private->flags.mpath) ··· 563 560 req->timeout = PGID_TIMEOUT; 564 561 req->maxretries = PGID_RETRIES; 565 562 req->lpm = sch->schib.pmcw.pam & sch->opm; 563 + req->singlepath = 1; 566 564 req->data = data; 567 565 req->callback = stlck_callback; 568 566 stlck_build_cp(cdev, buf1, buf2);
+6 -4
drivers/s390/cio/io_sch.h
··· 92 92 * @filter: optional callback to adjust request status based on IRB data 93 93 * @callback: final callback 94 94 * @data: user-defined pointer passed to all callbacks 95 + * @singlepath: if set, use only one path from @lpm per start I/O 96 + * @cancel: non-zero if request was cancelled 97 + * @done: non-zero if request was finished 95 98 * @mask: current path mask 96 99 * @retries: current number of retries 97 100 * @drc: delayed return code 98 - * @cancel: non-zero if request was cancelled 99 - * @done: non-zero if request was finished 100 101 */ 101 102 struct ccw_request { 102 103 struct ccw1 *cp; ··· 109 108 enum io_status); 110 109 void (*callback)(struct ccw_device *, void *, int); 111 110 void *data; 111 + unsigned int singlepath:1; 112 112 /* These fields are used internally. */ 113 + unsigned int cancel:1; 114 + unsigned int done:1; 113 115 u16 mask; 114 116 u16 retries; 115 117 int drc; 116 - int cancel:1; 117 - int done:1; 118 118 } __attribute__((packed)); 119 119 120 120 /*