From patchwork Tue Nov 10 04:20:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Fischofer X-Patchwork-Id: 56278 Delivered-To: patch@linaro.org Received: by 10.112.155.196 with SMTP id vy4csp549970lbb; Mon, 9 Nov 2015 20:22:14 -0800 (PST) X-Received: by 10.55.214.83 with SMTP id t80mr1694349qki.98.1447129333893; Mon, 09 Nov 2015 20:22:13 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id x5si1311838qka.90.2015.11.09.20.22.13; Mon, 09 Nov 2015 20:22:13 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dkim=neutral (body hash did not verify) header.i=@linaro_org.20150623.gappssmtp.com Received: by lists.linaro.org (Postfix, from userid 109) id 8155A61CFA; Tue, 10 Nov 2015 04:22:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 5E5B061CC9; Tue, 10 Nov 2015 04:20:57 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 8CC8A61CEC; Tue, 10 Nov 2015 04:20:53 +0000 (UTC) Received: from mail-pa0-f46.google.com (mail-pa0-f46.google.com [209.85.220.46]) by lists.linaro.org (Postfix) with ESMTPS id 9605861CB1 for ; Tue, 10 Nov 2015 04:20:26 +0000 (UTC) Received: by padhx2 with SMTP id hx2so212871110pad.1 for ; Mon, 09 Nov 2015 20:20:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro_org.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pQTU7xD70Ycm1GPy0WJx1zaTL7+Ofmm04NFMTZMw5Xs=; b=Z53Zv9pxlgPxu00F2zLINnL/xO0MOIG+TlPsoa3/QQnlCoWa4DscN8tc+FMtIYwd7g INi/HD1O0TmfuUF6ey6HNCKedfjP3dkiNWWd0iCWEda0y3UVVIKJ4cWlbeInI/ruQSMw B6BKGHJ52MzsoaDjjUTAciZoAnX0/kk1dwXU20atp4WzuWnLAkr84xRBjNdUDuvPQC2c rGeZYv1t4JTQbVSe4GYIo0PTV7rp+GDKRWQExzPzYH3dkUbUIEN4gR4i0I4y6apcWvSy Yabi8vcApZOo2PCzjFVcfJ2Fz/cdVkTY3PlHR0laj7GSCrzhfqjgPYpgJ/KCJZgSnHj+ bcKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pQTU7xD70Ycm1GPy0WJx1zaTL7+Ofmm04NFMTZMw5Xs=; b=hKP4uILxfcrKDtGOkW1+n2A5bo1/KXb+LV/9GMejXCBypbmMuslb2DljdXDGPv191B AT0teuOq+dG5+73CqLwpQoa34hhYWHKYbmrolI5Zxsz7ZiGe4J5J1Kr4MIj3Rq7hohuW YqHiDBsVTnYj66W40XVJ/fQ0ifKmapD2FnG/h70iTb1D8swnrIpJAEnet2+FV6p+6Mg0 znobtQNCXXSrFJbFpa+gawIN6l1Zk6YbxX7Gt2xv4w02Jw4VAsw/YtPFXKUy3Ha6qmJf rNOx06Kelo8uSJ/8S/DcxVf6LDj7Z742Uf6IbyVNCNctD3Enlrwss+3mOdxQiZ+8Ho+p 2DbA== X-Gm-Message-State: ALoCoQmP/Ycg/ni674FmTIIL21FwVPhoke8C23Rl/YpMnACxEk/wULXUXIwJueHzSgodXPU9j4vO X-Received: by 10.66.217.194 with SMTP id pa2mr2398668pac.98.1447129225677; Mon, 09 Nov 2015 20:20:25 -0800 (PST) Received: from Ubuntu15.localdomain ([40.139.248.3]) by smtp.gmail.com with ESMTPSA id fl5sm1137315pbd.70.2015.11.09.20.20.24 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Nov 2015 20:20:25 -0800 (PST) From: Bill Fischofer To: lng-odp@lists.linaro.org Date: Mon, 9 Nov 2015 20:20:06 -0800 Message-Id: <1447129211-9095-4-git-send-email-bill.fischofer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1447129211-9095-1-git-send-email-bill.fischofer@linaro.org> References: <1447129211-9095-1-git-send-email-bill.fischofer@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCHv3 3/8] linux-generic: queue: add ordered_queue_enq() routine - part 1 X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" Add the new ordered_queue_enq() internal routine. This is done in two parts to make the diffs easier to follow. Part 1 adds the new routine while Part 2 replaces queue_enq() to use it. Signed-off-by: Bill Fischofer --- .../linux-generic/include/odp_queue_internal.h | 2 + platform/linux-generic/odp_queue.c | 118 +++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h index 32e3288..1bd365b 100644 --- a/platform/linux-generic/include/odp_queue_internal.h +++ b/platform/linux-generic/include/odp_queue_internal.h @@ -96,6 +96,8 @@ union queue_entry_u { queue_entry_t *get_qentry(uint32_t queue_id); int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr, int sustain); +int ordered_queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr, + int systain, queue_entry_t *origin_qe, uint64_t order); odp_buffer_hdr_t *queue_deq(queue_entry_t *queue); int queue_enq_internal(odp_buffer_hdr_t *buf_hdr); diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c index bcc8190..a545927 100644 --- a/platform/linux-generic/odp_queue.c +++ b/platform/linux-generic/odp_queue.c @@ -529,6 +529,124 @@ int queue_enq(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr, int sustain) return 0; } +int ordered_queue_enq(queue_entry_t *queue, + odp_buffer_hdr_t *buf_hdr, + int sustain, + queue_entry_t *origin_qe, + uint64_t order) +{ + odp_buffer_hdr_t *reorder_buf; + odp_buffer_hdr_t *next_buf; + odp_buffer_hdr_t *reorder_prev; + odp_buffer_hdr_t *placeholder_buf = NULL; + int release_count, placeholder_count; + int sched = 0; + + /* Need two locks for enq operations from ordered queues */ + get_qe_locks(origin_qe, queue); + + if (odp_unlikely(origin_qe->s.status < QUEUE_STATUS_READY || + queue->s.status < QUEUE_STATUS_READY)) { + free_qe_locks(queue, origin_qe); + ODP_ERR("Bad queue status\n"); + ODP_ERR("queue = %s, origin q = %s, buf = %p\n", + queue->s.name, origin_qe->s.name, buf_hdr); + return -1; + } + + /* Remember that enq was called for this order */ + sched_enq_called(); + + /* We can only complete this enq if we're in order */ + if (order > origin_qe->s.order_out) { + reorder_enq(queue, order, origin_qe, buf_hdr, sustain); + + /* This enq can't complete until order is restored, so + * we're done here. + */ + free_qe_locks(queue, origin_qe); + return 0; + } + + /* Resolve order if requested */ + if (!sustain) { + order_release(origin_qe, 1); + sched_order_resolved(buf_hdr); + } + + /* Update queue status */ + if (queue->s.status == QUEUE_STATUS_NOTSCHED) { + queue->s.status = QUEUE_STATUS_SCHED; + sched = 1; + } + + /* We're in order, however the reorder queue may have other buffers + * sharing this order on it and this buffer must not be enqueued ahead + * of them. If the reorder queue is empty we can short-cut and + * simply add to the target queue directly. + */ + + if (!origin_qe->s.reorder_head) { + queue_add_chain(queue, buf_hdr); + free_qe_locks(queue, origin_qe); + + /* Add queue to scheduling */ + if (sched && schedule_queue(queue)) + ODP_ABORT("schedule_queue failed\n"); + return 0; + } + + /* The reorder_queue is non-empty, so sort this buffer into it. Note + * that we force the sustain bit on here because we'll be removing + * this immediately and we already accounted for this order earlier. + */ + reorder_enq(queue, order, origin_qe, buf_hdr, 1); + + /* Pick up this element, and all others resolved by this enq, + * and add them to the target queue. + */ + reorder_deq(queue, origin_qe, &reorder_buf, &reorder_prev, + &placeholder_buf, &release_count, &placeholder_count); + + /* Move the list from the reorder queue to the target queue */ + if (queue->s.head) + queue->s.tail->next = origin_qe->s.reorder_head; + else + queue->s.head = origin_qe->s.reorder_head; + queue->s.tail = reorder_prev; + origin_qe->s.reorder_head = reorder_prev->next; + reorder_prev->next = NULL; + + /* Reflect resolved orders in the output sequence */ + order_release(origin_qe, release_count + placeholder_count); + + /* Now handle any resolved orders for events destined for other + * queues, appending placeholder bufs as needed. + */ + if (origin_qe != queue) + UNLOCK(&queue->s.lock); + + /* Add queue to scheduling */ + if (sched && schedule_queue(queue)) + ODP_ABORT("schedule_queue failed\n"); + + reorder_complete(origin_qe, &reorder_buf, &placeholder_buf, + 1, 0); + UNLOCK(&origin_qe->s.lock); + + if (reorder_buf) + queue_enq_internal(reorder_buf); + + /* Free all placeholder bufs that are now released */ + while (placeholder_buf) { + next_buf = placeholder_buf->next; + odp_buffer_free(placeholder_buf->handle.handle); + placeholder_buf = next_buf; + } + + return 0; +} + int queue_enq_multi(queue_entry_t *queue, odp_buffer_hdr_t *buf_hdr[], int num, int sustain) {