From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933552AbbFKNtL (ORCPT ); Thu, 11 Jun 2015 09:49:11 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:43943 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933255AbbFKNsz (ORCPT ); Thu, 11 Jun 2015 09:48:55 -0400 From: Kishan Kumar To: paulmck@linux.vnet.ibm.com, josh@joshtriplett.org, rostedt@goodmis.org, mathieu.desnoyers@efficios.com, laijs@cn.fujitsu.com, linux-kernel@vger.kernel.org, kaushalk@codeaurora.org Cc: Kishan Kumar , Mohammed Khajapasha , Vignesh Radhakrishnan Subject: [PATCH] rcu: Start grace period even for single callback Date: Thu, 11 Jun 2015 19:18:18 +0530 Message-Id: <1434030498-25507-1-git-send-email-kishank@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When we queue a callback for RCU, it goes and sits on the nxttail of the per-cpu RCU data structure. Callback is represented via struct callback_head structure. struct callback_head { struct callback_head *next; void (*func)(struct callback_head *head); }; In case of a single callback queued in the nxttail, the next field will be NULL. "next" happens to be the zeroeth element of struct callback_head. The condition "if(*rdp->nxttail[RCU_NEXT_READY_TAIL])" in the function cpu_needs_another_gp(), essentially checks if any callback is queued. Since *rdp->nxttail[RCU_NEXT_READY_TAIL] dereferences to the first element, the if condition will just turn out to be if(NULL) in case there is a single callback queued. This in turn causes cpu_needs_another_gp() to return false even though we need a grace period to process the single callback. This leads to writers waiting until a second call_back gets queued, which can cause undesirable effects like boot up delay upto 300 seconds, etc. Fix this by performing this check on the "func" field rather than the "next" field of the callback_head. Signed-off-by: Kishan Kumar Signed-off-by: Mohammed Khajapasha Signed-off-by: Vignesh Radhakrishnan --- kernel/rcu/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index fc3abf1..394a4fa 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -324,7 +324,7 @@ cpu_needs_another_gp(struct rcu_state *rsp, struct rcu_data *rdp) return 1; /* Yes, a no-CBs CPU needs one. */ if (!rdp->nxttail[RCU_NEXT_TAIL]) return 0; /* No, this is a no-CBs (or offline) CPU. */ - if (*rdp->nxttail[RCU_NEXT_READY_TAIL]) + if (((struct callback_head *)rdp->nxttail[RCU_NEXT_READY_TAIL])->func) return 1; /* Yes, this CPU has newly registered callbacks. */ for (i = RCU_WAIT_TAIL; i < RCU_NEXT_TAIL; i++) if (rdp->nxttail[i - 1] != rdp->nxttail[i] && -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation.