From d0b2f91bede3bd5e3d24dd6803e56eee959c1797 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Thu, 20 Oct 2016 00:10:27 -0300 Subject: Linux-libre 4.8.2-gnu --- drivers/staging/android/Kconfig | 17 +- drivers/staging/android/Makefile | 3 +- drivers/staging/android/ashmem.c | 2 +- drivers/staging/android/lowmemorykiller.c | 12 +- drivers/staging/android/sw_sync.c | 341 ++++++++++++++++++++++++++---- drivers/staging/android/sync_debug.c | 165 ++------------- drivers/staging/android/sync_debug.h | 84 ++++++++ drivers/staging/android/trace/sync.h | 14 +- 8 files changed, 415 insertions(+), 223 deletions(-) create mode 100644 drivers/staging/android/sync_debug.h (limited to 'drivers/staging/android') diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig index 6480f60eb..06e41d24e 100644 --- a/drivers/staging/android/Kconfig +++ b/drivers/staging/android/Kconfig @@ -24,26 +24,19 @@ config ANDROID_LOW_MEMORY_KILLER scripts (/init.rc), and it defines priority values with minimum free memory size for each priority. -config SYNC - bool "Synchronization framework" - default n - select ANON_INODES - select DMA_SHARED_BUFFER - ---help--- - This option enables the framework for synchronization between multiple - drivers. Sync implementations can take advantage of hardware - synchronization built into devices like GPUs. - config SW_SYNC - bool "Software synchronization objects" + bool "Software synchronization framework" default n - depends on SYNC depends on SYNC_FILE + depends on DEBUG_FS ---help--- A sync object driver that uses a 32bit counter to coordinate synchronization. Useful when there is no hardware primitive backing the synchronization. + WARNING: improper use of this can result in deadlocking kernel + drivers from userspace. Intended for test and debug only. + source "drivers/staging/android/ion/Kconfig" endif # if ANDROID diff --git a/drivers/staging/android/Makefile b/drivers/staging/android/Makefile index 980d6dc4b..7ca61b77a 100644 --- a/drivers/staging/android/Makefile +++ b/drivers/staging/android/Makefile @@ -4,5 +4,4 @@ obj-y += ion/ obj-$(CONFIG_ASHMEM) += ashmem.o obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o -obj-$(CONFIG_SYNC) += sync.o sync_debug.o -obj-$(CONFIG_SW_SYNC) += sw_sync.o +obj-$(CONFIG_SW_SYNC) += sw_sync.o sync_debug.o diff --git a/drivers/staging/android/ashmem.c b/drivers/staging/android/ashmem.c index 2650202d7..ca9a53c03 100644 --- a/drivers/staging/android/ashmem.c +++ b/drivers/staging/android/ashmem.c @@ -400,7 +400,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) name = asma->name; /* ... and allocate the backing shmem file */ - vmfile = shmem_file_setup(name, asma->size, vma->vm_flags, 0); + vmfile = shmem_file_setup(name, asma->size, vma->vm_flags); if (IS_ERR(vmfile)) { ret = PTR_ERR(vmfile); goto out; diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 24d2745e9..45a1b4ec4 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -72,10 +72,10 @@ static unsigned long lowmem_deathpending_timeout; static unsigned long lowmem_count(struct shrinker *s, struct shrink_control *sc) { - return global_page_state(NR_ACTIVE_ANON) + - global_page_state(NR_ACTIVE_FILE) + - global_page_state(NR_INACTIVE_ANON) + - global_page_state(NR_INACTIVE_FILE); + return global_node_page_state(NR_ACTIVE_ANON) + + global_node_page_state(NR_ACTIVE_FILE) + + global_node_page_state(NR_INACTIVE_ANON) + + global_node_page_state(NR_INACTIVE_FILE); } static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) @@ -91,8 +91,8 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) short selected_oom_score_adj; int array_size = ARRAY_SIZE(lowmem_adj); int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages; - int other_file = global_page_state(NR_FILE_PAGES) - - global_page_state(NR_SHMEM) - + int other_file = global_node_page_state(NR_FILE_PAGES) - + global_node_page_state(NR_SHMEM) - total_swapcache_pages(); if (lowmem_adj_size < array_size) diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c index af39ff58f..115c91747 100644 --- a/drivers/staging/android/sw_sync.c +++ b/drivers/staging/android/sw_sync.c @@ -1,5 +1,5 @@ /* - * drivers/base/sw_sync.c + * drivers/dma-buf/sw_sync.c * * Copyright (C) 2012 Google, Inc. * @@ -14,76 +14,331 @@ * */ -#include -#include -#include #include #include -#include -#include #include +#include +#include -#include "sw_sync.h" +#include "sync_debug.h" -struct fence *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value) +#define CREATE_TRACE_POINTS +#include "trace/sync.h" + +struct sw_sync_create_fence_data { + __u32 value; + char name[32]; + __s32 fence; /* fd of new fence */ +}; + +#define SW_SYNC_IOC_MAGIC 'W' + +#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\ + struct sw_sync_create_fence_data) +#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32) + +static const struct fence_ops timeline_fence_ops; + +static inline struct sync_pt *fence_to_sync_pt(struct fence *fence) +{ + if (fence->ops != &timeline_fence_ops) + return NULL; + return container_of(fence, struct sync_pt, base); +} + +/** + * sync_timeline_create() - creates a sync object + * @name: sync_timeline name + * + * Creates a new sync_timeline. Returns the sync_timeline object or NULL in + * case of error. + */ +struct sync_timeline *sync_timeline_create(const char *name) +{ + struct sync_timeline *obj; + + obj = kzalloc(sizeof(*obj), GFP_KERNEL); + if (!obj) + return NULL; + + kref_init(&obj->kref); + obj->context = fence_context_alloc(1); + strlcpy(obj->name, name, sizeof(obj->name)); + + INIT_LIST_HEAD(&obj->child_list_head); + INIT_LIST_HEAD(&obj->active_list_head); + spin_lock_init(&obj->child_list_lock); + + sync_timeline_debug_add(obj); + + return obj; +} + +static void sync_timeline_free(struct kref *kref) +{ + struct sync_timeline *obj = + container_of(kref, struct sync_timeline, kref); + + sync_timeline_debug_remove(obj); + + kfree(obj); +} + +static void sync_timeline_get(struct sync_timeline *obj) +{ + kref_get(&obj->kref); +} + +static void sync_timeline_put(struct sync_timeline *obj) +{ + kref_put(&obj->kref, sync_timeline_free); +} + +/** + * sync_timeline_signal() - signal a status change on a sync_timeline + * @obj: sync_timeline to signal + * @inc: num to increment on timeline->value + * + * A sync implementation should call this any time one of it's fences + * has signaled or has an error condition. + */ +static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc) +{ + unsigned long flags; + struct sync_pt *pt, *next; + + trace_sync_timeline(obj); + + spin_lock_irqsave(&obj->child_list_lock, flags); + + obj->value += inc; + + list_for_each_entry_safe(pt, next, &obj->active_list_head, + active_list) { + if (fence_is_signaled_locked(&pt->base)) + list_del_init(&pt->active_list); + } + + spin_unlock_irqrestore(&obj->child_list_lock, flags); +} + +/** + * sync_pt_create() - creates a sync pt + * @parent: fence's parent sync_timeline + * @size: size to allocate for this pt + * @inc: value of the fence + * + * Creates a new sync_pt as a child of @parent. @size bytes will be + * allocated allowing for implementation specific data to be kept after + * the generic sync_timeline struct. Returns the sync_pt object or + * NULL in case of error. + */ +static struct sync_pt *sync_pt_create(struct sync_timeline *obj, int size, + unsigned int value) +{ + unsigned long flags; + struct sync_pt *pt; + + if (size < sizeof(*pt)) + return NULL; + + pt = kzalloc(size, GFP_KERNEL); + if (!pt) + return NULL; + + spin_lock_irqsave(&obj->child_list_lock, flags); + sync_timeline_get(obj); + fence_init(&pt->base, &timeline_fence_ops, &obj->child_list_lock, + obj->context, value); + list_add_tail(&pt->child_list, &obj->child_list_head); + INIT_LIST_HEAD(&pt->active_list); + spin_unlock_irqrestore(&obj->child_list_lock, flags); + return pt; +} + +static const char *timeline_fence_get_driver_name(struct fence *fence) +{ + return "sw_sync"; +} + +static const char *timeline_fence_get_timeline_name(struct fence *fence) +{ + struct sync_timeline *parent = fence_parent(fence); + + return parent->name; +} + +static void timeline_fence_release(struct fence *fence) { - struct sw_sync_pt *pt; + struct sync_pt *pt = fence_to_sync_pt(fence); + struct sync_timeline *parent = fence_parent(fence); + unsigned long flags; - pt = (struct sw_sync_pt *) - sync_pt_create(&obj->obj, sizeof(struct sw_sync_pt)); + spin_lock_irqsave(fence->lock, flags); + list_del(&pt->child_list); + if (WARN_ON_ONCE(!list_empty(&pt->active_list))) + list_del(&pt->active_list); + spin_unlock_irqrestore(fence->lock, flags); - pt->value = value; + sync_timeline_put(parent); + fence_free(fence); +} + +static bool timeline_fence_signaled(struct fence *fence) +{ + struct sync_timeline *parent = fence_parent(fence); - return (struct fence *)pt; + return (fence->seqno > parent->value) ? false : true; } -EXPORT_SYMBOL(sw_sync_pt_create); -static int sw_sync_fence_has_signaled(struct fence *fence) +static bool timeline_fence_enable_signaling(struct fence *fence) { - struct sw_sync_pt *pt = (struct sw_sync_pt *)fence; - struct sw_sync_timeline *obj = - (struct sw_sync_timeline *)fence_parent(fence); + struct sync_pt *pt = fence_to_sync_pt(fence); + struct sync_timeline *parent = fence_parent(fence); - return (pt->value > obj->value) ? 0 : 1; + if (timeline_fence_signaled(fence)) + return false; + + list_add_tail(&pt->active_list, &parent->active_list_head); + return true; } -static void sw_sync_timeline_value_str(struct sync_timeline *sync_timeline, - char *str, int size) +static void timeline_fence_value_str(struct fence *fence, + char *str, int size) { - struct sw_sync_timeline *timeline = - (struct sw_sync_timeline *)sync_timeline; - snprintf(str, size, "%d", timeline->value); + snprintf(str, size, "%d", fence->seqno); } -static void sw_sync_fence_value_str(struct fence *fence, char *str, int size) +static void timeline_fence_timeline_value_str(struct fence *fence, + char *str, int size) { - struct sw_sync_pt *pt = (struct sw_sync_pt *)fence; + struct sync_timeline *parent = fence_parent(fence); - snprintf(str, size, "%d", pt->value); + snprintf(str, size, "%d", parent->value); } -static struct sync_timeline_ops sw_sync_timeline_ops = { - .driver_name = "sw_sync", - .has_signaled = sw_sync_fence_has_signaled, - .timeline_value_str = sw_sync_timeline_value_str, - .fence_value_str = sw_sync_fence_value_str, +static const struct fence_ops timeline_fence_ops = { + .get_driver_name = timeline_fence_get_driver_name, + .get_timeline_name = timeline_fence_get_timeline_name, + .enable_signaling = timeline_fence_enable_signaling, + .signaled = timeline_fence_signaled, + .wait = fence_default_wait, + .release = timeline_fence_release, + .fence_value_str = timeline_fence_value_str, + .timeline_value_str = timeline_fence_timeline_value_str, }; -struct sw_sync_timeline *sw_sync_timeline_create(const char *name) +/* + * *WARNING* + * + * improper use of this can result in deadlocking kernel drivers from userspace. + */ + +/* opening sw_sync create a new sync obj */ +static int sw_sync_debugfs_open(struct inode *inode, struct file *file) { - struct sw_sync_timeline *obj = (struct sw_sync_timeline *) - sync_timeline_create(&sw_sync_timeline_ops, - sizeof(struct sw_sync_timeline), - name); + struct sync_timeline *obj; + char task_comm[TASK_COMM_LEN]; - return obj; + get_task_comm(task_comm, current); + + obj = sync_timeline_create(task_comm); + if (!obj) + return -ENOMEM; + + file->private_data = obj; + + return 0; } -EXPORT_SYMBOL(sw_sync_timeline_create); -void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc) +static int sw_sync_debugfs_release(struct inode *inode, struct file *file) { - obj->value += inc; + struct sync_timeline *obj = file->private_data; + + smp_wmb(); + + sync_timeline_put(obj); + return 0; +} + +static long sw_sync_ioctl_create_fence(struct sync_timeline *obj, + unsigned long arg) +{ + int fd = get_unused_fd_flags(O_CLOEXEC); + int err; + struct sync_pt *pt; + struct sync_file *sync_file; + struct sw_sync_create_fence_data data; + + if (fd < 0) + return fd; + + if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { + err = -EFAULT; + goto err; + } + + pt = sync_pt_create(obj, sizeof(*pt), data.value); + if (!pt) { + err = -ENOMEM; + goto err; + } + + sync_file = sync_file_create(&pt->base); + if (!sync_file) { + fence_put(&pt->base); + err = -ENOMEM; + goto err; + } + + data.fence = fd; + if (copy_to_user((void __user *)arg, &data, sizeof(data))) { + fput(sync_file->file); + err = -EFAULT; + goto err; + } + + fd_install(fd, sync_file->file); + + return 0; + +err: + put_unused_fd(fd); + return err; +} - sync_timeline_signal(&obj->obj); +static long sw_sync_ioctl_inc(struct sync_timeline *obj, unsigned long arg) +{ + u32 value; + + if (copy_from_user(&value, (void __user *)arg, sizeof(value))) + return -EFAULT; + + sync_timeline_signal(obj, value); + + return 0; +} + +static long sw_sync_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct sync_timeline *obj = file->private_data; + + switch (cmd) { + case SW_SYNC_IOC_CREATE_FENCE: + return sw_sync_ioctl_create_fence(obj, arg); + + case SW_SYNC_IOC_INC: + return sw_sync_ioctl_inc(obj, arg); + + default: + return -ENOTTY; + } } -EXPORT_SYMBOL(sw_sync_timeline_inc); + +const struct file_operations sw_sync_debugfs_fops = { + .open = sw_sync_debugfs_open, + .release = sw_sync_debugfs_release, + .unlocked_ioctl = sw_sync_ioctl, + .compat_ioctl = sw_sync_ioctl, +}; diff --git a/drivers/staging/android/sync_debug.c b/drivers/staging/android/sync_debug.c index 5f57499c9..4c5a85595 100644 --- a/drivers/staging/android/sync_debug.c +++ b/drivers/staging/android/sync_debug.c @@ -15,21 +15,7 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "sw_sync.h" - -#ifdef CONFIG_DEBUG_FS +#include "sync_debug.h" static struct dentry *dbgfs; @@ -105,7 +91,7 @@ static void sync_print_fence(struct seq_file *s, struct fence *fence, bool show) seq_printf(s, "@%lld.%09ld", (s64)ts64.tv_sec, ts64.tv_nsec); } - if ((!fence || fence->ops->timeline_value_str) && + if (fence->ops->timeline_value_str && fence->ops->fence_value_str) { char value[64]; bool success; @@ -113,10 +99,9 @@ static void sync_print_fence(struct seq_file *s, struct fence *fence, bool show) fence->ops->fence_value_str(fence, value, sizeof(value)); success = strlen(value); - if (success) + if (success) { seq_printf(s, ": %s", value); - if (success && fence) { fence->ops->timeline_value_str(fence, value, sizeof(value)); @@ -133,22 +118,13 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) struct list_head *pos; unsigned long flags; - seq_printf(s, "%s %s", obj->name, obj->ops->driver_name); - - if (obj->ops->timeline_value_str) { - char value[64]; - - obj->ops->timeline_value_str(obj, value, sizeof(value)); - seq_printf(s, ": %s", value); - } - - seq_puts(s, "\n"); + seq_printf(s, "%s: %d\n", obj->name, obj->value); spin_lock_irqsave(&obj->child_list_lock, flags); list_for_each(pos, &obj->child_list_head) { - struct fence *fence = - container_of(pos, struct fence, child_list); - sync_print_fence(s, fence, false); + struct sync_pt *pt = + container_of(pos, struct sync_pt, child_list); + sync_print_fence(s, &pt->base, false); } spin_unlock_irqrestore(&obj->child_list_lock, flags); } @@ -209,126 +185,19 @@ static const struct file_operations sync_info_debugfs_fops = { .release = single_release, }; -/* - * *WARNING* - * - * improper use of this can result in deadlocking kernel drivers from userspace. - */ - -/* opening sw_sync create a new sync obj */ -static int sw_sync_debugfs_open(struct inode *inode, struct file *file) -{ - struct sw_sync_timeline *obj; - char task_comm[TASK_COMM_LEN]; - - get_task_comm(task_comm, current); - - obj = sw_sync_timeline_create(task_comm); - if (!obj) - return -ENOMEM; - - file->private_data = obj; - - return 0; -} - -static int sw_sync_debugfs_release(struct inode *inode, struct file *file) -{ - struct sw_sync_timeline *obj = file->private_data; - - sync_timeline_destroy(&obj->obj); - return 0; -} - -static long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, - unsigned long arg) -{ - int fd = get_unused_fd_flags(O_CLOEXEC); - int err; - struct fence *fence; - struct sync_file *sync_file; - struct sw_sync_create_fence_data data; - - if (fd < 0) - return fd; - - if (copy_from_user(&data, (void __user *)arg, sizeof(data))) { - err = -EFAULT; - goto err; - } - - fence = sw_sync_pt_create(obj, data.value); - if (!fence) { - err = -ENOMEM; - goto err; - } - - sync_file = sync_file_create(fence); - if (!sync_file) { - fence_put(fence); - err = -ENOMEM; - goto err; - } - - data.fence = fd; - if (copy_to_user((void __user *)arg, &data, sizeof(data))) { - fput(sync_file->file); - err = -EFAULT; - goto err; - } - - fd_install(fd, sync_file->file); - - return 0; - -err: - put_unused_fd(fd); - return err; -} - -static long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg) -{ - u32 value; - - if (copy_from_user(&value, (void __user *)arg, sizeof(value))) - return -EFAULT; - - sw_sync_timeline_inc(obj, value); - - return 0; -} - -static long sw_sync_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - struct sw_sync_timeline *obj = file->private_data; - - switch (cmd) { - case SW_SYNC_IOC_CREATE_FENCE: - return sw_sync_ioctl_create_fence(obj, arg); - - case SW_SYNC_IOC_INC: - return sw_sync_ioctl_inc(obj, arg); - - default: - return -ENOTTY; - } -} - -static const struct file_operations sw_sync_debugfs_fops = { - .open = sw_sync_debugfs_open, - .release = sw_sync_debugfs_release, - .unlocked_ioctl = sw_sync_ioctl, - .compat_ioctl = sw_sync_ioctl, -}; - static __init int sync_debugfs_init(void) { dbgfs = debugfs_create_dir("sync", NULL); - debugfs_create_file("info", 0444, dbgfs, NULL, &sync_info_debugfs_fops); - debugfs_create_file("sw_sync", 0644, dbgfs, NULL, - &sw_sync_debugfs_fops); + /* + * The debugfs files won't ever get removed and thus, there is + * no need to protect it against removal races. The use of + * debugfs_create_file_unsafe() is actually safe here. + */ + debugfs_create_file_unsafe("info", 0444, dbgfs, NULL, + &sync_info_debugfs_fops); + debugfs_create_file_unsafe("sw_sync", 0644, dbgfs, NULL, + &sw_sync_debugfs_fops); return 0; } @@ -359,5 +228,3 @@ void sync_dump(void) } } } - -#endif diff --git a/drivers/staging/android/sync_debug.h b/drivers/staging/android/sync_debug.h new file mode 100644 index 000000000..fab66396d --- /dev/null +++ b/drivers/staging/android/sync_debug.h @@ -0,0 +1,84 @@ +/* + * include/linux/sync.h + * + * Copyright (C) 2012 Google, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef _LINUX_SYNC_H +#define _LINUX_SYNC_H + +#include +#include +#include + +#include +#include + +/** + * struct sync_timeline - sync object + * @kref: reference count on fence. + * @name: name of the sync_timeline. Useful for debugging + * @child_list_head: list of children sync_pts for this sync_timeline + * @child_list_lock: lock protecting @child_list_head and fence.status + * @active_list_head: list of active (unsignaled/errored) sync_pts + * @sync_timeline_list: membership in global sync_timeline_list + */ +struct sync_timeline { + struct kref kref; + char name[32]; + + /* protected by child_list_lock */ + u64 context; + int value; + + struct list_head child_list_head; + spinlock_t child_list_lock; + + struct list_head active_list_head; + + struct list_head sync_timeline_list; +}; + +static inline struct sync_timeline *fence_parent(struct fence *fence) +{ + return container_of(fence->lock, struct sync_timeline, + child_list_lock); +} + +/** + * struct sync_pt - sync_pt object + * @base: base fence object + * @child_list: sync timeline child's list + * @active_list: sync timeline active child's list + */ +struct sync_pt { + struct fence base; + struct list_head child_list; + struct list_head active_list; +}; + +#ifdef CONFIG_SW_SYNC + +extern const struct file_operations sw_sync_debugfs_fops; + +void sync_timeline_debug_add(struct sync_timeline *obj); +void sync_timeline_debug_remove(struct sync_timeline *obj); +void sync_file_debug_add(struct sync_file *fence); +void sync_file_debug_remove(struct sync_file *fence); +void sync_dump(void); + +#else +# define sync_timeline_debug_add(obj) +# define sync_timeline_debug_remove(obj) +# define sync_file_debug_add(fence) +# define sync_file_debug_remove(fence) +# define sync_dump() +#endif + +#endif /* _LINUX_SYNC_H */ diff --git a/drivers/staging/android/trace/sync.h b/drivers/staging/android/trace/sync.h index a0f80f416..6b5ce9640 100644 --- a/drivers/staging/android/trace/sync.h +++ b/drivers/staging/android/trace/sync.h @@ -5,7 +5,7 @@ #if !defined(_TRACE_SYNC_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_SYNC_H -#include "../sync.h" +#include "../sync_debug.h" #include TRACE_EVENT(sync_timeline, @@ -15,21 +15,15 @@ TRACE_EVENT(sync_timeline, TP_STRUCT__entry( __string(name, timeline->name) - __array(char, value, 32) + __field(u32, value) ), TP_fast_assign( __assign_str(name, timeline->name); - if (timeline->ops->timeline_value_str) { - timeline->ops->timeline_value_str(timeline, - __entry->value, - sizeof(__entry->value)); - } else { - __entry->value[0] = '\0'; - } + __entry->value = timeline->value; ), - TP_printk("name=%s value=%s", __get_str(name), __entry->value) + TP_printk("name=%s value=%d", __get_str(name), __entry->value) ); #endif /* if !defined(_TRACE_SYNC_H) || defined(TRACE_HEADER_MULTI_READ) */ -- cgit v1.2.3-54-g00ecf