diff options
author | Sami Kiminki <skiminki@nvidia.com> | 2017-11-14 08:56:09 -0500 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-11-15 16:26:19 -0500 |
commit | 69e032653df5aae335764f6346703a1e55c96a2d (patch) | |
tree | 4554eb5596bed720865e70a448674c7b1da4e1b9 /drivers/gpu/nvgpu/common/linux | |
parent | 44f8b11f47bc31aafd0e3d2486125e1d87725fd4 (diff) |
gpu: nvgpu: Add synchronization to comptag alloc and clearing
Comptags allocation and clearing was not synchronized for a
buffer. Fix this race by serializing the operations with the
gk20a_dmabuf_priv lock. While doing that, add an error check in
the cbc_ctrl call.
Bug 1902982
Change-Id: Icd96f1855eb5e5340651bcc85849b5ccc199b821
Signed-off-by: Sami Kiminki <skiminki@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1597904
Reviewed-by: Alex Waterman <alexw@nvidia.com>
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/comptags.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/comptags.c b/drivers/gpu/nvgpu/common/linux/comptags.c index 7d095793..353f6363 100644 --- a/drivers/gpu/nvgpu/common/linux/comptags.c +++ b/drivers/gpu/nvgpu/common/linux/comptags.c | |||
@@ -37,7 +37,9 @@ void gk20a_get_comptags(struct nvgpu_os_buffer *buf, | |||
37 | return; | 37 | return; |
38 | } | 38 | } |
39 | 39 | ||
40 | nvgpu_mutex_acquire(&priv->lock); | ||
40 | *comptags = priv->comptags; | 41 | *comptags = priv->comptags; |
42 | nvgpu_mutex_release(&priv->lock); | ||
41 | } | 43 | } |
42 | 44 | ||
43 | int gk20a_alloc_or_get_comptags(struct gk20a *g, | 45 | int gk20a_alloc_or_get_comptags(struct gk20a *g, |
@@ -55,20 +57,26 @@ int gk20a_alloc_or_get_comptags(struct gk20a *g, | |||
55 | if (!priv) | 57 | if (!priv) |
56 | return -ENOSYS; | 58 | return -ENOSYS; |
57 | 59 | ||
60 | nvgpu_mutex_acquire(&priv->lock); | ||
61 | |||
58 | if (priv->comptags.allocated) { | 62 | if (priv->comptags.allocated) { |
59 | /* | 63 | /* |
60 | * already allocated | 64 | * already allocated |
61 | */ | 65 | */ |
62 | *comptags = priv->comptags; | 66 | *comptags = priv->comptags; |
63 | return 0; | 67 | |
68 | err = 0; | ||
69 | goto exit_locked; | ||
64 | } | 70 | } |
65 | 71 | ||
66 | ctag_granularity = g->ops.fb.compression_page_size(g); | 72 | ctag_granularity = g->ops.fb.compression_page_size(g); |
67 | lines = DIV_ROUND_UP_ULL(buf->dmabuf->size, ctag_granularity); | 73 | lines = DIV_ROUND_UP_ULL(buf->dmabuf->size, ctag_granularity); |
68 | 74 | ||
69 | /* 0-sized buffer? Shouldn't occur, but let's check anyways. */ | 75 | /* 0-sized buffer? Shouldn't occur, but let's check anyways. */ |
70 | if (lines < 1) | 76 | if (lines < 1) { |
71 | return -EINVAL; | 77 | err = -EINVAL; |
78 | goto exit_locked; | ||
79 | } | ||
72 | 80 | ||
73 | /* store the allocator so we can use it when we free the ctags */ | 81 | /* store the allocator so we can use it when we free the ctags */ |
74 | priv->comptag_allocator = allocator; | 82 | priv->comptag_allocator = allocator; |
@@ -89,16 +97,44 @@ int gk20a_alloc_or_get_comptags(struct gk20a *g, | |||
89 | * would not be safe to re-allocate comptags anyways on | 97 | * would not be safe to re-allocate comptags anyways on |
90 | * successive calls, as that would break map aliasing. | 98 | * successive calls, as that would break map aliasing. |
91 | */ | 99 | */ |
100 | err = 0; | ||
92 | priv->comptags.allocated = true; | 101 | priv->comptags.allocated = true; |
93 | 102 | ||
94 | *comptags = priv->comptags; | 103 | *comptags = priv->comptags; |
95 | return 0; | 104 | |
105 | exit_locked: | ||
106 | nvgpu_mutex_release(&priv->lock); | ||
107 | |||
108 | return err; | ||
96 | } | 109 | } |
97 | 110 | ||
98 | void gk20a_mark_comptags_cleared(struct nvgpu_os_buffer *buf) | 111 | bool gk20a_comptags_start_clear(struct nvgpu_os_buffer *buf) |
99 | { | 112 | { |
100 | struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(buf->dmabuf, | 113 | struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(buf->dmabuf, |
101 | buf->dev); | 114 | buf->dev); |
102 | if (priv) | 115 | bool clear_started = false; |
103 | priv->comptags.needs_clear = false; | 116 | |
117 | if (priv) { | ||
118 | nvgpu_mutex_acquire(&priv->lock); | ||
119 | |||
120 | clear_started = priv->comptags.needs_clear; | ||
121 | |||
122 | if (!clear_started) | ||
123 | nvgpu_mutex_release(&priv->lock); | ||
124 | } | ||
125 | |||
126 | return clear_started; | ||
127 | } | ||
128 | |||
129 | void gk20a_comptags_finish_clear(struct nvgpu_os_buffer *buf, | ||
130 | bool clear_successful) | ||
131 | { | ||
132 | struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(buf->dmabuf, | ||
133 | buf->dev); | ||
134 | if (priv) { | ||
135 | if (clear_successful) | ||
136 | priv->comptags.needs_clear = false; | ||
137 | |||
138 | nvgpu_mutex_release(&priv->lock); | ||
139 | } | ||
104 | } | 140 | } |