From patchwork Tue Mar 22 07:09:20 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 651821 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p2M7CaNb029046 for ; Tue, 22 Mar 2011 07:12:36 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753475Ab1CVHMK (ORCPT ); Tue, 22 Mar 2011 03:12:10 -0400 Received: from mail-fx0-f46.google.com ([209.85.161.46]:45348 "EHLO mail-fx0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754203Ab1CVHMJ (ORCPT ); Tue, 22 Mar 2011 03:12:09 -0400 Received: by fxm17 with SMTP id 17so6151986fxm.19 for ; Tue, 22 Mar 2011 00:12:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:subject:from:to:cc:in-reply-to:references :content-type:date:message-id:mime-version:x-mailer :content-transfer-encoding; bh=iQVzaib+cDn4GOudMadwMdtOLzN6ogwMUzC4t+P+AiA=; b=mUrC7Xx3N5TgaTx3FawWdqITlK94NqTdkOqW1GcRSkC6w9F5anFcMo4pU8NiwXMeVL IHYcT0ORZ2Zp8011ghZRtVRLtPUFX/Y1oqIJD5Wbjcev6GCkEoVnb00Ocm7oRnbyjYG6 F3oKQvD0d3cY8iogZPTspatUXNdXj0vQraB3U= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=subject:from:to:cc:in-reply-to:references:content-type:date :message-id:mime-version:x-mailer:content-transfer-encoding; b=e0rfeipJCucilUdKtvEb2I/ISF6AH5xaPuwTzxqDbojkoOli2oWOZvLzi2O1T53Vze Dm+zAKgx1fljrbWMpI8G71FAxMQsyXPuvrr0ozRepXR3aWJCHHbQySz/UQi0RRUji5Cm ZAAeuk80kCU3MQ2xo6tXpM1PmRMZD699w+60Q= Received: by 10.223.27.14 with SMTP id g14mr763259fac.129.1300777766160; Tue, 22 Mar 2011 00:09:26 -0700 (PDT) Received: from [10.150.51.212] (gw0.net.jmsp.net [212.23.165.14]) by mx.google.com with ESMTPS id b18sm2581903fak.8.2011.03.22.00.09.23 (version=SSLv3 cipher=OTHER); Tue, 22 Mar 2011 00:09:24 -0700 (PDT) Subject: [PATCH] posix-timers: RCU conversion From: Eric Dumazet To: ben@iagu.net, Thomas Gleixner Cc: Avi Kivity , KVM list , linux-kernel , John Stultz , Richard Cochran In-Reply-To: <1300746429.2837.20.camel@edumazet-laptop> References: <20110318123031.GB6066@8bytes.org> <4D871F6C.40207@redhat.com> <4D875842.9050308@redhat.com> <4D8773AA.8030408@redhat.com> <1300726498.2884.493.camel@edumazet-laptop> <4D8784A9.8040303@redhat.com> <1300727545.2884.513.camel@edumazet-laptop> <1300746429.2837.20.camel@edumazet-laptop> Date: Tue, 22 Mar 2011 08:09:20 +0100 Message-ID: <1300777760.2837.38.camel@edumazet-laptop> Mime-Version: 1.0 X-Mailer: Evolution 2.30.3 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 22 Mar 2011 07:12:36 +0000 (UTC) diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index d51243a..5dc27ca 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -81,6 +81,7 @@ struct k_itimer { unsigned long expires; } mmtimer; } it; + struct rcu_head rcu; }; struct k_clock { diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index 4c01249..acb9be9 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -491,6 +491,13 @@ static struct k_itimer * alloc_posix_timer(void) return tmr; } +static void k_itimer_rcu_free(struct rcu_head *head) +{ + struct k_itimer *tmr = container_of(head, struct k_itimer, rcu); + + kmem_cache_free(posix_timers_cache, tmr); +} + #define IT_ID_SET 1 #define IT_ID_NOT_SET 0 static void release_posix_timer(struct k_itimer *tmr, int it_id_set) @@ -503,7 +510,7 @@ static void release_posix_timer(struct k_itimer *tmr, int it_id_set) } put_pid(tmr->it_pid); sigqueue_free(tmr->sigq); - kmem_cache_free(posix_timers_cache, tmr); + call_rcu(&tmr->rcu, k_itimer_rcu_free); } static struct k_clock *clockid_to_kclock(const clockid_t id) @@ -631,22 +638,18 @@ out: static struct k_itimer *__lock_timer(timer_t timer_id, unsigned long *flags) { struct k_itimer *timr; - /* - * Watch out here. We do a irqsave on the idr_lock and pass the - * flags part over to the timer lock. Must not let interrupts in - * while we are moving the lock. - */ - spin_lock_irqsave(&idr_lock, *flags); + + rcu_read_lock(); timr = idr_find(&posix_timers_id, (int)timer_id); if (timr) { - spin_lock(&timr->it_lock); + spin_lock_irqsave(&timr->it_lock, *flags); if (timr->it_signal == current->signal) { - spin_unlock(&idr_lock); + rcu_read_unlock(); return timr; } - spin_unlock(&timr->it_lock); + spin_unlock_irqrestore(&timr->it_lock, *flags); } - spin_unlock_irqrestore(&idr_lock, *flags); + rcu_read_unlock(); return NULL; }