Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752700AbdHHXHo (ORCPT ); Tue, 8 Aug 2017 19:07:44 -0400 Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:45281 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752597AbdHHXHl (ORCPT ); Tue, 8 Aug 2017 19:07:41 -0400 From: Sukadev Bhattiprolu To: Michael Ellerman Cc: Benjamin Herrenschmidt , mikey@neuling.org, stewart@linux.vnet.ibm.com, apopple@au1.ibm.com, hbabu@us.ibm.com, oohall@gmail.com, linuxppc-dev@ozlabs.org, Subject: [PATCH v6 14/17] powerpc: Add support for setting SPRN_TIDR Date: Tue, 8 Aug 2017 16:06:59 -0700 X-Mailer: git-send-email 2.7.4 In-Reply-To: <1502233622-9330-1-git-send-email-sukadev@linux.vnet.ibm.com> References: <1502233622-9330-1-git-send-email-sukadev@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 17080823-0008-0000-0000-0000026B8AAE X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007509; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000217; SDB=6.00899536; UDB=6.00450257; IPR=6.00679741; BA=6.00005519; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00016602; XFM=3.00000015; UTC=2017-08-08 23:07:40 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17080823-0009-0000-0000-0000364F401A Message-Id: <1502233622-9330-15-git-send-email-sukadev@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-08-08_11:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1706020000 definitions=main-1708080380 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3716 Lines: 130 We need the SPRN_TIDR to bet set for use with fast thread-wakeup (core-to-core wakeup). Each thread in a process needs to have a unique id within the process but as explained below, for now, we assign globally unique thread ids to all threads in the system. Signed-off-by: Sukadev Bhattiprolu --- arch/powerpc/include/asm/processor.h | 4 ++ arch/powerpc/kernel/process.c | 74 ++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index fab7ff8..bf6ba63 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -232,6 +232,10 @@ struct debug_reg { struct thread_struct { unsigned long ksp; /* Kernel stack pointer */ +#ifdef CONFIG_PPC_VAS + unsigned long tidr; +#endif + #ifdef CONFIG_PPC64 unsigned long ksp_vsid; #endif diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9f3e2c9..6123859 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1213,6 +1213,16 @@ struct task_struct *__switch_to(struct task_struct *prev, hard_irq_disable(); } +#ifdef CONFIG_PPC_VAS + mtspr(SPRN_TIDR, new->thread.tidr); +#endif + /* + * We can't take a PMU exception inside _switch() since there is a + * window where the kernel stack SLB and the kernel stack are out + * of sync. Hard disable here. + */ + hard_irq_disable(); + /* * Call restore_sprs() before calling _switch(). If we move it after * _switch() then we miss out on calling it for new tasks. The reason @@ -1449,9 +1459,70 @@ void flush_thread(void) #endif /* CONFIG_HAVE_HW_BREAKPOINT */ } +#ifdef CONFIG_PPC_VAS +static DEFINE_SPINLOCK(vas_thread_id_lock); +static DEFINE_IDA(vas_thread_ida); + +/* + * We need to assign an unique thread id to each thread in a process. This + * thread id is intended to be used with the Fast Thread-wakeup (aka Core- + * to-core wakeup) mechanism being implemented on top of Virtual Accelerator + * Switchboard (VAS). + * + * To get a unique thread-id per process we could simply use task_pid_nr() + * but the problem is that task_pid_nr() is not yet available for the thread + * when copy_thread() is called. Fixing that would require changing more + * intrusive arch-neutral code in code path in copy_process()?. + * + * Further, to assign unique thread ids within each process, we need an + * atomic field (or an IDR) in task_struct, which again intrudes into the + * arch-neutral code. + * + * So try to assign globally unique thraed ids for now. + */ +static int assign_thread_id(void) +{ + int index; + int err; + +again: + if (!ida_pre_get(&vas_thread_ida, GFP_KERNEL)) + return -ENOMEM; + + spin_lock(&vas_thread_id_lock); + err = ida_get_new_above(&vas_thread_ida, 1, &index); + spin_unlock(&vas_thread_id_lock); + + if (err == -EAGAIN) + goto again; + else if (err) + return err; + + if (index > MAX_USER_CONTEXT) { + spin_lock(&vas_thread_id_lock); + ida_remove(&vas_thread_ida, index); + spin_unlock(&vas_thread_id_lock); + return -ENOMEM; + } + + return index; +} + +static void free_thread_id(int id) +{ + spin_lock(&vas_thread_id_lock); + ida_remove(&vas_thread_ida, id); + spin_unlock(&vas_thread_id_lock); +} +#endif /* CONFIG_PPC_VAS */ + + void release_thread(struct task_struct *t) { +#ifdef CONFIG_PPC_VAS + free_thread_id(t->thread.tidr); +#endif } /* @@ -1587,6 +1658,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, #endif setup_ksp_vsid(p, sp); +#ifdef CONFIG_PPC_VAS + p->thread.tidr = assign_thread_id(); +#endif #ifdef CONFIG_PPC64 if (cpu_has_feature(CPU_FTR_DSCR)) { -- 2.7.4