From patchwork Fri Mar 1 00:43:11 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stultz X-Patchwork-Id: 15171 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 4E1CC23E1A for ; Fri, 1 Mar 2013 00:44:05 +0000 (UTC) Received: from mail-vc0-f173.google.com (mail-vc0-f173.google.com [209.85.220.173]) by fiordland.canonical.com (Postfix) with ESMTP id DEE74A1935F for ; Fri, 1 Mar 2013 00:44:04 +0000 (UTC) Received: by mail-vc0-f173.google.com with SMTP id fy27so1622169vcb.4 for ; Thu, 28 Feb 2013 16:44:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-received:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state; bh=yRdGgVcWIaSOdRFsoOlAgS0JnBtefDRWwzJpE+o9Gbs=; b=Pa4elzwnGdG3HhYGVD2bMQ6mHUDqMlbHqN12sZanq+InuqU1rRrELTz0J4Ia0JWwND v830izJuZCfIFm5IioLt/rqbuikVLasR3zoUfKv4Uyz9Zigf3LTY/Nlr+EuYaMG4QUM1 xyVoJv/1Kqd4Dd2NARUQBGENLcahMUtp15Btme1wzqK8H0D490fkPM3MdTpTztj1i7jB zy/dRMGlbBeqNidoxLmoJKC1woAod8Nh2pmychPcimex1vNjCjfceXb6vsxVcgA0vFQA UN3/ORnRvXH1cVAmdepoipaMZ4pYQw2MtePz1MkaxQUuiPmiG1ZbcyUPo76moYIaJHEy uJcA== X-Received: by 10.52.177.163 with SMTP id cr3mr2914321vdc.94.1362098644425; Thu, 28 Feb 2013 16:44:04 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp654veb; Thu, 28 Feb 2013 16:44:03 -0800 (PST) X-Received: by 10.68.135.168 with SMTP id pt8mr11876920pbb.10.1362098643461; Thu, 28 Feb 2013 16:44:03 -0800 (PST) Received: from mail-da0-f44.google.com (mail-da0-f44.google.com [209.85.210.44]) by mx.google.com with ESMTPS id f7si6018723paz.296.2013.02.28.16.44.03 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 28 Feb 2013 16:44:03 -0800 (PST) Received-SPF: neutral (google.com: 209.85.210.44 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) client-ip=209.85.210.44; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.210.44 is neither permitted nor denied by best guess record for domain of john.stultz@linaro.org) smtp.mail=john.stultz@linaro.org Received: by mail-da0-f44.google.com with SMTP id z20so1116171dae.3 for ; Thu, 28 Feb 2013 16:44:03 -0800 (PST) X-Received: by 10.66.234.65 with SMTP id uc1mr16080783pac.87.1362098643074; Thu, 28 Feb 2013 16:44:03 -0800 (PST) Received: from localhost.localdomain (c-24-21-54-107.hsd1.or.comcast.net. [24.21.54.107]) by mx.google.com with ESMTPS id dx17sm10914892pac.17.2013.02.28.16.44.01 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 28 Feb 2013 16:44:02 -0800 (PST) From: John Stultz To: lkml Cc: Erik Gilling , Maarten Lankhorst , Daniel Vetter , Rob Clark , Sumit Semwal , Greg KH , dri-devel@lists.freedesktop.org, Android Kernel Team , John Stultz Subject: [PATCH 15/30] staging: sync: Add reference counting to timelines Date: Thu, 28 Feb 2013 16:43:11 -0800 Message-Id: <1362098606-26469-16-git-send-email-john.stultz@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1362098606-26469-1-git-send-email-john.stultz@linaro.org> References: <1362098606-26469-1-git-send-email-john.stultz@linaro.org> X-Gm-Message-State: ALoCoQn9nrDYnE6wbnI3eXeTFYN6M+Mqv7fnvA8kQ37EA21xjSfV6tBMHuKAPaR/o3Y+IGIkkAkj From: Erik Gilling If a timeline is destroyed while fences still hold pts on it, the reworked fence release handler can cause the timeline to be freed before all it's points are freed. Cc: Maarten Lankhorst Cc: Erik Gilling Cc: Daniel Vetter Cc: Rob Clark Cc: Sumit Semwal Cc: Greg KH Cc: dri-devel@lists.freedesktop.org Cc: Android Kernel Team Signed-off-by: Erik Gilling [jstultz: Squished in compiler warning fix] Signed-off-by: John Stultz --- drivers/staging/android/sync.c | 29 +++++++++++++---------------- drivers/staging/android/sync.h | 2 ++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 7d4e9aa..61c27bd 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -51,6 +51,7 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, if (obj == NULL) return NULL; + kref_init(&obj->kref); obj->ops = ops; strlcpy(obj->name, name, sizeof(obj->name)); @@ -68,8 +69,10 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops, } EXPORT_SYMBOL(sync_timeline_create); -static void sync_timeline_free(struct sync_timeline *obj) +static void sync_timeline_free(struct kref *kref) { + struct sync_timeline *obj = + container_of(kref, struct sync_timeline, kref); unsigned long flags; if (obj->ops->release_obj) @@ -84,17 +87,14 @@ static void sync_timeline_free(struct sync_timeline *obj) void sync_timeline_destroy(struct sync_timeline *obj) { - unsigned long flags; - bool needs_freeing; - - spin_lock_irqsave(&obj->child_list_lock, flags); obj->destroyed = true; - needs_freeing = list_empty(&obj->child_list_head); - spin_unlock_irqrestore(&obj->child_list_lock, flags); - if (needs_freeing) - sync_timeline_free(obj); - else + /* + * If this is not the last reference, signal any children + * that their parent is going away. + */ + + if (!kref_put(&obj->kref, sync_timeline_free)) sync_timeline_signal(obj); } EXPORT_SYMBOL(sync_timeline_destroy); @@ -114,7 +114,6 @@ static void sync_timeline_remove_pt(struct sync_pt *pt) { struct sync_timeline *obj = pt->parent; unsigned long flags; - bool needs_freeing = false; spin_lock_irqsave(&obj->active_list_lock, flags); if (!list_empty(&pt->active_list)) @@ -124,13 +123,8 @@ static void sync_timeline_remove_pt(struct sync_pt *pt) spin_lock_irqsave(&obj->child_list_lock, flags); if (!list_empty(&pt->child_list)) { list_del_init(&pt->child_list); - needs_freeing = obj->destroyed && - list_empty(&obj->child_list_head); } spin_unlock_irqrestore(&obj->child_list_lock, flags); - - if (needs_freeing) - sync_timeline_free(obj); } void sync_timeline_signal(struct sync_timeline *obj) @@ -177,6 +171,7 @@ struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size) return NULL; INIT_LIST_HEAD(&pt->active_list); + kref_get(&parent->kref); sync_timeline_add_pt(parent, pt); return pt; @@ -190,6 +185,8 @@ void sync_pt_free(struct sync_pt *pt) sync_timeline_remove_pt(pt); + kref_put(&pt->parent->kref, sync_timeline_free); + kfree(pt); } EXPORT_SYMBOL(sync_pt_free); diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h index 00c9bae..15863a6 100644 --- a/drivers/staging/android/sync.h +++ b/drivers/staging/android/sync.h @@ -80,6 +80,7 @@ struct sync_timeline_ops { /** * struct sync_timeline - sync object + * @kref: reference count on fence. * @ops: ops that define the implementaiton of the sync_timeline * @name: name of the sync_timeline. Useful for debugging * @destoryed: set when sync_timeline is destroyed @@ -90,6 +91,7 @@ struct sync_timeline_ops { * @sync_timeline_list: membership in global sync_timeline_list */ struct sync_timeline { + struct kref kref; const struct sync_timeline_ops *ops; char name[32];