1. 20 6月, 2017 3 次提交
    • L
      mmc: block: move single ioctl() commands to block requests · 614f0388
      Linus Walleij 提交于
      This wraps single ioctl() commands into block requests using
      the custom block layer request types REQ_OP_DRV_IN and
      REQ_OP_DRV_OUT.
      
      By doing this we are loosening the grip on the big host lock,
      since two calls to mmc_get_card()/mmc_put_card() are removed.
      
      We are storing the ioctl() in/out argument as a pointer in
      the per-request struct mmc_blk_request container. Since we
      now let the block layer allocate this data, blk_get_request()
      will allocate it for us and we can immediately dereference
      it and use it to pass the argument into the block layer.
      
      We refactor the if/else/if/else ladder in mmc_blk_issue_rq()
      as part of the job, keeping some extra attention to the
      case when a NULL req is passed into this function and
      making that pipeline flush more explicit.
      
      Tested on the ux500 with the userspace:
      mmc extcsd read /dev/mmcblk3
      resulting in a successful EXTCSD info dump back to the
      console.
      
      This commit fixes a starvation issue in the MMC/SD stack
      that can be easily provoked in the following way by
      issueing the following commands in sequence:
      
      > dd if=/dev/mmcblk3 of=/dev/null bs=1M &
      > mmc extcs read /dev/mmcblk3
      
      Before this patch, the extcsd read command would hang
      (starve) while waiting for the dd command to finish since
      the block layer was holding the card/host lock.
      
      After this patch, the extcsd ioctl() command is nicely
      interpersed with the rest of the block commands and we
      can issue a bunch of ioctl()s from userspace while there
      is some busy block IO going on without any problems.
      
      Conversely userspace ioctl()s can no longer starve
      the block layer by holding the card/host lock.
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      Tested-by: NAvri Altman <Avri.Altman@sandisk.com>
      614f0388
    • L
      mmc: block: Tag is_rpmb as bool · 829043c4
      Linus Walleij 提交于
      The variable is_rpmb is clearly a bool and even assigned true
      and false, yet declared as an int.
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      829043c4
    • L
      mmc: core: Allocate per-request data using the block layer core · 304419d8
      Linus Walleij 提交于
      The mmc_queue_req is a per-request state container the MMC core uses
      to carry bounce buffers, pointers to asynchronous requests and so on.
      Currently allocated as a static array of objects, then as a request
      comes in, a mmc_queue_req is assigned to it, and used during the
      lifetime of the request.
      
      This is backwards compared to how other block layer drivers work:
      they usally let the block core provide a per-request struct that get
      allocated right beind the struct request, and which can be obtained
      using the blk_mq_rq_to_pdu() helper. (The _mq_ infix in this function
      name is misleading: it is used by both the old and the MQ block
      layer.)
      
      The per-request struct gets allocated to the size stored in the queue
      variable .cmd_size initialized using the .init_rq_fn() and
      cleaned up using .exit_rq_fn().
      
      The block layer code makes the MMC core rely on this mechanism to
      allocate the per-request mmc_queue_req state container.
      
      Doing this make a lot of complicated queue handling go away. We only
      need to keep the .qnct that keeps count of how many request are
      currently being processed by the MMC layer. The MQ block layer will
      replace also this once we transition to it.
      
      Doing this refactoring is necessary to move the ioctl() operations
      into custom block layer requests tagged with REQ_OP_DRV_[IN|OUT]
      instead of the custom code using the BigMMCHostLock that we have
      today: those require that per-request data be obtainable easily from
      a request after creating a custom request with e.g.:
      
      struct request *rq = blk_get_request(q, REQ_OP_DRV_IN, __GFP_RECLAIM);
      struct mmc_queue_req *mq_rq = req_to_mq_rq(rq);
      
      And this is not possible with the current construction, as the request
      is not immediately assigned the per-request state container, but
      instead it gets assigned when the request finally enters the MMC
      queue, which is way too late for custom requests.
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      [Ulf: Folded in the fix to drop a call to blk_cleanup_queue()]
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      Tested-by: NHeiner Kallweit <hkallweit1@gmail.com>
      304419d8
  2. 25 4月, 2017 6 次提交
  3. 16 3月, 2017 1 次提交
  4. 15 3月, 2017 2 次提交
  5. 15 2月, 2017 3 次提交
  6. 14 2月, 2017 2 次提交
    • L
      mmc: block: respect bool returned from blk_end_request() · 0e65f10c
      Linus Walleij 提交于
      The return value from blk_end_request() is a bool but is
      treated like an int. This is generally safe, but the variable
      also has the opaque name "ret" and gets returned from the
      helper function mmc_blk_cmd_err().
      
      - Switch the variable to a bool, applies everywhere.
      
      - Return a bool from mmc_blk_cmd_err() and rename the function
        mmc_blk_rw_cmd_err() to indicate through the namespace that
        this is a helper for mmc_blk_issue_rw_rq().
      
      - Rename the variable from "ret" to "req_pending" inside the
        while() loop inside mmc_blk_issue_rq_rq(), which finally
        makes it very clear what this while loop is waiting for.
      
      - Augment the argument "ret" to mmc_blk_rq_cmd_err() to
        old_req_pending so it becomes evident that this is an
        older state, and it is returned only if we fail to get
        the number of written blocks from an SD card in the
        function mmc_sd_num_wr_blocks().
      
      - Augment the while() loop in mmc_blk_rq_cmd_abort(): it
        is evident now that we know this is a bool variable,
        that the function is just spinning waiting for
        blk_end_request() to return false.
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      0e65f10c
    • L
      mmc: block: return errorcode from mmc_sd_num_wr_blocks() · 169f03a0
      Linus Walleij 提交于
      mmc_sd_num_wr_blocks() has an interesting construction that
      saves one return argument by casting (u32)-1 as error code
      if something goes wrong.
      
      This is however a bit confusing when the normal kernel
      pattern is to return an int error code on success.
      
      So instead pass a variable "blocks" that the function can
      fill in with the number of successfully transferred blocks
      and return an integer as error code.
      Signed-off-by: NLinus Walleij <linus.walleij@linaro.org>
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      [Ulf: Changed a return code to -EIO, reported by Dan Carpenter and fixed
      by Linus Walleij]
      169f03a0
  7. 13 2月, 2017 19 次提交
  8. 25 12月, 2016 1 次提交
  9. 12 12月, 2016 1 次提交
    • U
      mmc: block: Move files to core · f397c8d8
      Ulf Hansson 提交于
      Once upon a time it made sense to keep the mmc block device driver and its
      related code, in its own directory called card. Over time, more an more
      functions/structures have become shared through generic mmc header files,
      between the core and the card directory. In other words, the relationship
      between them has become closer.
      
      By sharing functions/structures via generic header files, it becomes easy
      for outside users to abuse them. In a way to avoid that from happen, let's
      move the files from card directory into the core directory, as it enables
      us to move definitions of functions/structures into mmc core specific
      header files.
      
      Note, this is only the first step in providing a cleaner mmc interface for
      outside users. Following changes will do the actual cleanup, as that is not
      part of this change.
      Signed-off-by: NUlf Hansson <ulf.hansson@linaro.org>
      Reviewed-by: NLinus Walleij <linus.walleij@linaro.org>
      f397c8d8
  10. 05 12月, 2016 2 次提交