On 10 May 2017 at 10:24, Linus Walleij <linus.walleij@xxxxxxxxxx> wrote: > This switches also the multiple-command ioctl() call to issue > all ioctl()s through the block layer instead of going directly > to the device. > > We extend the passed argument with an argument count and loop > over all passed commands in the ioctl() issue function called > from the block layer. > > By doing this we are again loosening the grip on the big host > lock, since two calls to mmc_get_card()/mmc_put_card() are > removed. > > Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> I have reviewed the series and it looks good to me. Some minor nitpicks was all I found, please address them then we can apply this. Kind regards Uffe > --- > drivers/mmc/core/block.c | 38 +++++++++++++++++++++++++------------- > drivers/mmc/core/queue.h | 3 ++- > 2 files changed, 27 insertions(+), 14 deletions(-) > > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c > index 640db4f57a31..152de904d5e4 100644 > --- a/drivers/mmc/core/block.c > +++ b/drivers/mmc/core/block.c > @@ -563,6 +563,7 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, > struct mmc_ioc_cmd __user *ic_ptr) > { > struct mmc_blk_ioc_data *idata; > + struct mmc_blk_ioc_data *idatas[1]; > struct mmc_blk_data *md; > struct mmc_queue *mq; > struct mmc_card *card; > @@ -600,7 +601,9 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, > req = blk_get_request(mq->queue, > idata->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, > __GFP_RECLAIM); > - req_to_mq_rq(req)->idata = idata; > + idatas[0] = idata; > + req_to_mq_rq(req)->idata = idatas; > + req_to_mq_rq(req)->ioc_count = 1; > blk_execute_rq(mq->queue, NULL, req, 0); > ioc_err = req_to_mq_rq(req)->ioc_result; > err = mmc_blk_ioctl_copy_to_user(ic_ptr, idata); > @@ -622,14 +625,17 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, > static void mmc_blk_ioctl_cmd_issue(struct mmc_queue *mq, struct request *req) > { > struct mmc_queue_req *mq_rq; > - struct mmc_blk_ioc_data *idata; > struct mmc_card *card = mq->card; > struct mmc_blk_data *md = mq->blkdata; > int ioc_err; > + int i; > > mq_rq = req_to_mq_rq(req); > - idata = mq_rq->idata; > - ioc_err = __mmc_blk_ioctl_cmd(card, md, idata); > + for (i = 0; i < mq_rq->ioc_count; i++) { > + ioc_err = __mmc_blk_ioctl_cmd(card, md, mq_rq->idata[i]); > + if (ioc_err) > + break; > + } > mq_rq->ioc_result = ioc_err; > > /* Always switch back to main area after RPMB access */ > @@ -646,8 +652,10 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, > struct mmc_ioc_cmd __user *cmds = user->cmds; > struct mmc_card *card; > struct mmc_blk_data *md; > + struct mmc_queue *mq; > int i, err = 0, ioc_err = 0; > __u64 num_of_cmds; > + struct request *req; > > /* > * The caller must have CAP_SYS_RAWIO, and must be calling this on the > @@ -689,21 +697,25 @@ static int mmc_blk_ioctl_multi_cmd(struct block_device *bdev, > goto cmd_done; > } > > - mmc_get_card(card); > - > - for (i = 0; i < num_of_cmds && !ioc_err; i++) > - ioc_err = __mmc_blk_ioctl_cmd(card, md, idata[i]); > - > - /* Always switch back to main area after RPMB access */ > - if (md->area_type & MMC_BLK_DATA_AREA_RPMB) > - mmc_blk_part_switch(card, dev_get_drvdata(&card->dev)); > > - mmc_put_card(card); > + /* > + * Dispatch the ioctl()s into the block request queue. > + */ > + mq = &md->queue; > + req = blk_get_request(mq->queue, > + idata[0]->ic.write_flag ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, > + __GFP_RECLAIM); > + req_to_mq_rq(req)->idata = idata; > + req_to_mq_rq(req)->ioc_count = num_of_cmds; > + blk_execute_rq(mq->queue, NULL, req, 0); > + ioc_err = req_to_mq_rq(req)->ioc_result; > > /* copy to user if data and response */ > for (i = 0; i < num_of_cmds && !err; i++) > err = mmc_blk_ioctl_copy_to_user(&cmds[i], idata[i]); > > + blk_put_request(req); > + > cmd_done: > mmc_blk_put(md); > cmd_err: > diff --git a/drivers/mmc/core/queue.h b/drivers/mmc/core/queue.h > index aeb3408dc85e..7015df6681c3 100644 > --- a/drivers/mmc/core/queue.h > +++ b/drivers/mmc/core/queue.h > @@ -42,7 +42,8 @@ struct mmc_queue_req { > unsigned int bounce_sg_len; > struct mmc_async_req areq; > int ioc_result; > - struct mmc_blk_ioc_data *idata; > + struct mmc_blk_ioc_data **idata; > + unsigned int ioc_count; > }; > > struct mmc_queue { > -- > 2.9.3 >