From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932417AbdGXVgu (ORCPT ); Mon, 24 Jul 2017 17:36:50 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:46507 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1756585AbdGXVgc (ORCPT ); Mon, 24 Jul 2017 17:36:32 -0400 From: "Paul E. McKenney" To: linux-kernel@vger.kernel.org Cc: mingo@kernel.org, jiangshanlai@gmail.com, dipankar@in.ibm.com, akpm@linux-foundation.org, mathieu.desnoyers@efficios.com, josh@joshtriplett.org, tglx@linutronix.de, peterz@infradead.org, rostedt@goodmis.org, dhowells@redhat.com, edumazet@google.com, fweisbec@gmail.com, oleg@redhat.com, "Paul E. McKenney" Subject: [PATCH tip/core/rcu 5/6] doc: No longer allowed to use rcu_dereference on non-pointers Date: Mon, 24 Jul 2017 14:36:27 -0700 X-Mailer: git-send-email 2.5.2 In-Reply-To: <20170724213605.GA8766@linux.vnet.ibm.com> References: <20170724213605.GA8766@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17072421-0024-0000-0000-000002B504A9 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007419; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000214; SDB=6.00892369; UDB=6.00446020; IPR=6.00672534; BA=6.00005489; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00016356; XFM=3.00000015; UTC=2017-07-24 21:36:30 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17072421-0025-0000-0000-000044DD56D7 Message-Id: <1500932188-9202-5-git-send-email-paulmck@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-07-24_13:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1706020000 definitions=main-1707240328 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: Paul E. McKenney --- Documentation/RCU/rcu_dereference.txt | 61 ++++++++++++----------------------- 1 file changed, 21 insertions(+), 40 deletions(-) diff --git a/Documentation/RCU/rcu_dereference.txt b/Documentation/RCU/rcu_dereference.txt index b2a613f16d74..1acb26b09b48 100644 --- a/Documentation/RCU/rcu_dereference.txt +++ b/Documentation/RCU/rcu_dereference.txt @@ -25,35 +25,35 @@ o You must use one of the rcu_dereference() family of primitives for an example where the compiler can in fact deduce the exact value of the pointer, and thus cause misordering. +o You are only permitted to use rcu_dereference on pointer values. + The compiler simply knows too much about integral values to + trust it to carry dependencies through integer operations. + There are a very few exceptions, namely that you can temporarily + cast the pointer to uintptr_t in order to: + + o Set bits and clear bits down in the must-be-zero low-order + bits of that pointer. This clearly means that the pointer + must have alignment constraints, for example, this does + -not- work in general for char* pointers. + + o XOR bits to translate pointers, as is done in some + classic buddy-allocator algorithms. + + It is important to cast the value back to pointer before + doing much of anything else with it. + o Avoid cancellation when using the "+" and "-" infix arithmetic operators. For example, for a given variable "x", avoid - "(x-x)". There are similar arithmetic pitfalls from other - arithmetic operators, such as "(x*0)", "(x/(x+1))" or "(x%1)". - The compiler is within its rights to substitute zero for all of - these expressions, so that subsequent accesses no longer depend - on the rcu_dereference(), again possibly resulting in bugs due - to misordering. + "(x-(uintptr_t)x)" for char* pointers. The compiler is within its + rights to substitute zero for this sort of expression, so that + subsequent accesses no longer depend on the rcu_dereference(), + again possibly resulting in bugs due to misordering. Of course, if "p" is a pointer from rcu_dereference(), and "a" and "b" are integers that happen to be equal, the expression "p+a-b" is safe because its value still necessarily depends on the rcu_dereference(), thus maintaining proper ordering. -o Avoid all-zero operands to the bitwise "&" operator, and - similarly avoid all-ones operands to the bitwise "|" operator. - If the compiler is able to deduce the value of such operands, - it is within its rights to substitute the corresponding constant - for the bitwise operation. Once again, this causes subsequent - accesses to no longer depend on the rcu_dereference(), causing - bugs due to misordering. - - Please note that single-bit operands to bitwise "&" can also - be dangerous. At this point, the compiler knows that the - resulting value can only take on one of two possible values. - Therefore, a very small amount of additional information will - allow the compiler to deduce the exact value, which again can - result in misordering. - o If you are using RCU to protect JITed functions, so that the "()" function-invocation operator is applied to a value obtained (directly or indirectly) from rcu_dereference(), you may need to @@ -61,25 +61,6 @@ o If you are using RCU to protect JITed functions, so that the This issue arises on some systems when a newly JITed function is using the same memory that was used by an earlier JITed function. -o Do not use the results from the boolean "&&" and "||" when - dereferencing. For example, the following (rather improbable) - code is buggy: - - int *p; - int *q; - - ... - - p = rcu_dereference(gp) - q = &global_q; - q += p != &oom_p1 && p != &oom_p2; - r1 = *q; /* BUGGY!!! */ - - The reason this is buggy is that "&&" and "||" are often compiled - using branches. While weak-memory machines such as ARM or PowerPC - do order stores after such branches, they can speculate loads, - which can result in misordering bugs. - o Do not use the results from relational operators ("==", "!=", ">", ">=", "<", or "<=") when dereferencing. For example, the following (quite strange) code is buggy: -- 2.5.2