diff options
Diffstat (limited to 'drivers/staging/android/sync.c')
| -rw-r--r-- | drivers/staging/android/sync.c | 26 | 
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/staging/android/sync.c b/drivers/staging/android/sync.c index 38e5d3b5ed9..18174f7c871 100644 --- a/drivers/staging/android/sync.c +++ b/drivers/staging/android/sync.c @@ -79,27 +79,31 @@ static void sync_timeline_free(struct kref *kref)  		container_of(kref, struct sync_timeline, kref);  	unsigned long flags; -	if (obj->ops->release_obj) -		obj->ops->release_obj(obj); -  	spin_lock_irqsave(&sync_timeline_list_lock, flags);  	list_del(&obj->sync_timeline_list);  	spin_unlock_irqrestore(&sync_timeline_list_lock, flags); +	if (obj->ops->release_obj) +		obj->ops->release_obj(obj); +  	kfree(obj);  }  void sync_timeline_destroy(struct sync_timeline *obj)  {  	obj->destroyed = true; +	/* +	 * Ensure timeline is marked as destroyed before +	 * changing timeline's fences status. +	 */ +	smp_wmb();  	/* -	 * If this is not the last reference, signal any children -	 * that their parent is going away. +	 * signal any children that their parent is going away.  	 */ +	sync_timeline_signal(obj); -	if (!kref_put(&obj->kref, sync_timeline_free)) -		sync_timeline_signal(obj); +	kref_put(&obj->kref, sync_timeline_free);  }  EXPORT_SYMBOL(sync_timeline_destroy); @@ -384,6 +388,7 @@ static void sync_fence_detach_pts(struct sync_fence *fence)  	list_for_each_safe(pos, n, &fence->pt_list_head) {  		struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); +  		sync_timeline_remove_pt(pt);  	}  } @@ -394,6 +399,7 @@ static void sync_fence_free_pts(struct sync_fence *fence)  	list_for_each_safe(pos, n, &fence->pt_list_head) {  		struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list); +  		sync_pt_free(pt);  	}  } @@ -827,6 +833,7 @@ static long sync_fence_ioctl(struct file *file, unsigned int cmd,  			     unsigned long arg)  {  	struct sync_fence *fence = file->private_data; +  	switch (cmd) {  	case SYNC_IOC_WAIT:  		return sync_fence_ioctl_wait(fence, arg); @@ -856,18 +863,21 @@ static const char *sync_status_str(int status)  static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)  {  	int status = pt->status; +  	seq_printf(s, "  %s%spt %s",  		   fence ? pt->parent->name : "",  		   fence ? "_" : "",  		   sync_status_str(status));  	if (pt->status) {  		struct timeval tv = ktime_to_timeval(pt->timestamp); +  		seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec);  	}  	if (pt->parent->ops->timeline_value_str &&  	    pt->parent->ops->pt_value_str) {  		char value[64]; +  		pt->parent->ops->pt_value_str(pt, value, sizeof(value));  		seq_printf(s, ": %s", value);  		if (fence) { @@ -892,6 +902,7 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)  	if (obj->ops->timeline_value_str) {  		char value[64]; +  		obj->ops->timeline_value_str(obj, value, sizeof(value));  		seq_printf(s, ": %s", value);  	} else if (obj->ops->print_obj) { @@ -1001,6 +1012,7 @@ static void sync_dump(void)  	for (i = 0; i < s.count; i += DUMP_CHUNK) {  		if ((s.count - i) > DUMP_CHUNK) {  			char c = s.buf[i + DUMP_CHUNK]; +  			s.buf[i + DUMP_CHUNK] = 0;  			pr_cont("%s", s.buf + i);  			s.buf[i + DUMP_CHUNK] = c;  | 
