From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.3 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C563C433ED for ; Sun, 2 May 2021 11:42:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0790B61244 for ; Sun, 2 May 2021 11:42:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230354AbhEBLnO (ORCPT ); Sun, 2 May 2021 07:43:14 -0400 Received: from mx2.suse.de ([195.135.220.15]:43016 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230120AbhEBLnO (ORCPT ); Sun, 2 May 2021 07:43:14 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id B57AEAD22; Sun, 2 May 2021 11:42:21 +0000 (UTC) Subject: Re: [RFC PATCH v4 22/27] qedn: Add IO level nvme_req and fw_cq workqueues To: Shai Malin , netdev@vger.kernel.org, linux-nvme@lists.infradead.org, sagi@grimberg.me, hch@lst.de, axboe@fb.com, kbusch@kernel.org Cc: "David S . Miller davem @ davemloft . net --cc=Jakub Kicinski" , aelior@marvell.com, mkalderon@marvell.com, okulkarni@marvell.com, pkushwaha@marvell.com, malin1024@gmail.com References: <20210429190926.5086-1-smalin@marvell.com> <20210429190926.5086-23-smalin@marvell.com> From: Hannes Reinecke Message-ID: <42912221-29b4-e97a-bec0-9d8eec2c97fa@suse.de> Date: Sun, 2 May 2021 13:42:20 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <20210429190926.5086-23-smalin@marvell.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On 4/29/21 9:09 PM, Shai Malin wrote: > This patch will present the IO level workqueues: > > - qedn_nvme_req_fp_wq(): process new requests, similar to > nvme_tcp_io_work(). The flow starts from > send_req() and will aggregate all the requests > on this CPU core. > > - qedn_fw_cq_fp_wq(): process new FW completions, the flow starts from > the IRQ handler and for a single interrupt it will > process all the pending NVMeoF Completions under > polling mode. > > Acked-by: Igor Russkikh > Signed-off-by: Prabhakar Kushwaha > Signed-off-by: Omkar Kulkarni > Signed-off-by: Michal Kalderon > Signed-off-by: Ariel Elior > Signed-off-by: Shai Malin > --- > drivers/nvme/hw/qedn/Makefile | 2 +- > drivers/nvme/hw/qedn/qedn.h | 29 +++++++ > drivers/nvme/hw/qedn/qedn_conn.c | 3 + > drivers/nvme/hw/qedn/qedn_main.c | 114 +++++++++++++++++++++++-- > drivers/nvme/hw/qedn/qedn_task.c | 138 +++++++++++++++++++++++++++++++ > 5 files changed, 278 insertions(+), 8 deletions(-) > create mode 100644 drivers/nvme/hw/qedn/qedn_task.c > > diff --git a/drivers/nvme/hw/qedn/Makefile b/drivers/nvme/hw/qedn/Makefile > index d8b343afcd16..c7d838a61ae6 100644 > --- a/drivers/nvme/hw/qedn/Makefile > +++ b/drivers/nvme/hw/qedn/Makefile > @@ -1,4 +1,4 @@ > # SPDX-License-Identifier: GPL-2.0-only > > obj-$(CONFIG_NVME_QEDN) += qedn.o > -qedn-y := qedn_main.o qedn_conn.o > +qedn-y := qedn_main.o qedn_conn.o qedn_task.o > \ No newline at end of file > diff --git a/drivers/nvme/hw/qedn/qedn.h b/drivers/nvme/hw/qedn/qedn.h > index c15cac37ec1e..bd9a250cb2f5 100644 > --- a/drivers/nvme/hw/qedn/qedn.h > +++ b/drivers/nvme/hw/qedn/qedn.h > @@ -47,6 +47,9 @@ > #define QEDN_NON_ABORTIVE_TERMINATION 0 > #define QEDN_ABORTIVE_TERMINATION 1 > > +#define QEDN_FW_CQ_FP_WQ_WORKQUEUE "qedn_fw_cq_fp_wq" > +#define QEDN_NVME_REQ_FP_WQ_WORKQUEUE "qedn_nvme_req_fp_wq" > + > /* > * TCP offload stack default configurations and defines. > * Future enhancements will allow controlling the configurable > @@ -100,6 +103,7 @@ struct qedn_fp_queue { > struct qedn_ctx *qedn; > struct qed_sb_info *sb_info; > unsigned int cpu; > + struct work_struct fw_cq_fp_wq_entry; > u16 sb_id; > char irqname[QEDN_IRQ_NAME_LEN]; > }; > @@ -131,6 +135,8 @@ struct qedn_ctx { > struct qedn_fp_queue *fp_q_arr; > struct nvmetcp_glbl_queue_entry *fw_cq_array_virt; > dma_addr_t fw_cq_array_phy; /* Physical address of fw_cq_array_virt */ > + struct workqueue_struct *nvme_req_fp_wq; > + struct workqueue_struct *fw_cq_fp_wq; > }; > > struct qedn_endpoint { > @@ -213,6 +219,25 @@ struct qedn_ctrl { > > /* Connection level struct */ > struct qedn_conn_ctx { > + /* IO path */ > + struct workqueue_struct *nvme_req_fp_wq; /* ptr to qedn->nvme_req_fp_wq */ > + struct nvme_tcp_ofld_req *req; /* currently proccessed request */ > + > + struct list_head host_pend_req_list; > + /* Spinlock to access pending request list */ > + spinlock_t nvme_req_lock; > + unsigned int cpu; > + > + /* Entry for registering to nvme_req_fp_wq */ > + struct work_struct nvme_req_fp_wq_entry; > + /* > + * Spinlock for accessing qedn_process_req as it can be called > + * from multiple place like queue_rq, async, self requeued > + */ > + struct mutex nvme_req_mutex; > + struct qedn_fp_queue *fp_q; > + int qid; > + > struct qedn_ctx *qedn; > struct nvme_tcp_ofld_queue *queue; > struct nvme_tcp_ofld_ctrl *ctrl; > @@ -280,5 +305,9 @@ int qedn_wait_for_conn_est(struct qedn_conn_ctx *conn_ctx); > int qedn_set_con_state(struct qedn_conn_ctx *conn_ctx, enum qedn_conn_state new_state); > void qedn_terminate_connection(struct qedn_conn_ctx *conn_ctx, int abrt_flag); > __be16 qedn_get_in_port(struct sockaddr_storage *sa); > +inline int qedn_validate_cccid_in_range(struct qedn_conn_ctx *conn_ctx, u16 cccid); > +void qedn_queue_request(struct qedn_conn_ctx *qedn_conn, struct nvme_tcp_ofld_req *req); > +void qedn_nvme_req_fp_wq_handler(struct work_struct *work); > +void qedn_io_work_cq(struct qedn_ctx *qedn, struct nvmetcp_fw_cqe *cqe); > > #endif /* _QEDN_H_ */ > diff --git a/drivers/nvme/hw/qedn/qedn_conn.c b/drivers/nvme/hw/qedn/qedn_conn.c > index 9bfc0a5f0cdb..90d8aa36d219 100644 > --- a/drivers/nvme/hw/qedn/qedn_conn.c > +++ b/drivers/nvme/hw/qedn/qedn_conn.c > @@ -385,6 +385,9 @@ static int qedn_prep_and_offload_queue(struct qedn_conn_ctx *conn_ctx) > } > > set_bit(QEDN_CONN_RESRC_FW_SQ, &conn_ctx->resrc_state); > + INIT_LIST_HEAD(&conn_ctx->host_pend_req_list); > + spin_lock_init(&conn_ctx->nvme_req_lock); > + > rc = qed_ops->acquire_conn(qedn->cdev, > &conn_ctx->conn_handle, > &conn_ctx->fw_cid, > diff --git a/drivers/nvme/hw/qedn/qedn_main.c b/drivers/nvme/hw/qedn/qedn_main.c > index 8b5714e7e2bb..38f23dbb03a5 100644 > --- a/drivers/nvme/hw/qedn/qedn_main.c > +++ b/drivers/nvme/hw/qedn/qedn_main.c > @@ -267,6 +267,18 @@ static int qedn_release_ctrl(struct nvme_tcp_ofld_ctrl *ctrl) > return 0; > } > > +static void qedn_set_ctrl_io_cpus(struct qedn_conn_ctx *conn_ctx, int qid) > +{ > + struct qedn_ctx *qedn = conn_ctx->qedn; > + struct qedn_fp_queue *fp_q = NULL; > + int index; > + > + index = qid ? (qid - 1) % qedn->num_fw_cqs : 0; > + fp_q = &qedn->fp_q_arr[index]; > + > + conn_ctx->cpu = fp_q->cpu; > +} > + > static int qedn_create_queue(struct nvme_tcp_ofld_queue *queue, int qid, size_t q_size) > { > struct nvme_tcp_ofld_ctrl *ctrl = queue->ctrl; > @@ -288,6 +300,7 @@ static int qedn_create_queue(struct nvme_tcp_ofld_queue *queue, int qid, size_t > conn_ctx->queue = queue; > conn_ctx->ctrl = ctrl; > conn_ctx->sq_depth = q_size; > + qedn_set_ctrl_io_cpus(conn_ctx, qid); > > init_waitqueue_head(&conn_ctx->conn_waitq); > atomic_set(&conn_ctx->est_conn_indicator, 0); > @@ -295,6 +308,10 @@ static int qedn_create_queue(struct nvme_tcp_ofld_queue *queue, int qid, size_t > > spin_lock_init(&conn_ctx->conn_state_lock); > > + INIT_WORK(&conn_ctx->nvme_req_fp_wq_entry, qedn_nvme_req_fp_wq_handler); > + conn_ctx->nvme_req_fp_wq = qedn->nvme_req_fp_wq; > + conn_ctx->qid = qid; > + > qedn_initialize_endpoint(&conn_ctx->ep, qedn->local_mac_addr, > &ctrl->conn_params); > > @@ -356,6 +373,7 @@ static void qedn_destroy_queue(struct nvme_tcp_ofld_queue *queue) > if (!conn_ctx) > return; > > + cancel_work_sync(&conn_ctx->nvme_req_fp_wq_entry); > qedn_terminate_connection(conn_ctx, QEDN_ABORTIVE_TERMINATION); > > qedn_queue_wait_for_terminate_complete(conn_ctx); > @@ -385,12 +403,24 @@ static int qedn_init_req(struct nvme_tcp_ofld_req *req) > > static void qedn_commit_rqs(struct nvme_tcp_ofld_queue *queue) > { > - /* Placeholder - queue work */ > + struct qedn_conn_ctx *conn_ctx; > + > + conn_ctx = (struct qedn_conn_ctx *)queue->private_data; > + > + if (!list_empty(&conn_ctx->host_pend_req_list)) > + queue_work_on(conn_ctx->cpu, conn_ctx->nvme_req_fp_wq, > + &conn_ctx->nvme_req_fp_wq_entry); > } > > static int qedn_send_req(struct nvme_tcp_ofld_req *req) > { > - /* Placeholder - qedn_send_req */ > + struct qedn_conn_ctx *qedn_conn = (struct qedn_conn_ctx *)req->queue->private_data; > + > + /* Under the assumption that the cccid/tag will be in the range of 0 to sq_depth-1. */ > + if (!req->async && qedn_validate_cccid_in_range(qedn_conn, req->rq->tag)) > + return BLK_STS_NOTSUPP; > + > + qedn_queue_request(qedn_conn, req); > > return 0; > } > @@ -434,9 +464,59 @@ struct qedn_conn_ctx *qedn_get_conn_hash(struct qedn_ctx *qedn, u16 icid) > } > > /* Fastpath IRQ handler */ > +void qedn_fw_cq_fp_handler(struct qedn_fp_queue *fp_q) > +{ > + u16 sb_id, cq_prod_idx, cq_cons_idx; > + struct qedn_ctx *qedn = fp_q->qedn; > + struct nvmetcp_fw_cqe *cqe = NULL; > + > + sb_id = fp_q->sb_id; > + qed_sb_update_sb_idx(fp_q->sb_info); > + > + /* rmb - to prevent missing new cqes */ > + rmb(); > + > + /* Read the latest cq_prod from the SB */ > + cq_prod_idx = *fp_q->cq_prod; > + cq_cons_idx = qed_chain_get_cons_idx(&fp_q->cq_chain); > + > + while (cq_cons_idx != cq_prod_idx) { > + cqe = qed_chain_consume(&fp_q->cq_chain); > + if (likely(cqe)) > + qedn_io_work_cq(qedn, cqe); > + else > + pr_err("Failed consuming cqe\n"); > + > + cq_cons_idx = qed_chain_get_cons_idx(&fp_q->cq_chain); > + > + /* Check if new completions were posted */ > + if (unlikely(cq_prod_idx == cq_cons_idx)) { > + /* rmb - to prevent missing new cqes */ > + rmb(); > + > + /* Update the latest cq_prod from the SB */ > + cq_prod_idx = *fp_q->cq_prod; > + } > + } > +} > + > +static void qedn_fw_cq_fq_wq_handler(struct work_struct *work) > +{ > + struct qedn_fp_queue *fp_q = container_of(work, struct qedn_fp_queue, fw_cq_fp_wq_entry); > + > + qedn_fw_cq_fp_handler(fp_q); > + qed_sb_ack(fp_q->sb_info, IGU_INT_ENABLE, 1); > +} > + > static irqreturn_t qedn_irq_handler(int irq, void *dev_id) > { > - /* Placeholder */ > + struct qedn_fp_queue *fp_q = dev_id; > + struct qedn_ctx *qedn = fp_q->qedn; > + > + fp_q->cpu = smp_processor_id(); > + > + qed_sb_ack(fp_q->sb_info, IGU_INT_DISABLE, 0); > + queue_work_on(fp_q->cpu, qedn->fw_cq_fp_wq, &fp_q->fw_cq_fp_wq_entry); > > return IRQ_HANDLED; > } > @@ -584,6 +664,11 @@ static void qedn_free_function_queues(struct qedn_ctx *qedn) > int i; > > /* Free workqueues */ > + destroy_workqueue(qedn->fw_cq_fp_wq); > + qedn->fw_cq_fp_wq = NULL; > + > + destroy_workqueue(qedn->nvme_req_fp_wq); > + qedn->nvme_req_fp_wq = NULL; > > /* Free the fast path queues*/ > for (i = 0; i < qedn->num_fw_cqs; i++) { > @@ -651,7 +736,23 @@ static int qedn_alloc_function_queues(struct qedn_ctx *qedn) > u64 cq_phy_addr; > int i; > > - /* Place holder - IO-path workqueues */ > + qedn->fw_cq_fp_wq = alloc_workqueue(QEDN_FW_CQ_FP_WQ_WORKQUEUE, > + WQ_HIGHPRI | WQ_MEM_RECLAIM, 0); > + if (!qedn->fw_cq_fp_wq) { > + rc = -ENODEV; > + pr_err("Unable to create fastpath FW CQ workqueue!\n"); > + > + return rc; > + } > + > + qedn->nvme_req_fp_wq = alloc_workqueue(QEDN_NVME_REQ_FP_WQ_WORKQUEUE, > + WQ_HIGHPRI | WQ_MEM_RECLAIM, 1); > + if (!qedn->nvme_req_fp_wq) { > + rc = -ENODEV; > + pr_err("Unable to create fastpath qedn nvme workqueue!\n"); > + > + return rc; > + } > > qedn->fp_q_arr = kcalloc(qedn->num_fw_cqs, > sizeof(struct qedn_fp_queue), GFP_KERNEL); Why don't you use threaded interrupts if you're spinning off a workqueue for handling interrupts anyway? > @@ -679,7 +780,7 @@ static int qedn_alloc_function_queues(struct qedn_ctx *qedn) > chain_params.mode = QED_CHAIN_MODE_PBL, > chain_params.cnt_type = QED_CHAIN_CNT_TYPE_U16, > chain_params.num_elems = QEDN_FW_CQ_SIZE; > - chain_params.elem_size = 64; /*Placeholder - sizeof(struct nvmetcp_fw_cqe)*/ > + chain_params.elem_size = sizeof(struct nvmetcp_fw_cqe); > > rc = qed_ops->common->chain_alloc(qedn->cdev, > &fp_q->cq_chain, > @@ -708,8 +809,7 @@ static int qedn_alloc_function_queues(struct qedn_ctx *qedn) > sb = fp_q->sb_info->sb_virt; > fp_q->cq_prod = (u16 *)&sb->pi_array[QEDN_PROTO_CQ_PROD_IDX]; > fp_q->qedn = qedn; > - > - /* Placeholder - Init IO-path workqueue */ > + INIT_WORK(&fp_q->fw_cq_fp_wq_entry, qedn_fw_cq_fq_wq_handler); > > /* Placeholder - Init IO-path resources */ > } > diff --git a/drivers/nvme/hw/qedn/qedn_task.c b/drivers/nvme/hw/qedn/qedn_task.c > new file mode 100644 > index 000000000000..d3474188efdc > --- /dev/null > +++ b/drivers/nvme/hw/qedn/qedn_task.c > @@ -0,0 +1,138 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Copyright 2021 Marvell. All rights reserved. > + */ > + > +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > + > + /* Kernel includes */ > +#include > + > +/* Driver includes */ > +#include "qedn.h" > + > +inline int qedn_validate_cccid_in_range(struct qedn_conn_ctx *conn_ctx, u16 cccid) > +{ > + int rc = 0; > + > + if (unlikely(cccid >= conn_ctx->sq_depth)) { > + pr_err("cccid 0x%x out of range ( > sq depth)\n", cccid); > + rc = -EINVAL; > + } > + > + return rc; > +} > + > +static bool qedn_process_req(struct qedn_conn_ctx *qedn_conn) > +{ > + return true; > +} > + > +/* The WQ handler can be call from 3 flows: > + * 1. queue_rq. > + * 2. async. > + * 3. self requeued > + * Try to send requests from the pending list. If a request proccess has failed, > + * re-register to the workqueue. > + * If there are no additional pending requests - exit the handler. > + */ > +void qedn_nvme_req_fp_wq_handler(struct work_struct *work) > +{ > + struct qedn_conn_ctx *qedn_conn; > + bool more = false; > + > + qedn_conn = container_of(work, struct qedn_conn_ctx, nvme_req_fp_wq_entry); > + do { > + if (mutex_trylock(&qedn_conn->nvme_req_mutex)) { > + more = qedn_process_req(qedn_conn); > + qedn_conn->req = NULL; > + mutex_unlock(&qedn_conn->nvme_req_mutex); > + } > + } while (more); > + > + if (!list_empty(&qedn_conn->host_pend_req_list)) > + queue_work_on(qedn_conn->cpu, qedn_conn->nvme_req_fp_wq, > + &qedn_conn->nvme_req_fp_wq_entry); > +} > + > +void qedn_queue_request(struct qedn_conn_ctx *qedn_conn, struct nvme_tcp_ofld_req *req) > +{ > + bool empty, res = false; > + > + spin_lock(&qedn_conn->nvme_req_lock); > + empty = list_empty(&qedn_conn->host_pend_req_list) && !qedn_conn->req; > + list_add_tail(&req->queue_entry, &qedn_conn->host_pend_req_list); > + spin_unlock(&qedn_conn->nvme_req_lock); > + > + /* attempt workqueue bypass */ > + if (qedn_conn->cpu == smp_processor_id() && empty && > + mutex_trylock(&qedn_conn->nvme_req_mutex)) { > + res = qedn_process_req(qedn_conn); > + qedn_conn->req = NULL; > + mutex_unlock(&qedn_conn->nvme_req_mutex); > + if (res || list_empty(&qedn_conn->host_pend_req_list)) > + return; > + } else if (req->last) { > + queue_work_on(qedn_conn->cpu, qedn_conn->nvme_req_fp_wq, > + &qedn_conn->nvme_req_fp_wq_entry); > + } > +} > + Queueing a request? Does wonders for your latency ... Can't you do without? > +struct qedn_task_ctx *qedn_cqe_get_active_task(struct nvmetcp_fw_cqe *cqe) > +{ > + struct regpair *p = &cqe->task_opaque; > + > + return (struct qedn_task_ctx *)((((u64)(le32_to_cpu(p->hi)) << 32) > + + le32_to_cpu(p->lo))); > +} > + > +void qedn_io_work_cq(struct qedn_ctx *qedn, struct nvmetcp_fw_cqe *cqe) > +{ > + struct qedn_task_ctx *qedn_task = NULL; > + struct qedn_conn_ctx *conn_ctx = NULL; > + u16 itid; > + u32 cid; > + > + conn_ctx = qedn_get_conn_hash(qedn, le16_to_cpu(cqe->conn_id)); > + if (unlikely(!conn_ctx)) { > + pr_err("CID 0x%x: Failed to fetch conn_ctx from hash\n", > + le16_to_cpu(cqe->conn_id)); > + > + return; > + } > + > + cid = conn_ctx->fw_cid; > + itid = le16_to_cpu(cqe->itid); > + qedn_task = qedn_cqe_get_active_task(cqe); > + if (unlikely(!qedn_task)) > + return; > + > + if (likely(cqe->cqe_type == NVMETCP_FW_CQE_TYPE_NORMAL)) { > + /* Placeholder - verify the connection was established */ > + > + switch (cqe->task_type) { > + case NVMETCP_TASK_TYPE_HOST_WRITE: > + case NVMETCP_TASK_TYPE_HOST_READ: > + > + /* Placeholder - IO flow */ > + > + break; > + > + case NVMETCP_TASK_TYPE_HOST_READ_NO_CQE: > + > + /* Placeholder - IO flow */ > + > + break; > + > + case NVMETCP_TASK_TYPE_INIT_CONN_REQUEST: > + > + /* Placeholder - ICReq flow */ > + > + break; > + default: > + pr_info("Could not identify task type\n"); > + } > + } else { > + /* Placeholder - Recovery flows */ > + } > +} > Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@suse.de +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 57397C433ED for ; Sun, 2 May 2021 11:42:40 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AB0D561244 for ; Sun, 2 May 2021 11:42:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AB0D561244 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvme-bounces+linux-nvme=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:Cc:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=pwGr3XPCK+XEbHu9gFmOLh6vilafWULg8Z2C4m65xqs=; b=Q+RYa+i5T+cRIcyWJ2Y7tf7eF dHD2hHefuYQu9h+m7lGf2b1MZ0ejiq9X+Fx3HeaH6D3AIjTgKfO+CFkzBuGMWrD0T/no/92EZMTWk qLpnlnvomZ7cjoHt3MK/xdQ2THDAFUKWv9Ch4gEKFtYKpTR7Df54bkYUp1SxyK2tjZi1JI5YWOwE7 pX4deXtRYDSjdB6c/gvt59XaA36VBO4Ahwl2c7mQxbQz0nDDaOt8Thu905oFGtahQ2UKhsV3Efwf8 W9asse5t/1h6i80DgnXBKnxzMDp+mHZBHo34ApbEWgYp5Pa0W/u3Mp8KrKgsB2/WLYgdaKdlHTXzS 2VxbnXThw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1ldAUb-00BhHN-39; Sun, 02 May 2021 11:42:33 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ldAUU-00BhGs-T8 for linux-nvme@desiato.infradead.org; Sun, 02 May 2021 11:42:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: Content-Type:In-Reply-To:MIME-Version:Date:Message-ID:From:References:Cc:To: Subject:Sender:Reply-To:Content-ID:Content-Description; bh=Sx6lb0Jxp5XHrhJVjEu7PssnYcbj4I40M1Aw65VhadA=; b=LLt5dow5jXciFNozVe3UJOFsrT ci8zlot+jPn+1dZZHYD8flJfyIsbgxVM66Hcy0r5LTjVDrQAXEXEblleCfdzjgQeBUBwQX21MVl35 HYmqWVE+rbel63IdBhEtzvDD1fe86hipo5rE7vRfVSMWbhm5sYfCVg02r/sj3rUxySVf3yCjPcGwR 2mwx+D8aVipdI0VSnde/Eg8b5DjIbwXL8mPdAYghbVuIXrnwJKvYB+Z/NoJIPPVQj+K9qayDZ2Eus N0egPSHD1qTI8dc7pTcJ99T2Kc8J0IxzlbURBWh2fBBDmXzZcEGewJVo/Ay1CskgAji1qECL/3hhn sUKcGxqw==; Received: from mx2.suse.de ([195.135.220.15]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ldAUR-002VYD-3E for linux-nvme@lists.infradead.org; Sun, 02 May 2021 11:42:25 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id B57AEAD22; Sun, 2 May 2021 11:42:21 +0000 (UTC) Subject: Re: [RFC PATCH v4 22/27] qedn: Add IO level nvme_req and fw_cq workqueues To: Shai Malin , netdev@vger.kernel.org, linux-nvme@lists.infradead.org, sagi@grimberg.me, hch@lst.de, axboe@fb.com, kbusch@kernel.org Cc: "David S . Miller davem @ davemloft . net --cc=Jakub Kicinski" , aelior@marvell.com, mkalderon@marvell.com, okulkarni@marvell.com, pkushwaha@marvell.com, malin1024@gmail.com References: <20210429190926.5086-1-smalin@marvell.com> <20210429190926.5086-23-smalin@marvell.com> From: Hannes Reinecke Message-ID: <42912221-29b4-e97a-bec0-9d8eec2c97fa@suse.de> Date: Sun, 2 May 2021 13:42:20 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <20210429190926.5086-23-smalin@marvell.com> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210502_044223_464711_8AECF35B X-CRM114-Status: GOOD ( 40.91 ) X-BeenThere: linux-nvme@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "Linux-nvme" Errors-To: linux-nvme-bounces+linux-nvme=archiver.kernel.org@lists.infradead.org T24gNC8yOS8yMSA5OjA5IFBNLCBTaGFpIE1hbGluIHdyb3RlOgo+IFRoaXMgcGF0Y2ggd2lsbCBw cmVzZW50IHRoZSBJTyBsZXZlbCB3b3JrcXVldWVzOgo+IAo+IC0gcWVkbl9udm1lX3JlcV9mcF93 cSgpOiBwcm9jZXNzIG5ldyByZXF1ZXN0cywgc2ltaWxhciB0bwo+IAkJCSBudm1lX3RjcF9pb193 b3JrKCkuIFRoZSBmbG93IHN0YXJ0cyBmcm9tCj4gCQkJIHNlbmRfcmVxKCkgYW5kIHdpbGwgYWdn cmVnYXRlIGFsbCB0aGUgcmVxdWVzdHMKPiAJCQkgb24gdGhpcyBDUFUgY29yZS4KPiAKPiAtIHFl ZG5fZndfY3FfZnBfd3EoKTogICBwcm9jZXNzIG5ldyBGVyBjb21wbGV0aW9ucywgdGhlIGZsb3cg c3RhcnRzIGZyb20KPiAJCQl0aGUgSVJRIGhhbmRsZXIgYW5kIGZvciBhIHNpbmdsZSBpbnRlcnJ1 cHQgaXQgd2lsbAo+IAkJCXByb2Nlc3MgYWxsIHRoZSBwZW5kaW5nIE5WTWVvRiBDb21wbGV0aW9u cyB1bmRlcgo+IAkJCXBvbGxpbmcgbW9kZS4KPiAKPiBBY2tlZC1ieTogSWdvciBSdXNza2lraCA8 aXJ1c3NraWtoQG1hcnZlbGwuY29tPgo+IFNpZ25lZC1vZmYtYnk6IFByYWJoYWthciBLdXNod2Fo YSA8cGt1c2h3YWhhQG1hcnZlbGwuY29tPgo+IFNpZ25lZC1vZmYtYnk6IE9ta2FyIEt1bGthcm5p IDxva3Vsa2FybmlAbWFydmVsbC5jb20+Cj4gU2lnbmVkLW9mZi1ieTogTWljaGFsIEthbGRlcm9u IDxta2FsZGVyb25AbWFydmVsbC5jb20+Cj4gU2lnbmVkLW9mZi1ieTogQXJpZWwgRWxpb3IgPGFl bGlvckBtYXJ2ZWxsLmNvbT4KPiBTaWduZWQtb2ZmLWJ5OiBTaGFpIE1hbGluIDxzbWFsaW5AbWFy dmVsbC5jb20+Cj4gLS0tCj4gICBkcml2ZXJzL252bWUvaHcvcWVkbi9NYWtlZmlsZSAgICB8ICAg MiArLQo+ICAgZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbi5oICAgICAgfCAgMjkgKysrKysrKwo+ ICAgZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl9jb25uLmMgfCAgIDMgKwo+ICAgZHJpdmVycy9u dm1lL2h3L3FlZG4vcWVkbl9tYWluLmMgfCAxMTQgKysrKysrKysrKysrKysrKysrKysrKystLQo+ ICAgZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl90YXNrLmMgfCAxMzggKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrKwo+ICAgNSBmaWxlcyBjaGFuZ2VkLCAyNzggaW5zZXJ0aW9ucygrKSwg OCBkZWxldGlvbnMoLSkKPiAgIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL252bWUvaHcvcWVk bi9xZWRuX3Rhc2suYwo+IAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL252bWUvaHcvcWVkbi9NYWtl ZmlsZSBiL2RyaXZlcnMvbnZtZS9ody9xZWRuL01ha2VmaWxlCj4gaW5kZXggZDhiMzQzYWZjZDE2 Li5jN2Q4MzhhNjFhZTYgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9udm1lL2h3L3FlZG4vTWFrZWZp bGUKPiArKysgYi9kcml2ZXJzL252bWUvaHcvcWVkbi9NYWtlZmlsZQo+IEBAIC0xLDQgKzEsNCBA QAo+ICAgIyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMC1vbmx5Cj4gICAKPiAgIG9i ai0kKENPTkZJR19OVk1FX1FFRE4pICs9IHFlZG4ubwo+IC1xZWRuLXkgOj0gcWVkbl9tYWluLm8g cWVkbl9jb25uLm8KPiArcWVkbi15IDo9IHFlZG5fbWFpbi5vIHFlZG5fY29ubi5vIHFlZG5fdGFz ay5vCj4gXCBObyBuZXdsaW5lIGF0IGVuZCBvZiBmaWxlCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMv bnZtZS9ody9xZWRuL3FlZG4uaCBiL2RyaXZlcnMvbnZtZS9ody9xZWRuL3FlZG4uaAo+IGluZGV4 IGMxNWNhYzM3ZWMxZS4uYmQ5YTI1MGNiMmY1IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbnZtZS9o dy9xZWRuL3FlZG4uaAo+ICsrKyBiL2RyaXZlcnMvbnZtZS9ody9xZWRuL3FlZG4uaAo+IEBAIC00 Nyw2ICs0Nyw5IEBACj4gICAjZGVmaW5lIFFFRE5fTk9OX0FCT1JUSVZFX1RFUk1JTkFUSU9OIDAK PiAgICNkZWZpbmUgUUVETl9BQk9SVElWRV9URVJNSU5BVElPTiAxCj4gICAKPiArI2RlZmluZSBR RUROX0ZXX0NRX0ZQX1dRX1dPUktRVUVVRSAicWVkbl9md19jcV9mcF93cSIKPiArI2RlZmluZSBR RUROX05WTUVfUkVRX0ZQX1dRX1dPUktRVUVVRSAicWVkbl9udm1lX3JlcV9mcF93cSIKPiArCj4g ICAvKgo+ICAgICogVENQIG9mZmxvYWQgc3RhY2sgZGVmYXVsdCBjb25maWd1cmF0aW9ucyBhbmQg ZGVmaW5lcy4KPiAgICAqIEZ1dHVyZSBlbmhhbmNlbWVudHMgd2lsbCBhbGxvdyBjb250cm9sbGlu ZyB0aGUgY29uZmlndXJhYmxlCj4gQEAgLTEwMCw2ICsxMDMsNyBAQCBzdHJ1Y3QgcWVkbl9mcF9x dWV1ZSB7Cj4gICAJc3RydWN0IHFlZG5fY3R4CSpxZWRuOwo+ICAgCXN0cnVjdCBxZWRfc2JfaW5m byAqc2JfaW5mbzsKPiAgIAl1bnNpZ25lZCBpbnQgY3B1Owo+ICsJc3RydWN0IHdvcmtfc3RydWN0 IGZ3X2NxX2ZwX3dxX2VudHJ5Owo+ICAgCXUxNiBzYl9pZDsKPiAgIAljaGFyIGlycW5hbWVbUUVE Tl9JUlFfTkFNRV9MRU5dOwo+ICAgfTsKPiBAQCAtMTMxLDYgKzEzNSw4IEBAIHN0cnVjdCBxZWRu X2N0eCB7Cj4gICAJc3RydWN0IHFlZG5fZnBfcXVldWUgKmZwX3FfYXJyOwo+ICAgCXN0cnVjdCBu dm1ldGNwX2dsYmxfcXVldWVfZW50cnkgKmZ3X2NxX2FycmF5X3ZpcnQ7Cj4gICAJZG1hX2FkZHJf dCBmd19jcV9hcnJheV9waHk7IC8qIFBoeXNpY2FsIGFkZHJlc3Mgb2YgZndfY3FfYXJyYXlfdmly dCAqLwo+ICsJc3RydWN0IHdvcmtxdWV1ZV9zdHJ1Y3QgKm52bWVfcmVxX2ZwX3dxOwo+ICsJc3Ry dWN0IHdvcmtxdWV1ZV9zdHJ1Y3QgKmZ3X2NxX2ZwX3dxOwo+ICAgfTsKPiAgIAo+ICAgc3RydWN0 IHFlZG5fZW5kcG9pbnQgewo+IEBAIC0yMTMsNiArMjE5LDI1IEBAIHN0cnVjdCBxZWRuX2N0cmwg ewo+ICAgCj4gICAvKiBDb25uZWN0aW9uIGxldmVsIHN0cnVjdCAqLwo+ICAgc3RydWN0IHFlZG5f Y29ubl9jdHggewo+ICsJLyogSU8gcGF0aCAqLwo+ICsJc3RydWN0IHdvcmtxdWV1ZV9zdHJ1Y3QJ Km52bWVfcmVxX2ZwX3dxOyAvKiBwdHIgdG8gcWVkbi0+bnZtZV9yZXFfZnBfd3EgKi8KPiArCXN0 cnVjdCBudm1lX3RjcF9vZmxkX3JlcSAqcmVxOyAvKiBjdXJyZW50bHkgcHJvY2Nlc3NlZCByZXF1 ZXN0ICovCj4gKwo+ICsJc3RydWN0IGxpc3RfaGVhZCBob3N0X3BlbmRfcmVxX2xpc3Q7Cj4gKwkv KiBTcGlubG9jayB0byBhY2Nlc3MgcGVuZGluZyByZXF1ZXN0IGxpc3QgKi8KPiArCXNwaW5sb2Nr X3QgbnZtZV9yZXFfbG9jazsKPiArCXVuc2lnbmVkIGludCBjcHU7Cj4gKwo+ICsJLyogRW50cnkg Zm9yIHJlZ2lzdGVyaW5nIHRvIG52bWVfcmVxX2ZwX3dxICovCj4gKwlzdHJ1Y3Qgd29ya19zdHJ1 Y3QgbnZtZV9yZXFfZnBfd3FfZW50cnk7Cj4gKwkvKgo+ICsJICogU3BpbmxvY2sgZm9yIGFjY2Vz c2luZyBxZWRuX3Byb2Nlc3NfcmVxIGFzIGl0IGNhbiBiZSBjYWxsZWQKPiArCSAqIGZyb20gbXVs dGlwbGUgcGxhY2UgbGlrZSBxdWV1ZV9ycSwgYXN5bmMsIHNlbGYgcmVxdWV1ZWQKPiArCSAqLwo+ ICsJc3RydWN0IG11dGV4IG52bWVfcmVxX211dGV4Owo+ICsJc3RydWN0IHFlZG5fZnBfcXVldWUg KmZwX3E7Cj4gKwlpbnQgcWlkOwo+ICsKPiAgIAlzdHJ1Y3QgcWVkbl9jdHggKnFlZG47Cj4gICAJ c3RydWN0IG52bWVfdGNwX29mbGRfcXVldWUgKnF1ZXVlOwo+ICAgCXN0cnVjdCBudm1lX3RjcF9v ZmxkX2N0cmwgKmN0cmw7Cj4gQEAgLTI4MCw1ICszMDUsOSBAQCBpbnQgcWVkbl93YWl0X2Zvcl9j b25uX2VzdChzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqY29ubl9jdHgpOwo+ICAgaW50IHFlZG5fc2V0 X2Nvbl9zdGF0ZShzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqY29ubl9jdHgsIGVudW0gcWVkbl9jb25u X3N0YXRlIG5ld19zdGF0ZSk7Cj4gICB2b2lkIHFlZG5fdGVybWluYXRlX2Nvbm5lY3Rpb24oc3Ry dWN0IHFlZG5fY29ubl9jdHggKmNvbm5fY3R4LCBpbnQgYWJydF9mbGFnKTsKPiAgIF9fYmUxNiBx ZWRuX2dldF9pbl9wb3J0KHN0cnVjdCBzb2NrYWRkcl9zdG9yYWdlICpzYSk7Cj4gK2lubGluZSBp bnQgcWVkbl92YWxpZGF0ZV9jY2NpZF9pbl9yYW5nZShzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqY29u bl9jdHgsIHUxNiBjY2NpZCk7Cj4gK3ZvaWQgcWVkbl9xdWV1ZV9yZXF1ZXN0KHN0cnVjdCBxZWRu X2Nvbm5fY3R4ICpxZWRuX2Nvbm4sIHN0cnVjdCBudm1lX3RjcF9vZmxkX3JlcSAqcmVxKTsKPiAr dm9pZCBxZWRuX252bWVfcmVxX2ZwX3dxX2hhbmRsZXIoc3RydWN0IHdvcmtfc3RydWN0ICp3b3Jr KTsKPiArdm9pZCBxZWRuX2lvX3dvcmtfY3Eoc3RydWN0IHFlZG5fY3R4ICpxZWRuLCBzdHJ1Y3Qg bnZtZXRjcF9md19jcWUgKmNxZSk7Cj4gICAKPiAgICNlbmRpZiAvKiBfUUVETl9IXyAqLwo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX2Nvbm4uYyBiL2RyaXZlcnMvbnZt ZS9ody9xZWRuL3FlZG5fY29ubi5jCj4gaW5kZXggOWJmYzBhNWYwY2RiLi45MGQ4YWEzNmQyMTkg MTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl9jb25uLmMKPiArKysgYi9k cml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX2Nvbm4uYwo+IEBAIC0zODUsNiArMzg1LDkgQEAgc3Rh dGljIGludCBxZWRuX3ByZXBfYW5kX29mZmxvYWRfcXVldWUoc3RydWN0IHFlZG5fY29ubl9jdHgg KmNvbm5fY3R4KQo+ICAgCX0KPiAgIAo+ICAgCXNldF9iaXQoUUVETl9DT05OX1JFU1JDX0ZXX1NR LCAmY29ubl9jdHgtPnJlc3JjX3N0YXRlKTsKPiArCUlOSVRfTElTVF9IRUFEKCZjb25uX2N0eC0+ aG9zdF9wZW5kX3JlcV9saXN0KTsKPiArCXNwaW5fbG9ja19pbml0KCZjb25uX2N0eC0+bnZtZV9y ZXFfbG9jayk7Cj4gKwo+ICAgCXJjID0gcWVkX29wcy0+YWNxdWlyZV9jb25uKHFlZG4tPmNkZXYs Cj4gICAJCQkJICAgJmNvbm5fY3R4LT5jb25uX2hhbmRsZSwKPiAgIAkJCQkgICAmY29ubl9jdHgt PmZ3X2NpZCwKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl9tYWluLmMg Yi9kcml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX21haW4uYwo+IGluZGV4IDhiNTcxNGU3ZTJiYi4u MzhmMjNkYmIwM2E1IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvbnZtZS9ody9xZWRuL3FlZG5fbWFp bi5jCj4gKysrIGIvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl9tYWluLmMKPiBAQCAtMjY3LDYg KzI2NywxOCBAQCBzdGF0aWMgaW50IHFlZG5fcmVsZWFzZV9jdHJsKHN0cnVjdCBudm1lX3RjcF9v ZmxkX2N0cmwgKmN0cmwpCj4gICAJcmV0dXJuIDA7Cj4gICB9Cj4gICAKPiArc3RhdGljIHZvaWQg cWVkbl9zZXRfY3RybF9pb19jcHVzKHN0cnVjdCBxZWRuX2Nvbm5fY3R4ICpjb25uX2N0eCwgaW50 IHFpZCkKPiArewo+ICsJc3RydWN0IHFlZG5fY3R4ICpxZWRuID0gY29ubl9jdHgtPnFlZG47Cj4g KwlzdHJ1Y3QgcWVkbl9mcF9xdWV1ZSAqZnBfcSA9IE5VTEw7Cj4gKwlpbnQgaW5kZXg7Cj4gKwo+ ICsJaW5kZXggPSBxaWQgPyAocWlkIC0gMSkgJSBxZWRuLT5udW1fZndfY3FzIDogMDsKPiArCWZw X3EgPSAmcWVkbi0+ZnBfcV9hcnJbaW5kZXhdOwo+ICsKPiArCWNvbm5fY3R4LT5jcHUgPSBmcF9x LT5jcHU7Cj4gK30KPiArCj4gICBzdGF0aWMgaW50IHFlZG5fY3JlYXRlX3F1ZXVlKHN0cnVjdCBu dm1lX3RjcF9vZmxkX3F1ZXVlICpxdWV1ZSwgaW50IHFpZCwgc2l6ZV90IHFfc2l6ZSkKPiAgIHsK PiAgIAlzdHJ1Y3QgbnZtZV90Y3Bfb2ZsZF9jdHJsICpjdHJsID0gcXVldWUtPmN0cmw7Cj4gQEAg LTI4OCw2ICszMDAsNyBAQCBzdGF0aWMgaW50IHFlZG5fY3JlYXRlX3F1ZXVlKHN0cnVjdCBudm1l X3RjcF9vZmxkX3F1ZXVlICpxdWV1ZSwgaW50IHFpZCwgc2l6ZV90Cj4gICAJY29ubl9jdHgtPnF1 ZXVlID0gcXVldWU7Cj4gICAJY29ubl9jdHgtPmN0cmwgPSBjdHJsOwo+ICAgCWNvbm5fY3R4LT5z cV9kZXB0aCA9IHFfc2l6ZTsKPiArCXFlZG5fc2V0X2N0cmxfaW9fY3B1cyhjb25uX2N0eCwgcWlk KTsKPiAgIAo+ICAgCWluaXRfd2FpdHF1ZXVlX2hlYWQoJmNvbm5fY3R4LT5jb25uX3dhaXRxKTsK PiAgIAlhdG9taWNfc2V0KCZjb25uX2N0eC0+ZXN0X2Nvbm5faW5kaWNhdG9yLCAwKTsKPiBAQCAt Mjk1LDYgKzMwOCwxMCBAQCBzdGF0aWMgaW50IHFlZG5fY3JlYXRlX3F1ZXVlKHN0cnVjdCBudm1l X3RjcF9vZmxkX3F1ZXVlICpxdWV1ZSwgaW50IHFpZCwgc2l6ZV90Cj4gICAKPiAgIAlzcGluX2xv Y2tfaW5pdCgmY29ubl9jdHgtPmNvbm5fc3RhdGVfbG9jayk7Cj4gICAKPiArCUlOSVRfV09SSygm Y29ubl9jdHgtPm52bWVfcmVxX2ZwX3dxX2VudHJ5LCBxZWRuX252bWVfcmVxX2ZwX3dxX2hhbmRs ZXIpOwo+ICsJY29ubl9jdHgtPm52bWVfcmVxX2ZwX3dxID0gcWVkbi0+bnZtZV9yZXFfZnBfd3E7 Cj4gKwljb25uX2N0eC0+cWlkID0gcWlkOwo+ICsKPiAgIAlxZWRuX2luaXRpYWxpemVfZW5kcG9p bnQoJmNvbm5fY3R4LT5lcCwgcWVkbi0+bG9jYWxfbWFjX2FkZHIsCj4gICAJCQkJICZjdHJsLT5j b25uX3BhcmFtcyk7Cj4gICAKPiBAQCAtMzU2LDYgKzM3Myw3IEBAIHN0YXRpYyB2b2lkIHFlZG5f ZGVzdHJveV9xdWV1ZShzdHJ1Y3QgbnZtZV90Y3Bfb2ZsZF9xdWV1ZSAqcXVldWUpCj4gICAJaWYg KCFjb25uX2N0eCkKPiAgIAkJcmV0dXJuOwo+ICAgCj4gKwljYW5jZWxfd29ya19zeW5jKCZjb25u X2N0eC0+bnZtZV9yZXFfZnBfd3FfZW50cnkpOwo+ICAgCXFlZG5fdGVybWluYXRlX2Nvbm5lY3Rp b24oY29ubl9jdHgsIFFFRE5fQUJPUlRJVkVfVEVSTUlOQVRJT04pOwo+ICAgCj4gICAJcWVkbl9x dWV1ZV93YWl0X2Zvcl90ZXJtaW5hdGVfY29tcGxldGUoY29ubl9jdHgpOwo+IEBAIC0zODUsMTIg KzQwMywyNCBAQCBzdGF0aWMgaW50IHFlZG5faW5pdF9yZXEoc3RydWN0IG52bWVfdGNwX29mbGRf cmVxICpyZXEpCj4gICAKPiAgIHN0YXRpYyB2b2lkIHFlZG5fY29tbWl0X3JxcyhzdHJ1Y3QgbnZt ZV90Y3Bfb2ZsZF9xdWV1ZSAqcXVldWUpCj4gICB7Cj4gLQkvKiBQbGFjZWhvbGRlciAtIHF1ZXVl IHdvcmsgKi8KPiArCXN0cnVjdCBxZWRuX2Nvbm5fY3R4ICpjb25uX2N0eDsKPiArCj4gKwljb25u X2N0eCA9IChzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqKXF1ZXVlLT5wcml2YXRlX2RhdGE7Cj4gKwo+ ICsJaWYgKCFsaXN0X2VtcHR5KCZjb25uX2N0eC0+aG9zdF9wZW5kX3JlcV9saXN0KSkKPiArCQlx dWV1ZV93b3JrX29uKGNvbm5fY3R4LT5jcHUsIGNvbm5fY3R4LT5udm1lX3JlcV9mcF93cSwKPiAr CQkJICAgICAgJmNvbm5fY3R4LT5udm1lX3JlcV9mcF93cV9lbnRyeSk7Cj4gICB9Cj4gICAKPiAg IHN0YXRpYyBpbnQgcWVkbl9zZW5kX3JlcShzdHJ1Y3QgbnZtZV90Y3Bfb2ZsZF9yZXEgKnJlcSkK PiAgIHsKPiAtCS8qIFBsYWNlaG9sZGVyIC0gcWVkbl9zZW5kX3JlcSAqLwo+ICsJc3RydWN0IHFl ZG5fY29ubl9jdHggKnFlZG5fY29ubiA9IChzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqKXJlcS0+cXVl dWUtPnByaXZhdGVfZGF0YTsKPiArCj4gKwkvKiBVbmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IHRo ZSBjY2NpZC90YWcgd2lsbCBiZSBpbiB0aGUgcmFuZ2Ugb2YgMCB0byBzcV9kZXB0aC0xLiAqLwo+ ICsJaWYgKCFyZXEtPmFzeW5jICYmIHFlZG5fdmFsaWRhdGVfY2NjaWRfaW5fcmFuZ2UocWVkbl9j b25uLCByZXEtPnJxLT50YWcpKQo+ICsJCXJldHVybiBCTEtfU1RTX05PVFNVUFA7Cj4gKwo+ICsJ cWVkbl9xdWV1ZV9yZXF1ZXN0KHFlZG5fY29ubiwgcmVxKTsKPiAgIAo+ICAgCXJldHVybiAwOwo+ ICAgfQo+IEBAIC00MzQsOSArNDY0LDU5IEBAIHN0cnVjdCBxZWRuX2Nvbm5fY3R4ICpxZWRuX2dl dF9jb25uX2hhc2goc3RydWN0IHFlZG5fY3R4ICpxZWRuLCB1MTYgaWNpZCkKPiAgIH0KPiAgIAo+ ICAgLyogRmFzdHBhdGggSVJRIGhhbmRsZXIgKi8KPiArdm9pZCBxZWRuX2Z3X2NxX2ZwX2hhbmRs ZXIoc3RydWN0IHFlZG5fZnBfcXVldWUgKmZwX3EpCj4gK3sKPiArCXUxNiBzYl9pZCwgY3FfcHJv ZF9pZHgsIGNxX2NvbnNfaWR4Owo+ICsJc3RydWN0IHFlZG5fY3R4ICpxZWRuID0gZnBfcS0+cWVk bjsKPiArCXN0cnVjdCBudm1ldGNwX2Z3X2NxZSAqY3FlID0gTlVMTDsKPiArCj4gKwlzYl9pZCA9 IGZwX3EtPnNiX2lkOwo+ICsJcWVkX3NiX3VwZGF0ZV9zYl9pZHgoZnBfcS0+c2JfaW5mbyk7Cj4g Kwo+ICsJLyogcm1iIC0gdG8gcHJldmVudCBtaXNzaW5nIG5ldyBjcWVzICovCj4gKwlybWIoKTsK PiArCj4gKwkvKiBSZWFkIHRoZSBsYXRlc3QgY3FfcHJvZCBmcm9tIHRoZSBTQiAqLwo+ICsJY3Ff cHJvZF9pZHggPSAqZnBfcS0+Y3FfcHJvZDsKPiArCWNxX2NvbnNfaWR4ID0gcWVkX2NoYWluX2dl dF9jb25zX2lkeCgmZnBfcS0+Y3FfY2hhaW4pOwo+ICsKPiArCXdoaWxlIChjcV9jb25zX2lkeCAh PSBjcV9wcm9kX2lkeCkgewo+ICsJCWNxZSA9IHFlZF9jaGFpbl9jb25zdW1lKCZmcF9xLT5jcV9j aGFpbik7Cj4gKwkJaWYgKGxpa2VseShjcWUpKQo+ICsJCQlxZWRuX2lvX3dvcmtfY3EocWVkbiwg Y3FlKTsKPiArCQllbHNlCj4gKwkJCXByX2VycigiRmFpbGVkIGNvbnN1bWluZyBjcWVcbiIpOwo+ ICsKPiArCQljcV9jb25zX2lkeCA9IHFlZF9jaGFpbl9nZXRfY29uc19pZHgoJmZwX3EtPmNxX2No YWluKTsKPiArCj4gKwkJLyogQ2hlY2sgaWYgbmV3IGNvbXBsZXRpb25zIHdlcmUgcG9zdGVkICov Cj4gKwkJaWYgKHVubGlrZWx5KGNxX3Byb2RfaWR4ID09IGNxX2NvbnNfaWR4KSkgewo+ICsJCQkv KiBybWIgLSB0byBwcmV2ZW50IG1pc3NpbmcgbmV3IGNxZXMgKi8KPiArCQkJcm1iKCk7Cj4gKwo+ ICsJCQkvKiBVcGRhdGUgdGhlIGxhdGVzdCBjcV9wcm9kIGZyb20gdGhlIFNCICovCj4gKwkJCWNx X3Byb2RfaWR4ID0gKmZwX3EtPmNxX3Byb2Q7Cj4gKwkJfQo+ICsJfQo+ICt9Cj4gKwo+ICtzdGF0 aWMgdm9pZCBxZWRuX2Z3X2NxX2ZxX3dxX2hhbmRsZXIoc3RydWN0IHdvcmtfc3RydWN0ICp3b3Jr KQo+ICt7Cj4gKwlzdHJ1Y3QgcWVkbl9mcF9xdWV1ZSAqZnBfcSA9IGNvbnRhaW5lcl9vZih3b3Jr LCBzdHJ1Y3QgcWVkbl9mcF9xdWV1ZSwgZndfY3FfZnBfd3FfZW50cnkpOwo+ICsKPiArCXFlZG5f ZndfY3FfZnBfaGFuZGxlcihmcF9xKTsKPiArCXFlZF9zYl9hY2soZnBfcS0+c2JfaW5mbywgSUdV X0lOVF9FTkFCTEUsIDEpOwo+ICt9Cj4gKwo+ICAgc3RhdGljIGlycXJldHVybl90IHFlZG5faXJx X2hhbmRsZXIoaW50IGlycSwgdm9pZCAqZGV2X2lkKQo+ICAgewo+IC0JLyogUGxhY2Vob2xkZXIg Ki8KPiArCXN0cnVjdCBxZWRuX2ZwX3F1ZXVlICpmcF9xID0gZGV2X2lkOwo+ICsJc3RydWN0IHFl ZG5fY3R4ICpxZWRuID0gZnBfcS0+cWVkbjsKPiArCj4gKwlmcF9xLT5jcHUgPSBzbXBfcHJvY2Vz c29yX2lkKCk7Cj4gKwo+ICsJcWVkX3NiX2FjayhmcF9xLT5zYl9pbmZvLCBJR1VfSU5UX0RJU0FC TEUsIDApOwo+ICsJcXVldWVfd29ya19vbihmcF9xLT5jcHUsIHFlZG4tPmZ3X2NxX2ZwX3dxLCAm ZnBfcS0+ZndfY3FfZnBfd3FfZW50cnkpOwo+ICAgCj4gICAJcmV0dXJuIElSUV9IQU5ETEVEOwo+ ICAgfQo+IEBAIC01ODQsNiArNjY0LDExIEBAIHN0YXRpYyB2b2lkIHFlZG5fZnJlZV9mdW5jdGlv bl9xdWV1ZXMoc3RydWN0IHFlZG5fY3R4ICpxZWRuKQo+ICAgCWludCBpOwo+ICAgCj4gICAJLyog RnJlZSB3b3JrcXVldWVzICovCj4gKwlkZXN0cm95X3dvcmtxdWV1ZShxZWRuLT5md19jcV9mcF93 cSk7Cj4gKwlxZWRuLT5md19jcV9mcF93cSA9IE5VTEw7Cj4gKwo+ICsJZGVzdHJveV93b3JrcXVl dWUocWVkbi0+bnZtZV9yZXFfZnBfd3EpOwo+ICsJcWVkbi0+bnZtZV9yZXFfZnBfd3EgPSBOVUxM Owo+ICAgCj4gICAJLyogRnJlZSB0aGUgZmFzdCBwYXRoIHF1ZXVlcyovCj4gICAJZm9yIChpID0g MDsgaSA8IHFlZG4tPm51bV9md19jcXM7IGkrKykgewo+IEBAIC02NTEsNyArNzM2LDIzIEBAIHN0 YXRpYyBpbnQgcWVkbl9hbGxvY19mdW5jdGlvbl9xdWV1ZXMoc3RydWN0IHFlZG5fY3R4ICpxZWRu KQo+ICAgCXU2NCBjcV9waHlfYWRkcjsKPiAgIAlpbnQgaTsKPiAgIAo+IC0JLyogUGxhY2UgaG9s ZGVyIC0gSU8tcGF0aCB3b3JrcXVldWVzICovCj4gKwlxZWRuLT5md19jcV9mcF93cSA9IGFsbG9j X3dvcmtxdWV1ZShRRUROX0ZXX0NRX0ZQX1dRX1dPUktRVUVVRSwKPiArCQkJCQkgICAgV1FfSElH SFBSSSB8IFdRX01FTV9SRUNMQUlNLCAwKTsKPiArCWlmICghcWVkbi0+ZndfY3FfZnBfd3EpIHsK PiArCQlyYyA9IC1FTk9ERVY7Cj4gKwkJcHJfZXJyKCJVbmFibGUgdG8gY3JlYXRlIGZhc3RwYXRo IEZXIENRIHdvcmtxdWV1ZSFcbiIpOwo+ICsKPiArCQlyZXR1cm4gcmM7Cj4gKwl9Cj4gKwo+ICsJ cWVkbi0+bnZtZV9yZXFfZnBfd3EgPSBhbGxvY193b3JrcXVldWUoUUVETl9OVk1FX1JFUV9GUF9X UV9XT1JLUVVFVUUsCj4gKwkJCQkJICAgICAgIFdRX0hJR0hQUkkgfCBXUV9NRU1fUkVDTEFJTSwg MSk7Cj4gKwlpZiAoIXFlZG4tPm52bWVfcmVxX2ZwX3dxKSB7Cj4gKwkJcmMgPSAtRU5PREVWOwo+ ICsJCXByX2VycigiVW5hYmxlIHRvIGNyZWF0ZSBmYXN0cGF0aCBxZWRuIG52bWUgd29ya3F1ZXVl IVxuIik7Cj4gKwo+ICsJCXJldHVybiByYzsKPiArCX0KPiAgIAo+ICAgCXFlZG4tPmZwX3FfYXJy ID0ga2NhbGxvYyhxZWRuLT5udW1fZndfY3FzLAo+ICAgCQkJCSBzaXplb2Yoc3RydWN0IHFlZG5f ZnBfcXVldWUpLCBHRlBfS0VSTkVMKTsKCldoeSBkb24ndCB5b3UgdXNlIHRocmVhZGVkIGludGVy cnVwdHMgaWYgeW91J3JlIHNwaW5uaW5nIG9mZiBhIHdvcmtxdWV1ZSAKZm9yIGhhbmRsaW5nIGlu dGVycnVwdHMgYW55d2F5PwoKPiBAQCAtNjc5LDcgKzc4MCw3IEBAIHN0YXRpYyBpbnQgcWVkbl9h bGxvY19mdW5jdGlvbl9xdWV1ZXMoc3RydWN0IHFlZG5fY3R4ICpxZWRuKQo+ICAgCQljaGFpbl9w YXJhbXMubW9kZSA9IFFFRF9DSEFJTl9NT0RFX1BCTCwKPiAgIAkJY2hhaW5fcGFyYW1zLmNudF90 eXBlID0gUUVEX0NIQUlOX0NOVF9UWVBFX1UxNiwKPiAgIAkJY2hhaW5fcGFyYW1zLm51bV9lbGVt cyA9IFFFRE5fRldfQ1FfU0laRTsKPiAtCQljaGFpbl9wYXJhbXMuZWxlbV9zaXplID0gNjQ7IC8q UGxhY2Vob2xkZXIgLSBzaXplb2Yoc3RydWN0IG52bWV0Y3BfZndfY3FlKSovCj4gKwkJY2hhaW5f cGFyYW1zLmVsZW1fc2l6ZSA9IHNpemVvZihzdHJ1Y3QgbnZtZXRjcF9md19jcWUpOwo+ICAgCj4g ICAJCXJjID0gcWVkX29wcy0+Y29tbW9uLT5jaGFpbl9hbGxvYyhxZWRuLT5jZGV2LAo+ICAgCQkJ CQkJICAmZnBfcS0+Y3FfY2hhaW4sCj4gQEAgLTcwOCw4ICs4MDksNyBAQCBzdGF0aWMgaW50IHFl ZG5fYWxsb2NfZnVuY3Rpb25fcXVldWVzKHN0cnVjdCBxZWRuX2N0eCAqcWVkbikKPiAgIAkJc2Ig PSBmcF9xLT5zYl9pbmZvLT5zYl92aXJ0Owo+ICAgCQlmcF9xLT5jcV9wcm9kID0gKHUxNiAqKSZz Yi0+cGlfYXJyYXlbUUVETl9QUk9UT19DUV9QUk9EX0lEWF07Cj4gICAJCWZwX3EtPnFlZG4gPSBx ZWRuOwo+IC0KPiAtCQkvKiBQbGFjZWhvbGRlciAtIEluaXQgSU8tcGF0aCB3b3JrcXVldWUgKi8K PiArCQlJTklUX1dPUksoJmZwX3EtPmZ3X2NxX2ZwX3dxX2VudHJ5LCBxZWRuX2Z3X2NxX2ZxX3dx X2hhbmRsZXIpOwo+ICAgCj4gICAJCS8qIFBsYWNlaG9sZGVyIC0gSW5pdCBJTy1wYXRoIHJlc291 cmNlcyAqLwo+ICAgCX0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl90 YXNrLmMgYi9kcml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX3Rhc2suYwo+IG5ldyBmaWxlIG1vZGUg MTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi5kMzQ3NDE4OGVmZGMKPiAtLS0gL2Rldi9udWxs Cj4gKysrIGIvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl90YXNrLmMKPiBAQCAtMCwwICsxLDEz OCBAQAo+ICsvLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogR1BMLTIuMAo+ICsvKgo+ICsgKiBD b3B5cmlnaHQgMjAyMSBNYXJ2ZWxsLiBBbGwgcmlnaHRzIHJlc2VydmVkLgo+ICsgKi8KPiArCj4g KyNkZWZpbmUgcHJfZm10KGZtdCkgS0JVSUxEX01PRE5BTUUgIjogIiBmbXQKPiArCj4gKyAvKiBL ZXJuZWwgaW5jbHVkZXMgKi8KPiArI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgo+ICsKPiArLyog RHJpdmVyIGluY2x1ZGVzICovCj4gKyNpbmNsdWRlICJxZWRuLmgiCj4gKwo+ICtpbmxpbmUgaW50 IHFlZG5fdmFsaWRhdGVfY2NjaWRfaW5fcmFuZ2Uoc3RydWN0IHFlZG5fY29ubl9jdHggKmNvbm5f Y3R4LCB1MTYgY2NjaWQpCj4gK3sKPiArCWludCByYyA9IDA7Cj4gKwo+ICsJaWYgKHVubGlrZWx5 KGNjY2lkID49IGNvbm5fY3R4LT5zcV9kZXB0aCkpIHsKPiArCQlwcl9lcnIoImNjY2lkIDB4JXgg b3V0IG9mIHJhbmdlICggPiBzcSBkZXB0aClcbiIsIGNjY2lkKTsKPiArCQlyYyA9IC1FSU5WQUw7 Cj4gKwl9Cj4gKwo+ICsJcmV0dXJuIHJjOwo+ICt9Cj4gKwo+ICtzdGF0aWMgYm9vbCBxZWRuX3By b2Nlc3NfcmVxKHN0cnVjdCBxZWRuX2Nvbm5fY3R4ICpxZWRuX2Nvbm4pCj4gK3sKPiArCXJldHVy biB0cnVlOwo+ICt9Cj4gKwo+ICsvKiBUaGUgV1EgaGFuZGxlciBjYW4gYmUgY2FsbCBmcm9tIDMg Zmxvd3M6Cj4gKyAqCTEuIHF1ZXVlX3JxLgo+ICsgKgkyLiBhc3luYy4KPiArICoJMy4gc2VsZiBy ZXF1ZXVlZAo+ICsgKiBUcnkgdG8gc2VuZCByZXF1ZXN0cyBmcm9tIHRoZSBwZW5kaW5nIGxpc3Qu IElmIGEgcmVxdWVzdCBwcm9jY2VzcyBoYXMgZmFpbGVkLAo+ICsgKiByZS1yZWdpc3RlciB0byB0 aGUgd29ya3F1ZXVlLgo+ICsgKiBJZiB0aGVyZSBhcmUgbm8gYWRkaXRpb25hbCBwZW5kaW5nIHJl cXVlc3RzIC0gZXhpdCB0aGUgaGFuZGxlci4KPiArICovCj4gK3ZvaWQgcWVkbl9udm1lX3JlcV9m cF93cV9oYW5kbGVyKHN0cnVjdCB3b3JrX3N0cnVjdCAqd29yaykKPiArewo+ICsJc3RydWN0IHFl ZG5fY29ubl9jdHggKnFlZG5fY29ubjsKPiArCWJvb2wgbW9yZSA9IGZhbHNlOwo+ICsKPiArCXFl ZG5fY29ubiA9IGNvbnRhaW5lcl9vZih3b3JrLCBzdHJ1Y3QgcWVkbl9jb25uX2N0eCwgbnZtZV9y ZXFfZnBfd3FfZW50cnkpOwo+ICsJZG8gewo+ICsJCWlmIChtdXRleF90cnlsb2NrKCZxZWRuX2Nv bm4tPm52bWVfcmVxX211dGV4KSkgewo+ICsJCQltb3JlID0gcWVkbl9wcm9jZXNzX3JlcShxZWRu X2Nvbm4pOwo+ICsJCQlxZWRuX2Nvbm4tPnJlcSA9IE5VTEw7Cj4gKwkJCW11dGV4X3VubG9jaygm cWVkbl9jb25uLT5udm1lX3JlcV9tdXRleCk7Cj4gKwkJfQo+ICsJfSB3aGlsZSAobW9yZSk7Cj4g Kwo+ICsJaWYgKCFsaXN0X2VtcHR5KCZxZWRuX2Nvbm4tPmhvc3RfcGVuZF9yZXFfbGlzdCkpCj4g KwkJcXVldWVfd29ya19vbihxZWRuX2Nvbm4tPmNwdSwgcWVkbl9jb25uLT5udm1lX3JlcV9mcF93 cSwKPiArCQkJICAgICAgJnFlZG5fY29ubi0+bnZtZV9yZXFfZnBfd3FfZW50cnkpOwo+ICt9Cj4g Kwo+ICt2b2lkIHFlZG5fcXVldWVfcmVxdWVzdChzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqcWVkbl9j b25uLCBzdHJ1Y3QgbnZtZV90Y3Bfb2ZsZF9yZXEgKnJlcSkKPiArewo+ICsJYm9vbCBlbXB0eSwg cmVzID0gZmFsc2U7Cj4gKwo+ICsJc3Bpbl9sb2NrKCZxZWRuX2Nvbm4tPm52bWVfcmVxX2xvY2sp Owo+ICsJZW1wdHkgPSBsaXN0X2VtcHR5KCZxZWRuX2Nvbm4tPmhvc3RfcGVuZF9yZXFfbGlzdCkg JiYgIXFlZG5fY29ubi0+cmVxOwo+ICsJbGlzdF9hZGRfdGFpbCgmcmVxLT5xdWV1ZV9lbnRyeSwg JnFlZG5fY29ubi0+aG9zdF9wZW5kX3JlcV9saXN0KTsKPiArCXNwaW5fdW5sb2NrKCZxZWRuX2Nv bm4tPm52bWVfcmVxX2xvY2spOwo+ICsKPiArCS8qIGF0dGVtcHQgd29ya3F1ZXVlIGJ5cGFzcyAq Lwo+ICsJaWYgKHFlZG5fY29ubi0+Y3B1ID09IHNtcF9wcm9jZXNzb3JfaWQoKSAmJiBlbXB0eSAm Jgo+ICsJICAgIG11dGV4X3RyeWxvY2soJnFlZG5fY29ubi0+bnZtZV9yZXFfbXV0ZXgpKSB7Cj4g KwkJcmVzID0gcWVkbl9wcm9jZXNzX3JlcShxZWRuX2Nvbm4pOwo+ICsJCXFlZG5fY29ubi0+cmVx ID0gTlVMTDsKPiArCQltdXRleF91bmxvY2soJnFlZG5fY29ubi0+bnZtZV9yZXFfbXV0ZXgpOwo+ ICsJCWlmIChyZXMgfHwgbGlzdF9lbXB0eSgmcWVkbl9jb25uLT5ob3N0X3BlbmRfcmVxX2xpc3Qp KQo+ICsJCQlyZXR1cm47Cj4gKwl9IGVsc2UgaWYgKHJlcS0+bGFzdCkgewo+ICsJCXF1ZXVlX3dv cmtfb24ocWVkbl9jb25uLT5jcHUsIHFlZG5fY29ubi0+bnZtZV9yZXFfZnBfd3EsCj4gKwkJCSAg ICAgICZxZWRuX2Nvbm4tPm52bWVfcmVxX2ZwX3dxX2VudHJ5KTsKPiArCX0KPiArfQo+ICsKClF1 ZXVlaW5nIGEgcmVxdWVzdD8KRG9lcyB3b25kZXJzIGZvciB5b3VyIGxhdGVuY3kgLi4uIENhbid0 IHlvdSBkbyB3aXRob3V0PwoKPiArc3RydWN0IHFlZG5fdGFza19jdHggKnFlZG5fY3FlX2dldF9h Y3RpdmVfdGFzayhzdHJ1Y3QgbnZtZXRjcF9md19jcWUgKmNxZSkKPiArewo+ICsJc3RydWN0IHJl Z3BhaXIgKnAgPSAmY3FlLT50YXNrX29wYXF1ZTsKPiArCj4gKwlyZXR1cm4gKHN0cnVjdCBxZWRu X3Rhc2tfY3R4ICopKCgoKHU2NCkobGUzMl90b19jcHUocC0+aGkpKSA8PCAzMikKPiArCQkJCQkr IGxlMzJfdG9fY3B1KHAtPmxvKSkpOwo+ICt9Cj4gKwo+ICt2b2lkIHFlZG5faW9fd29ya19jcShz dHJ1Y3QgcWVkbl9jdHggKnFlZG4sIHN0cnVjdCBudm1ldGNwX2Z3X2NxZSAqY3FlKQo+ICt7Cj4g KwlzdHJ1Y3QgcWVkbl90YXNrX2N0eCAqcWVkbl90YXNrID0gTlVMTDsKPiArCXN0cnVjdCBxZWRu X2Nvbm5fY3R4ICpjb25uX2N0eCA9IE5VTEw7Cj4gKwl1MTYgaXRpZDsKPiArCXUzMiBjaWQ7Cj4g Kwo+ICsJY29ubl9jdHggPSBxZWRuX2dldF9jb25uX2hhc2gocWVkbiwgbGUxNl90b19jcHUoY3Fl LT5jb25uX2lkKSk7Cj4gKwlpZiAodW5saWtlbHkoIWNvbm5fY3R4KSkgewo+ICsJCXByX2Vycigi Q0lEIDB4JXg6IEZhaWxlZCB0byBmZXRjaCBjb25uX2N0eCBmcm9tIGhhc2hcbiIsCj4gKwkJICAg ICAgIGxlMTZfdG9fY3B1KGNxZS0+Y29ubl9pZCkpOwo+ICsKPiArCQlyZXR1cm47Cj4gKwl9Cj4g Kwo+ICsJY2lkID0gY29ubl9jdHgtPmZ3X2NpZDsKPiArCWl0aWQgPSBsZTE2X3RvX2NwdShjcWUt Pml0aWQpOwo+ICsJcWVkbl90YXNrID0gcWVkbl9jcWVfZ2V0X2FjdGl2ZV90YXNrKGNxZSk7Cj4g KwlpZiAodW5saWtlbHkoIXFlZG5fdGFzaykpCj4gKwkJcmV0dXJuOwo+ICsKPiArCWlmIChsaWtl bHkoY3FlLT5jcWVfdHlwZSA9PSBOVk1FVENQX0ZXX0NRRV9UWVBFX05PUk1BTCkpIHsKPiArCQkv KiBQbGFjZWhvbGRlciAtIHZlcmlmeSB0aGUgY29ubmVjdGlvbiB3YXMgZXN0YWJsaXNoZWQgKi8K PiArCj4gKwkJc3dpdGNoIChjcWUtPnRhc2tfdHlwZSkgewo+ICsJCWNhc2UgTlZNRVRDUF9UQVNL X1RZUEVfSE9TVF9XUklURToKPiArCQljYXNlIE5WTUVUQ1BfVEFTS19UWVBFX0hPU1RfUkVBRDoK PiArCj4gKwkJCS8qIFBsYWNlaG9sZGVyIC0gSU8gZmxvdyAqLwo+ICsKPiArCQkJYnJlYWs7Cj4g Kwo+ICsJCWNhc2UgTlZNRVRDUF9UQVNLX1RZUEVfSE9TVF9SRUFEX05PX0NRRToKPiArCj4gKwkJ CS8qIFBsYWNlaG9sZGVyIC0gSU8gZmxvdyAqLwo+ICsKPiArCQkJYnJlYWs7Cj4gKwo+ICsJCWNh c2UgTlZNRVRDUF9UQVNLX1RZUEVfSU5JVF9DT05OX1JFUVVFU1Q6Cj4gKwo+ICsJCQkvKiBQbGFj ZWhvbGRlciAtIElDUmVxIGZsb3cgKi8KPiArCj4gKwkJCWJyZWFrOwo+ICsJCWRlZmF1bHQ6Cj4g KwkJCXByX2luZm8oIkNvdWxkIG5vdCBpZGVudGlmeSB0YXNrIHR5cGVcbiIpOwo+ICsJCX0KPiAr CX0gZWxzZSB7Cj4gKwkJLyogUGxhY2Vob2xkZXIgLSBSZWNvdmVyeSBmbG93cyAqLwo+ICsJfQo+ ICt9Cj4gCkNoZWVycywKCkhhbm5lcwotLSAKRHIuIEhhbm5lcyBSZWluZWNrZSAgICAgICAgICAg ICAgICBLZXJuZWwgU3RvcmFnZSBBcmNoaXRlY3QKaGFyZUBzdXNlLmRlICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgKzQ5IDkxMSA3NDA1MyA2ODgKU1VTRSBTb2Z0d2FyZSBTb2x1dGlvbnMg R21iSCwgTWF4ZmVsZHN0ci4gNSwgOTA0MDkgTsO8cm5iZXJnCkhSQiAzNjgwOSAoQUcgTsO8cm5i ZXJnKSwgR2VzY2jDpGZ0c2bDvGhyZXI6IEZlbGl4IEltZW5kw7ZyZmZlcgoKX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KTGludXgtbnZtZSBtYWlsaW5nIGxp c3QKTGludXgtbnZtZUBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQu b3JnL21haWxtYW4vbGlzdGluZm8vbGludXgtbnZtZQo=