lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-id: <000001cd4eb5$9af113b0$d0d33b10$%jun@samsung.com>
Date:	Wed, 20 Jun 2012 16:23:35 +0900
From:	Seungwon Jeon <tgih.jun@...sung.com>
To:	'Namjae Jeon' <linkinjeon@...il.com>, merez@...eaurora.org,
	'Chris Ball' <cjb@...top.org>
Cc:	linux-mmc@...r.kernel.org, linux-kernel@...r.kernel.org,
	'Chris Ball' <cjb@...top.org>,
	'Subhash Jadavani' <subhashj@...eaurora.org>,
	"'S, Venkatraman'" <svenkatr@...com>
Subject: RE: [PATCH RESEND v7 3/3] mmc: core: Support packed read command for
 eMMC4.5 device

We have already shared the result of packed read. Currently there is no benefit with packed read.
It would be better to examine more if we can test the improved device for packed read.
I'll check over this patch for improvement.
Thanks to constant reviews.

Hi Chris,
Could you check the following two patches for merging?
[PATCH RESEND v7 1/3] mmc: core: Add packed command feature of eMMC4.5
[PATCH RESEND v7 2/3] mmc: core: Support packed write command for eMMC4.5 device

Best regards,
Seungwon Jeon

Namjae Jeon <linkinjeon@...il.com> wrote:
> 2012/6/19, merez@...eaurora.org <merez@...eaurora.org>:
> > Hi Namjae,
> >
> > We have seen that read packing causes degradation to read performance and
> > also got reports for the same from card vendors.
> > When vendors will improve this feature and it will be proven to be
> > beneficial we can open the discussion on it again.
> > Until then, there is no point in merging a massive amount of code that
> > will be disabled.
> 
> Okay, I agree about big changing. As I know, packed read speed on
> sequecial read is better than original. random read is not. because of
> overhead of header sector tranfering and error checking.
> 
> Hi. Seungwon.
> When you measure packed read performance using lmdd, Is there any
> improved performance ?
> 
> Thanks.
> 
> >
> > Thanks,
> > Maya
> > On Mon, June 18, 2012 7:22 am, Namjae Jeon wrote:
> >> 2012/6/18  <merez@...eaurora.org>:
> >>> I would prefer that you didn't submit this.
> >>> Let's wait with packed read until it is proven to be beneficial.
> >> Hi. Merez.
> >> I have reported packed read speed issue was because of firmware of mmc
> >> card before.
> >> And host can select packed read and write cmd by each performance.
> >> mmc vendors willl be considering to improve packed read cmd.
> >>
> >> Reviewed-by: Namjae Jeon <linkinjeon@...il.com>
> >>
> >> Thanks.
> >>>
> >>> Thanks,
> >>> Maya
> >>> On Sun, June 17, 2012 10:46 pm, Seungwon Jeon wrote:
> >>>> Add the packed read command for issuing data. Unlike the
> >>>> packed write, command header is handled separately.
> >>>>
> >>>> Signed-off-by: Seungwon Jeon <tgih.jun@...sung.com>
> >>>> ---
> >>>>  drivers/mmc/card/block.c |  134
> >>>> +++++++++++++++++++++++++++++++++++++++++++---
> >>>>  drivers/mmc/card/queue.c |    6 ++-
> >>>>  drivers/mmc/card/queue.h |    2 +
> >>>>  3 files changed, 133 insertions(+), 9 deletions(-)
> >>>>
> >>>> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
> >>>> index eb99e35..25f42e8 100644
> >>>> --- a/drivers/mmc/card/block.c
> >>>> +++ b/drivers/mmc/card/block.c
> >>>> @@ -62,6 +62,7 @@ MODULE_ALIAS("mmc:block");
> >>>>                       (req->cmd_flags & REQ_META)) && \
> >>>>                       (rq_data_dir(req) == WRITE))
> >>>>  #define PACKED_CMD_VER               0x01
> >>>> +#define PACKED_CMD_RD                0x01
> >>>>  #define PACKED_CMD_WR                0x02
> >>>>
> >>>>  static DEFINE_MUTEX(block_mutex);
> >>>> @@ -104,6 +105,7 @@ struct mmc_blk_data {
> >>>>  #define MMC_BLK_WRITE                BIT(1)
> >>>>  #define MMC_BLK_DISCARD              BIT(2)
> >>>>  #define MMC_BLK_SECDISCARD   BIT(3)
> >>>> +#define MMC_BLK_WR_HDR               BIT(4)
> >>>>
> >>>>       /*
> >>>>        * Only set in main mmc_blk_data associated
> >>>> @@ -1062,7 +1064,8 @@ static int mmc_blk_err_check(struct mmc_card
> >>>> *card,
> >>>>        * kind.  If it was a write, we may have transitioned to
> >>>>        * program mode, which we have to wait for it to complete.
> >>>>        */
> >>>> -     if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) {
> >>>> +     if ((!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ)
> >>>> ||
> >>>> +                     (mq_mrq->packed_cmd ==
> >>>> MMC_PACKED_WR_HDR)) {
> >>>>               u32 status;
> >>>>               do {
> >>>>                       int err = get_card_status(card,
> >>>> &status, 5);
> >>>> @@ -1087,7 +1090,8 @@ static int mmc_blk_err_check(struct mmc_card
> >>>> *card,
> >>>>                      (unsigned)blk_rq_sectors(req),
> >>>>                      brq->cmd.resp[0], brq->stop.resp[0]);
> >>>>
> >>>> -             if (rq_data_dir(req) == READ) {
> >>>> +             if (rq_data_dir(req) == READ &&
> >>>> +                             mq_mrq->packed_cmd !=
> >>>> MMC_PACKED_WR_HDR) {
> >>>>                       if (ecc_err)
> >>>>                               return MMC_BLK_ECC_ERR;
> >>>>                       return MMC_BLK_DATA_ERR;
> >>>> @@ -1330,6 +1334,9 @@ static u8 mmc_blk_prep_packed_list(struct
> >>>> mmc_queue
> >>>> *mq, struct request *req)
> >>>>       if ((rq_data_dir(cur) == WRITE) &&
> >>>>                       (card->host->caps2 &
> >>>> MMC_CAP2_PACKED_WR))
> >>>>               max_packed_rw = card->ext_csd.max_packed_writes;
> >>>> +     else if ((rq_data_dir(cur) == READ) &&
> >>>> +                     (card->host->caps2 &
> >>>> MMC_CAP2_PACKED_RD))
> >>>> +             max_packed_rw = card->ext_csd.max_packed_reads;
> >>>>
> >>>>       if (max_packed_rw == 0)
> >>>>               goto no_packed;
> >>>> @@ -1426,13 +1433,16 @@ static void mmc_blk_packed_hdr_wrq_prep(struct
> >>>> mmc_queue_req *mqrq,
> >>>>       u32 *packed_cmd_hdr = mqrq->packed_cmd_hdr;
> >>>>       u8 i = 1;
> >>>>
> >>>> -     mqrq->packed_cmd = MMC_PACKED_WRITE;
> >>>> +     mqrq->packed_cmd = (rq_data_dir(req) == READ) ?
> >>>> +             MMC_PACKED_WR_HDR : MMC_PACKED_WRITE;
> >>>>       mqrq->packed_blocks = 0;
> >>>>       mqrq->packed_fail_idx = MMC_PACKED_N_IDX;
> >>>>
> >>>>       memset(packed_cmd_hdr, 0, sizeof(mqrq->packed_cmd_hdr));
> >>>>       packed_cmd_hdr[0] = (mqrq->packed_num << 16) |
> >>>> -             (PACKED_CMD_WR << 8) | PACKED_CMD_VER;
> >>>> +             (((rq_data_dir(req) == READ) ?
> >>>> +               PACKED_CMD_RD : PACKED_CMD_WR) << 8) |
> >>>> +             PACKED_CMD_VER;
> >>>>
> >>>>       /*
> >>>>        * Argument for each entry of packed group
> >>>> @@ -1464,7 +1474,8 @@ static void mmc_blk_packed_hdr_wrq_prep(struct
> >>>> mmc_queue_req *mqrq,
> >>>>       brq->mrq.stop = &brq->stop;
> >>>>
> >>>>       brq->sbc.opcode = MMC_SET_BLOCK_COUNT;
> >>>> -     brq->sbc.arg = MMC_CMD23_ARG_PACKED | (mqrq->packed_blocks +
> >>>> 1);
> >>>> +     brq->sbc.arg = MMC_CMD23_ARG_PACKED |
> >>>> +             ((rq_data_dir(req) == READ) ? 1 :
> >>>> mqrq->packed_blocks + 1);
> >>>>       brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
> >>>>
> >>>>       brq->cmd.opcode = MMC_WRITE_MULTIPLE_BLOCK;
> >>>> @@ -1474,7 +1485,12 @@ static void mmc_blk_packed_hdr_wrq_prep(struct
> >>>> mmc_queue_req *mqrq,
> >>>>       brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
> >>>>
> >>>>       brq->data.blksz = 512;
> >>>> -     brq->data.blocks = mqrq->packed_blocks + 1;
> >>>> +     /*
> >>>> +      * Write separately the packd command header only for packed
> >>>> read.
> >>>> +      * In case of packed write, header is sent with blocks of
> >>>> data.
> >>>> +      */
> >>>> +     brq->data.blocks = (rq_data_dir(req) == READ) ?
> >>>> +             1 : mqrq->packed_blocks + 1;
> >>>>       brq->data.flags |= MMC_DATA_WRITE;
> >>>>
> >>>>       brq->stop.opcode = MMC_STOP_TRANSMISSION;
> >>>> @@ -1487,6 +1503,45 @@ static void mmc_blk_packed_hdr_wrq_prep(struct
> >>>> mmc_queue_req *mqrq,
> >>>>       brq->data.sg_len = mmc_queue_map_sg(mq, mqrq);
> >>>>
> >>>>       mqrq->mmc_active.mrq = &brq->mrq;
> >>>> +     mqrq->mmc_active.err_check = (rq_data_dir(req) == READ) ?
> >>>> +             mmc_blk_err_check : mmc_blk_packed_err_check;
> >>>> +
> >>>> +     mmc_queue_bounce_pre(mqrq);
> >>>> +}
> >>>> +
> >>>> +static void mmc_blk_packed_rrq_prep(struct mmc_queue_req *mqrq,
> >>>> +                                 struct mmc_card
> >>>> *card,
> >>>> +                                 struct mmc_queue *mq)
> >>>> +{
> >>>> +     struct mmc_blk_request *brq = &mqrq->brq;
> >>>> +     struct request *req = mqrq->req;
> >>>> +
> >>>> +     mqrq->packed_cmd = MMC_PACKED_READ;
> >>>> +
> >>>> +     memset(brq, 0, sizeof(struct mmc_blk_request));
> >>>> +     brq->mrq.cmd = &brq->cmd;
> >>>> +     brq->mrq.data = &brq->data;
> >>>> +     brq->mrq.stop = &brq->stop;
> >>>> +
> >>>> +     brq->cmd.opcode = MMC_READ_MULTIPLE_BLOCK;
> >>>> +     brq->cmd.arg = blk_rq_pos(req);
> >>>> +     if (!mmc_card_blockaddr(card))
> >>>> +             brq->cmd.arg <<= 9;
> >>>> +     brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
> >>>> +     brq->data.blksz = 512;
> >>>> +     brq->data.blocks = mqrq->packed_blocks;
> >>>> +     brq->data.flags |= MMC_DATA_READ;
> >>>> +
> >>>> +     brq->stop.opcode = MMC_STOP_TRANSMISSION;
> >>>> +     brq->stop.arg = 0;
> >>>> +     brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
> >>>> +
> >>>> +     mmc_set_data_timeout(&brq->data, card);
> >>>> +
> >>>> +     brq->data.sg = mqrq->sg;
> >>>> +     brq->data.sg_len = mmc_queue_map_sg(mq, mqrq);
> >>>> +
> >>>> +     mqrq->mmc_active.mrq = &brq->mrq;
> >>>>       mqrq->mmc_active.err_check = mmc_blk_packed_err_check;
> >>>>
> >>>>       mmc_queue_bounce_pre(mqrq);
> >>>> @@ -1521,6 +1576,56 @@ static int mmc_blk_cmd_err(struct mmc_blk_data
> >>>> *md,
> >>>> struct mmc_card *card,
> >>>>       return ret;
> >>>>  }
> >>>>
> >>>> +static int mmc_blk_chk_hdr_err(struct mmc_queue *mq, int status)
> >>>> +{
> >>>> +     struct mmc_blk_data *md = mq->data;
> >>>> +     struct mmc_card *card = md->queue.card;
> >>>> +     int type = MMC_BLK_WR_HDR, err = 0;
> >>>> +
> >>>> +     switch (status) {
> >>>> +     case MMC_BLK_PARTIAL:
> >>>> +     case MMC_BLK_RETRY:
> >>>> +             err = 0;
> >>>> +             break;
> >>>> +     case MMC_BLK_CMD_ERR:
> >>>> +     case MMC_BLK_ABORT:
> >>>> +     case MMC_BLK_DATA_ERR:
> >>>> +     case MMC_BLK_ECC_ERR:
> >>>> +             err = mmc_blk_reset(md, card->host, type);
> >>>> +             if (!err)
> >>>> +                     mmc_blk_reset_success(md, type);
> >>>> +             break;
> >>>> +     }
> >>>> +
> >>>> +     return err;
> >>>> +}
> >>>> +
> >>>> +static int mmc_blk_issue_packed_rd(struct mmc_queue *mq,
> >>>> +                                struct mmc_queue_req
> >>>> *mq_rq)
> >>>> +{
> >>>> +     struct mmc_blk_data *md = mq->data;
> >>>> +     struct mmc_card *card = md->queue.card;
> >>>> +     int status, ret, retry = 2;
> >>>> +
> >>>> +     do {
> >>>> +             mmc_start_req(card->host, NULL, (int *) &status);
> >>>> +             if (status) {
> >>>> +                     ret = mmc_blk_chk_hdr_err(mq, status);
> >>>> +                     if (ret)
> >>>> +                             break;
> >>>> +                     mmc_blk_packed_hdr_wrq_prep(mq_rq,
> >>>> card, mq);
> >>>> +                     mmc_start_req(card->host,
> >>>> &mq_rq->mmc_active, NULL);
> >>>> +             } else {
> >>>> +                     mmc_blk_packed_rrq_prep(mq_rq, card,
> >>>> mq);
> >>>> +                     mmc_start_req(card->host,
> >>>> &mq_rq->mmc_active, NULL);
> >>>> +                     ret = 0;
> >>>> +                     break;
> >>>> +             }
> >>>> +     } while (retry-- > 0);
> >>>> +
> >>>> +     return ret;
> >>>> +}
> >>>> +
> >>>>  static int mmc_blk_end_packed_req(struct mmc_queue_req *mq_rq)
> >>>>  {
> >>>>       struct request *prq;
> >>>> @@ -1626,8 +1731,12 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue
> >>>> *mq, struct request *rqc)
> >>>>               } else
> >>>>                       areq = NULL;
> >>>>               areq = mmc_start_req(card->host, areq, (int *)
> >>>> &status);
> >>>> -             if (!areq)
> >>>> -                     return 0;
> >>>> +             if (!areq) {
> >>>> +                     if (mq->mqrq_cur->packed_cmd ==
> >>>> MMC_PACKED_WR_HDR)
> >>>> +                             goto snd_packed_rd;
> >>>> +                     else
> >>>> +                             return 0;
> >>>> +             }
> >>>>
> >>>>               mq_rq = container_of(areq, struct mmc_queue_req,
> >>>> mmc_active);
> >>>>               brq = &mq_rq->brq;
> >>>> @@ -1726,10 +1835,19 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue
> >>>> *mq, struct request *rqc)
> >>>>
> >>>> mmc_blk_packed_hdr_wrq_prep(mq_rq, card, mq);
> >>>>                               mmc_start_req(card->host,
> >>>>
> >>>> &mq_rq->mmc_active, NULL);
> >>>> +                             if (mq_rq->packed_cmd ==
> >>>> MMC_PACKED_WR_HDR) {
> >>>> +                                     if
> >>>> (mmc_blk_issue_packed_rd(mq, mq_rq))
> >>>> +
> >>>> goto cmd_abort;
> >>>> +                             }
> >>>>                       }
> >>>>               }
> >>>>       } while (ret);
> >>>>
> >>>> +snd_packed_rd:
> >>>> +     if (mq->mqrq_cur->packed_cmd == MMC_PACKED_WR_HDR) {
> >>>> +             if (mmc_blk_issue_packed_rd(mq, mq->mqrq_cur))
> >>>> +                     goto start_new_req;
> >>>> +     }
> >>>>       return 1;
> >>>>
> >>>>   cmd_abort:
> >>>> diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
> >>>> index 165d85a..277905e 100644
> >>>> --- a/drivers/mmc/card/queue.c
> >>>> +++ b/drivers/mmc/card/queue.c
> >>>> @@ -389,11 +389,15 @@ static unsigned int
> >>>> mmc_queue_packed_map_sg(struct
> >>>> mmc_queue *mq,
> >>>>
> >>>>       cmd = mqrq->packed_cmd;
> >>>>
> >>>> -     if (cmd == MMC_PACKED_WRITE) {
> >>>> +     if (cmd == MMC_PACKED_WR_HDR || cmd == MMC_PACKED_WRITE) {
> >>>>               __sg = sg;
> >>>>               sg_set_buf(__sg, mqrq->packed_cmd_hdr,
> >>>>
> >>>> sizeof(mqrq->packed_cmd_hdr));
> >>>>               sg_len++;
> >>>> +             if (cmd == MMC_PACKED_WR_HDR) {
> >>>> +                     sg_mark_end(__sg);
> >>>> +                     return sg_len;
> >>>> +             }
> >>>>               __sg->page_link &= ~0x02;
> >>>>       }
> >>>>
> >>>> diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
> >>>> index 5e04938..a8cad1f 100644
> >>>> --- a/drivers/mmc/card/queue.h
> >>>> +++ b/drivers/mmc/card/queue.h
> >>>> @@ -14,7 +14,9 @@ struct mmc_blk_request {
> >>>>
> >>>>  enum mmc_packed_cmd {
> >>>>       MMC_PACKED_NONE = 0,
> >>>> +     MMC_PACKED_WR_HDR,
> >>>>       MMC_PACKED_WRITE,
> >>>> +     MMC_PACKED_READ,
> >>>>  };
> >>>>
> >>>>  struct mmc_queue_req {
> >>>> --
> >>>> 1.7.0.4
> >>>>
> >>>>
> >>>>
> >>>
> >>>
> >>> --
> >>> Sent by consultant of Qualcomm Innovation Center, Inc.
> >>> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
> >>>
> >>> --
> >>> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> >>> the body of a message to majordomo@...r.kernel.org
> >>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> >>
> >
> >
> > --
> > Sent by consultant of Qualcomm Innovation Center, Inc.
> > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
> >
> >
> --
> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ