diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2017-05-16 07:10:42 -0400 |
---|---|---|
committer | Gustavo Padovan <gustavo.padovan@collabora.com> | 2017-05-24 12:08:29 -0400 |
commit | 71ebc9a3795818eab52e81bbcbdfae130ee35d9e (patch) | |
tree | 471cdf0619cc75a44a992c0916beb498b3c894d9 /drivers/dma-buf | |
parent | c16f291dee8b7dc28d4bd0f395ccecf3f898cd21 (diff) |
dma-buf/sync-file: Defer creation of sync_file->name
Constructing the name takes the majority of the time for allocating a
sync_file to wrap a fence, and the name is very rarely used (only via
the sync_file status user interface). To reduce the impact on the common
path (that of creating sync_file to pass around), defer the construction
of the name until it is first used.
v2: Update kerneldoc (kbuild test robot)
v3: sync_debug.c was peeking at the name
v4: Comment upon the potential race between two users of
sync_file_get_name() and claim that such a race is below the level of
notice. However, to prevent any future nuisance, use a global spinlock
to serialize the assignment of the name.
v5: Completely avoid the read/write race by only storing the name passed
in from the user inside sync_file->user_name and passing in a buffer to
dynamically construct the name otherwise.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Cc: Gustavo Padovan <gustavo@padovan.org>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: David Herrmann <dh.herrmann@gmail.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170516111042.24719-1-chris@chris-wilson.co.uk
Diffstat (limited to 'drivers/dma-buf')
-rw-r--r-- | drivers/dma-buf/sync_debug.c | 4 | ||||
-rw-r--r-- | drivers/dma-buf/sync_file.c | 39 |
2 files changed, 35 insertions, 8 deletions
diff --git a/drivers/dma-buf/sync_debug.c b/drivers/dma-buf/sync_debug.c index a0d780ab68c3..82a6e7f6d37f 100644 --- a/drivers/dma-buf/sync_debug.c +++ b/drivers/dma-buf/sync_debug.c | |||
@@ -132,9 +132,11 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj) | |||
132 | static void sync_print_sync_file(struct seq_file *s, | 132 | static void sync_print_sync_file(struct seq_file *s, |
133 | struct sync_file *sync_file) | 133 | struct sync_file *sync_file) |
134 | { | 134 | { |
135 | char buf[128]; | ||
135 | int i; | 136 | int i; |
136 | 137 | ||
137 | seq_printf(s, "[%p] %s: %s\n", sync_file, sync_file->name, | 138 | seq_printf(s, "[%p] %s: %s\n", sync_file, |
139 | sync_file_get_name(sync_file, buf, sizeof(buf)), | ||
138 | sync_status_str(dma_fence_get_status(sync_file->fence))); | 140 | sync_status_str(dma_fence_get_status(sync_file->fence))); |
139 | 141 | ||
140 | if (dma_fence_is_array(sync_file->fence)) { | 142 | if (dma_fence_is_array(sync_file->fence)) { |
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index dc89b1d484e8..545e2c5c4815 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c | |||
@@ -80,11 +80,6 @@ struct sync_file *sync_file_create(struct dma_fence *fence) | |||
80 | 80 | ||
81 | sync_file->fence = dma_fence_get(fence); | 81 | sync_file->fence = dma_fence_get(fence); |
82 | 82 | ||
83 | snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d", | ||
84 | fence->ops->get_driver_name(fence), | ||
85 | fence->ops->get_timeline_name(fence), fence->context, | ||
86 | fence->seqno); | ||
87 | |||
88 | return sync_file; | 83 | return sync_file; |
89 | } | 84 | } |
90 | EXPORT_SYMBOL(sync_file_create); | 85 | EXPORT_SYMBOL(sync_file_create); |
@@ -129,6 +124,36 @@ struct dma_fence *sync_file_get_fence(int fd) | |||
129 | } | 124 | } |
130 | EXPORT_SYMBOL(sync_file_get_fence); | 125 | EXPORT_SYMBOL(sync_file_get_fence); |
131 | 126 | ||
127 | /** | ||
128 | * sync_file_get_name - get the name of the sync_file | ||
129 | * @sync_file: sync_file to get the fence from | ||
130 | * @buf: destination buffer to copy sync_file name into | ||
131 | * @len: available size of destination buffer. | ||
132 | * | ||
133 | * Each sync_file may have a name assigned either by the user (when merging | ||
134 | * sync_files together) or created from the fence it contains. In the latter | ||
135 | * case construction of the name is deferred until use, and so requires | ||
136 | * sync_file_get_name(). | ||
137 | * | ||
138 | * Returns: a string representing the name. | ||
139 | */ | ||
140 | char *sync_file_get_name(struct sync_file *sync_file, char *buf, int len) | ||
141 | { | ||
142 | if (sync_file->user_name[0]) { | ||
143 | strlcpy(buf, sync_file->user_name, len); | ||
144 | } else { | ||
145 | struct dma_fence *fence = sync_file->fence; | ||
146 | |||
147 | snprintf(buf, len, "%s-%s%llu-%d", | ||
148 | fence->ops->get_driver_name(fence), | ||
149 | fence->ops->get_timeline_name(fence), | ||
150 | fence->context, | ||
151 | fence->seqno); | ||
152 | } | ||
153 | |||
154 | return buf; | ||
155 | } | ||
156 | |||
132 | static int sync_file_set_fence(struct sync_file *sync_file, | 157 | static int sync_file_set_fence(struct sync_file *sync_file, |
133 | struct dma_fence **fences, int num_fences) | 158 | struct dma_fence **fences, int num_fences) |
134 | { | 159 | { |
@@ -266,7 +291,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, | |||
266 | goto err; | 291 | goto err; |
267 | } | 292 | } |
268 | 293 | ||
269 | strlcpy(sync_file->name, name, sizeof(sync_file->name)); | 294 | strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name)); |
270 | return sync_file; | 295 | return sync_file; |
271 | 296 | ||
272 | err: | 297 | err: |
@@ -413,7 +438,7 @@ static long sync_file_ioctl_fence_info(struct sync_file *sync_file, | |||
413 | } | 438 | } |
414 | 439 | ||
415 | no_fences: | 440 | no_fences: |
416 | strlcpy(info.name, sync_file->name, sizeof(info.name)); | 441 | sync_file_get_name(sync_file, info.name, sizeof(info.name)); |
417 | info.status = dma_fence_is_signaled(sync_file->fence); | 442 | info.status = dma_fence_is_signaled(sync_file->fence); |
418 | info.num_fences = num_fences; | 443 | info.num_fences = num_fences; |
419 | 444 | ||