Message ID | 20200714200327.40927-2-sth@linux.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | DASD DIAG patches | expand |
On 7/14/20 2:03 PM, Stefan Haberland wrote: > During initialization of the DASD DIAG driver a request is issued > that has a bio structure that resides on the stack. With virtually > mapped kernel stacks this bio address might be in virtual storage > which is unsuitable for usage with the diag250 call. > In this case the device can not be set online using the DIAG > discipline and fails with -EOPNOTSUP. > In the system journal the following error message is presented: > > dasd: X.X.XXXX Setting the DASD online with discipline DIAG failed > with rc=-95 > > Fix by allocating the bio structure instead of having it on the stack. > > Fixes: ce3dc447493f ("s390: add support for virtually mapped kernel stacks") > Cc: stable@vger.kernel.org #4.20 > Signed-off-by: Stefan Haberland <sth@linux.ibm.com> > Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> > --- > drivers/s390/block/dasd_diag.c | 25 +++++++++++++++++-------- > 1 file changed, 17 insertions(+), 8 deletions(-) > > diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c > index facb588d09e4..069d6b39cacf 100644 > --- a/drivers/s390/block/dasd_diag.c > +++ b/drivers/s390/block/dasd_diag.c > @@ -319,7 +319,7 @@ dasd_diag_check_device(struct dasd_device *device) > struct dasd_diag_characteristics *rdc_data; > struct vtoc_cms_label *label; > struct dasd_block *block; > - struct dasd_diag_bio bio; > + struct dasd_diag_bio *bio; > unsigned int sb, bsize; > blocknum_t end_block; > int rc; > @@ -395,29 +395,36 @@ dasd_diag_check_device(struct dasd_device *device) > rc = -ENOMEM; > goto out; > } > + bio = kzalloc(sizeof(*bio), GFP_KERNEL); > + if (bio == NULL) { > + DBF_DEV_EVENT(DBF_WARNING, device, "%s", > + "No memory to allocate initialization bio"); > + rc = -ENOMEM; > + goto out_label; > + } Just curious, any reason this isn't just using bio_alloc()?
On Tue, Jul 14, 2020 at 02:12:27PM -0600, Jens Axboe wrote:
> Just curious, any reason this isn't just using bio_alloc()?
The dasd_diag_bio doesn't seem to have anything to do with the
block layer struct bio..
Am 15.07.20 um 08:48 schrieb Christoph Hellwig: > On Tue, Jul 14, 2020 at 02:12:27PM -0600, Jens Axboe wrote: >> Just curious, any reason this isn't just using bio_alloc()? > The dasd_diag_bio doesn't seem to have anything to do with the > block layer struct bio.. exactly, that's a struct dasd_diag_bio.
On 7/15/20 7:32 AM, Stefan Haberland wrote: > Am 15.07.20 um 08:48 schrieb Christoph Hellwig: >> On Tue, Jul 14, 2020 at 02:12:27PM -0600, Jens Axboe wrote: >>> Just curious, any reason this isn't just using bio_alloc()? >> The dasd_diag_bio doesn't seem to have anything to do with the >> block layer struct bio.. > > exactly, that's a struct dasd_diag_bio. Duh, guess I should have looked a bit more closely...
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index facb588d09e4..069d6b39cacf 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -319,7 +319,7 @@ dasd_diag_check_device(struct dasd_device *device) struct dasd_diag_characteristics *rdc_data; struct vtoc_cms_label *label; struct dasd_block *block; - struct dasd_diag_bio bio; + struct dasd_diag_bio *bio; unsigned int sb, bsize; blocknum_t end_block; int rc; @@ -395,29 +395,36 @@ dasd_diag_check_device(struct dasd_device *device) rc = -ENOMEM; goto out; } + bio = kzalloc(sizeof(*bio), GFP_KERNEL); + if (bio == NULL) { + DBF_DEV_EVENT(DBF_WARNING, device, "%s", + "No memory to allocate initialization bio"); + rc = -ENOMEM; + goto out_label; + } rc = 0; end_block = 0; /* try all sizes - needed for ECKD devices */ for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) { mdsk_init_io(device, bsize, 0, &end_block); - memset(&bio, 0, sizeof (struct dasd_diag_bio)); - bio.type = MDSK_READ_REQ; - bio.block_number = private->pt_block + 1; - bio.buffer = label; + memset(bio, 0, sizeof(*bio)); + bio->type = MDSK_READ_REQ; + bio->block_number = private->pt_block + 1; + bio->buffer = label; memset(&private->iob, 0, sizeof (struct dasd_diag_rw_io)); private->iob.dev_nr = rdc_data->dev_nr; private->iob.key = 0; private->iob.flags = 0; /* do synchronous io */ private->iob.block_count = 1; private->iob.interrupt_params = 0; - private->iob.bio_list = &bio; + private->iob.bio_list = bio; private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; rc = dia250(&private->iob, RW_BIO); if (rc == 3) { pr_warn("%s: A 64-bit DIAG call failed\n", dev_name(&device->cdev->dev)); rc = -EOPNOTSUPP; - goto out_label; + goto out_bio; } mdsk_term_io(device); if (rc == 0) @@ -427,7 +434,7 @@ dasd_diag_check_device(struct dasd_device *device) pr_warn("%s: Accessing the DASD failed because of an incorrect format (rc=%d)\n", dev_name(&device->cdev->dev), rc); rc = -EIO; - goto out_label; + goto out_bio; } /* check for label block */ if (memcmp(label->label_id, DASD_DIAG_CMS1, @@ -457,6 +464,8 @@ dasd_diag_check_device(struct dasd_device *device) (rc == 4) ? ", read-only device" : ""); rc = 0; } +out_bio: + kfree(bio); out_label: free_page((long) label); out: