From patchwork Sun Nov 8 20:42:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Fischofer X-Patchwork-Id: 56162 Delivered-To: patch@linaro.org Received: by 10.112.1.169 with SMTP id 9csp127182lbn; Sun, 8 Nov 2015 12:44:13 -0800 (PST) X-Received: by 10.140.173.65 with SMTP id t62mr14898479qht.96.1447015453258; Sun, 08 Nov 2015 12:44:13 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id w80si8564457qhw.112.2015.11.08.12.44.13; Sun, 08 Nov 2015 12:44: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 D3C0261817; Sun, 8 Nov 2015 20:44:12 +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=-2.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,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 A9AE661988; Sun, 8 Nov 2015 20:42:27 +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 E32F961971; Sun, 8 Nov 2015 20:42:21 +0000 (UTC) Received: from mail-yk0-f175.google.com (mail-yk0-f175.google.com [209.85.160.175]) by lists.linaro.org (Postfix) with ESMTPS id 65B7961942 for ; Sun, 8 Nov 2015 20:42:18 +0000 (UTC) Received: by ykek133 with SMTP id k133so236389805yke.2 for ; Sun, 08 Nov 2015 12:42:18 -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=LEFZLF+xSoE90FeA6/UWDyISx/j36gfY9y8q4yWgAdLrmZ3pSkv4kvL0x1jAUjgy7b eYblSAxpN5XOQpcqdexOnm1HqgTpAaf9qFc1pMyOwhfu5nl3JHmhg/lSLuHGAJtje4/7 S0RXYERqcOfL7qc0LmCw3LMGz6tPMM1GcGCb/RTOEswUVJpNliXUOwvvA0AhH8IwGobY tUF8j1jpyWsqzJs7ibo+0hpswXOvScbh6Cvyzx6gdrMx/uBNenhV2jyhxihSs8riI/Jw 0GrguVDhypYlPriYSMlOkccx+q5fmvx5H9EHu1kZagsYbl6l4/SYhMGeTxbCDjqcgULp d4PQ== 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=FDfRhqHOoX0bFDMdWxnFznzQzMFE3vlr1bu0n9BBY+jZZLV8btm2kJDTk0+dDvXCNj ANoHurZyf5e/YKqaltj10Q4rgfz4A//OyAs5d6PWw3XGeEtcMd5wGkp0vnWsGvk0ANz3 rKOgaoUGmi/IN4cOsb1fT/EF5nc4+o3khnRaQA4LJDpaZ1NfFHzX6RMsJheiXwWCTVRs U5M/E4BU2+GlgCIou7d9QWqCG58m1CvJHcynHGaaDTDg0pJLr9Om3mtyFDzuDlSfek42 I2YFFYNm9Ec5kNy7K6J5a940iCvDKVe+BbwPUbZiMqGcokncO+6Ld0DZcbUTioHs0TH4 fwhg== X-Gm-Message-State: ALoCoQm6vi4s385Eg0vuRsLVlB6OjFohfEiN/yhlXiIuvxjoAPBlRFGC0f0Yw1ksvJwtDFgF0iOn X-Received: by 10.129.22.213 with SMTP id 204mr22764132yww.78.1447015338064; Sun, 08 Nov 2015 12:42:18 -0800 (PST) Received: from Ubuntu15.localdomain (cpe-66-68-129-43.austin.res.rr.com. [66.68.129.43]) by smtp.gmail.com with ESMTPSA id f133sm10270399ywa.27.2015.11.08.12.42.17 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 08 Nov 2015 12:42:17 -0800 (PST) From: Bill Fischofer To: lng-odp@lists.linaro.org Date: Sun, 8 Nov 2015 14:42:07 -0600 Message-Id: <1447015330-24420-4-git-send-email-bill.fischofer@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1447015330-24420-1-git-send-email-bill.fischofer@linaro.org> References: <1447015330-24420-1-git-send-email-bill.fischofer@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCHv2 3/6] 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) {