Received: by 10.223.176.46 with SMTP id f43csp3876426wra; Tue, 23 Jan 2018 00:09:58 -0800 (PST) X-Google-Smtp-Source: AH8x227c7HFZUzZuc7PuWIUU18ro0pxr2xh6h6NYoSjZTNmJ3g7RMsTECKhyUVL7f0Syuhp0Y7W8 X-Received: by 2002:a17:902:3181:: with SMTP id x1-v6mr4874311plb.361.1516694998625; Tue, 23 Jan 2018 00:09:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516694998; cv=none; d=google.com; s=arc-20160816; b=a3fFnyH8fyQ9RcS/a3ydjQmml0no0vf0IdxUubvkZU28GXsqWcj+qv8sMtsBKAM7Xn A/z+sn1TtG6thXkgUn4gbJKm/JUjYgi9ln4raab3AKYtpG5fJNdhlkhVSRGfey/+7cv9 y52WzZ5JQL0XZVQx/OmcDA5U3/InYryJ3K8sZzbgeGw4s/Aptcj+9mDODR+50wQLN1k9 WrzN7BXWoLKdSppbjN2qoyGOwaTEoYJA26LK2kCnHIg7IAns0GA90HKygAKWtlJST+0v cRpAD8vI69fzA2SnwaIjTxQN9rC7V8JLTFSKWFn0KrnQaeKqXuHjIha4fJE0kZoRFmn2 /hpw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=9SM+qR983shwMAebK4Pv3lxqE7wf6CruU4rWNXK8cT4=; b=my8Nz9CPZZLAXGxwVxEK3pCeSfdWx91Q9Ewf3QMtvalgGORcPsuyCvdgmAU3CsG/Wo mkbe2PVQmo0Opu/Y4/8w6a1qf+X14PRXmsGzZpe4btRzoFSN0mTeHsBhuQMR1Gbe1KSM R5RTH3LUgxWMj4VcgtDRtyY0DYiluFIHr9/XN/js0ZZ7s2iGt0ieYfplWcnvtuME5JIn dgDKtzkHyX6W+SflsMqo+jFc9s1SjXMg3jP6fh2M+cKxE1VoZ2iAfUJdeDplJQY+xI6O biu6kRMQrS//XJ22fgxckY+mGJVeiqakYiFFNOpCE0VG7R6F9u/1/dX3uBIzQuIRn0T1 w9XQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 129si13294571pgc.441.2018.01.23.00.09.44; Tue, 23 Jan 2018 00:09:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751408AbeAWII6 (ORCPT + 99 others); Tue, 23 Jan 2018 03:08:58 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:4719 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751351AbeAWIIy (ORCPT ); Tue, 23 Jan 2018 03:08:54 -0500 Received: from DGGEMS409-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id D0116C1AAE3F5; Tue, 23 Jan 2018 16:08:36 +0800 (CST) Received: from huawei.com (10.175.102.37) by DGGEMS409-HUB.china.huawei.com (10.3.19.209) with Microsoft SMTP Server id 14.3.361.1; Tue, 23 Jan 2018 16:08:28 +0800 From: To: CC: , , , , Subject: [PATCH RFC 07/16] prcu: Implement call_prcu() API Date: Tue, 23 Jan 2018 15:59:32 +0800 Message-ID: <1516694381-20333-8-git-send-email-lianglihao@huawei.com> X-Mailer: git-send-email 1.7.12.4 In-Reply-To: <1516694381-20333-1-git-send-email-lianglihao@huawei.com> References: <1516694381-20333-1-git-send-email-lianglihao@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.175.102.37] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lihao Liang This is PRCU's counterpart of RCU's call_rcu() API. Reviewed-by: Heng Zhang Signed-off-by: Lihao Liang --- include/linux/prcu.h | 25 ++++++++++++++++++++ init/main.c | 2 ++ kernel/rcu/prcu.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 91 insertions(+), 3 deletions(-) diff --git a/include/linux/prcu.h b/include/linux/prcu.h index 653b4633..e5e09c9b 100644 --- a/include/linux/prcu.h +++ b/include/linux/prcu.h @@ -2,15 +2,36 @@ #define __LINUX_PRCU_H #include +#include #include #include #define CONFIG_PRCU +struct prcu_version_head { + unsigned long long version; + struct prcu_version_head *next; +}; + +/* Simple unsegmented callback list for PRCU. */ +struct prcu_cblist { + struct rcu_head *head; + struct rcu_head **tail; + struct prcu_version_head *version_head; + struct prcu_version_head **version_tail; + long len; +}; + +#define PRCU_CBLIST_INITIALIZER(n) { \ + .head = NULL, .tail = &n.head, \ + .version_head = NULL, .version_tail = &n.version_head, \ +} + struct prcu_local_struct { unsigned int locked; unsigned int online; unsigned long long version; + struct prcu_cblist cblist; }; struct prcu_struct { @@ -24,6 +45,8 @@ struct prcu_struct { void prcu_read_lock(void); void prcu_read_unlock(void); void synchronize_prcu(void); +void call_prcu(struct rcu_head *head, rcu_callback_t func); +void prcu_init(void); void prcu_note_context_switch(void); #else /* #ifdef CONFIG_PRCU */ @@ -31,6 +54,8 @@ void prcu_note_context_switch(void); #define prcu_read_lock() do {} while (0) #define prcu_read_unlock() do {} while (0) #define synchronize_prcu() do {} while (0) +#define call_prcu() do {} while (0) +#define prcu_init() do {} while (0) #define prcu_note_context_switch() do {} while (0) #endif /* #ifdef CONFIG_PRCU */ diff --git a/init/main.c b/init/main.c index f8665104..4925964e 100644 --- a/init/main.c +++ b/init/main.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -574,6 +575,7 @@ asmlinkage __visible void __init start_kernel(void) workqueue_init_early(); rcu_init(); + prcu_init(); /* Trace events are available after this */ trace_init(); diff --git a/kernel/rcu/prcu.c b/kernel/rcu/prcu.c index a00b9420..f198285c 100644 --- a/kernel/rcu/prcu.c +++ b/kernel/rcu/prcu.c @@ -1,11 +1,12 @@ #include -#include #include -#include +#include #include - +#include #include +#include "rcu.h" + DEFINE_PER_CPU_SHARED_ALIGNED(struct prcu_local_struct, prcu_local); struct prcu_struct global_prcu = { @@ -16,6 +17,16 @@ struct prcu_struct global_prcu = { }; struct prcu_struct *prcu = &global_prcu; +/* Initialize simple callback list. */ +static void prcu_cblist_init(struct prcu_cblist *rclp) +{ + rclp->head = NULL; + rclp->tail = &rclp->head; + rclp->version_head = NULL; + rclp->version_tail = &rclp->version_head; + rclp->len = 0; +} + static inline void prcu_report(struct prcu_local_struct *local) { unsigned long long global_version; @@ -123,3 +134,53 @@ void prcu_note_context_switch(void) prcu_report(local); put_cpu_ptr(&prcu_local); } + +void call_prcu(struct rcu_head *head, rcu_callback_t func) +{ + unsigned long flags; + struct prcu_local_struct *local; + struct prcu_cblist *rclp; + struct prcu_version_head *vhp; + + debug_rcu_head_queue(head); + + /* Use GFP_ATOMIC with IRQs disabled */ + vhp = kmalloc(sizeof(struct prcu_version_head), GFP_ATOMIC); + if (!vhp) + return; + + head->func = func; + head->next = NULL; + vhp->next = NULL; + + local_irq_save(flags); + local = this_cpu_ptr(&prcu_local); + vhp->version = local->version; + rclp = &local->cblist; + rclp->len++; + *rclp->tail = head; + rclp->tail = &head->next; + *rclp->version_tail = vhp; + rclp->version_tail = &vhp->next; + local_irq_restore(flags); +} +EXPORT_SYMBOL(call_prcu); + +void prcu_init_local_struct(int cpu) +{ + struct prcu_local_struct *local; + + local = per_cpu_ptr(&prcu_local, cpu); + local->locked = 0; + local->online = 0; + local->version = 0; + prcu_cblist_init(&local->cblist); +} + +void __init prcu_init(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + prcu_init_local_struct(cpu); +} -- 2.14.1.729.g59c0ea183