Skip to content

Commit f98c213

Browse files
committed
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Just a couple of dma-buf related fixes and some amdgpu fixes, along with a regression fix for radeon off but default feature, but makes my 30" monitor happy again" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: drm/radeon/mst: cleanup code indentation drm/radeon/mst: fix regression in lane/link handling. drm/amdgpu: add invalidate_page callback for userptrs drm/amdgpu: Revert "remove the userptr rmn->lock" drm/amdgpu: clean up path handling for powerplay drm/amd/powerplay: fix memory leak of tdp_table dma-buf/fence: fix fence_is_later v2 dma-buf: Update docs for SYNC ioctl drm: remove excess description dma-buf, drm, ion: Propagate error code from dma_buf_start_cpu_access() drm/atmel-hlcdc: use helper to get crtc state drm/atomic: use helper to get crtc state
2 parents 11caf57 + 4604202 commit f98c213

File tree

15 files changed

+147
-98
lines changed

15 files changed

+147
-98
lines changed

Documentation/dma-buf-sharing.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,8 @@ Being able to mmap an export dma-buf buffer object has 2 main use-cases:
352352

353353
No special interfaces, userspace simply calls mmap on the dma-buf fd, making
354354
sure that the cache synchronization ioctl (DMA_BUF_IOCTL_SYNC) is *always*
355-
used when the access happens. This is discussed next paragraphs.
355+
used when the access happens. Note that DMA_BUF_IOCTL_SYNC can fail with
356+
-EAGAIN or -EINTR, in which case it must be restarted.
356357

357358
Some systems might need some sort of cache coherency management e.g. when
358359
CPU and GPU domains are being accessed through dma-buf at the same time. To
@@ -366,10 +367,10 @@ Being able to mmap an export dma-buf buffer object has 2 main use-cases:
366367
want (with the new data being consumed by the GPU or say scanout device)
367368
- munmap once you don't need the buffer any more
368369

369-
Therefore, for correctness and optimal performance, systems with the memory
370-
cache shared by the GPU and CPU i.e. the "coherent" and also the
371-
"incoherent" are always required to use SYNC_START and SYNC_END before and
372-
after, respectively, when accessing the mapped address.
370+
For correctness and optimal performance, it is always required to use
371+
SYNC_START and SYNC_END before and after, respectively, when accessing the
372+
mapped address. Userspace cannot rely on coherent access, even when there
373+
are systems where it just works without calling these ioctls.
373374

374375
2. Supporting existing mmap interfaces in importers
375376

drivers/dma-buf/dma-buf.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ static long dma_buf_ioctl(struct file *file,
259259
struct dma_buf *dmabuf;
260260
struct dma_buf_sync sync;
261261
enum dma_data_direction direction;
262+
int ret;
262263

263264
dmabuf = file->private_data;
264265

@@ -285,11 +286,11 @@ static long dma_buf_ioctl(struct file *file,
285286
}
286287

287288
if (sync.flags & DMA_BUF_SYNC_END)
288-
dma_buf_end_cpu_access(dmabuf, direction);
289+
ret = dma_buf_end_cpu_access(dmabuf, direction);
289290
else
290-
dma_buf_begin_cpu_access(dmabuf, direction);
291+
ret = dma_buf_begin_cpu_access(dmabuf, direction);
291292

292-
return 0;
293+
return ret;
293294
default:
294295
return -ENOTTY;
295296
}
@@ -611,15 +612,19 @@ EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access);
611612
* @dmabuf: [in] buffer to complete cpu access for.
612613
* @direction: [in] length of range for cpu access.
613614
*
614-
* This call must always succeed.
615+
* Can return negative error values, returns 0 on success.
615616
*/
616-
void dma_buf_end_cpu_access(struct dma_buf *dmabuf,
617-
enum dma_data_direction direction)
617+
int dma_buf_end_cpu_access(struct dma_buf *dmabuf,
618+
enum dma_data_direction direction)
618619
{
620+
int ret = 0;
621+
619622
WARN_ON(!dmabuf);
620623

621624
if (dmabuf->ops->end_cpu_access)
622-
dmabuf->ops->end_cpu_access(dmabuf, direction);
625+
ret = dmabuf->ops->end_cpu_access(dmabuf, direction);
626+
627+
return ret;
623628
}
624629
EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access);
625630

drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c

Lines changed: 86 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ struct amdgpu_mn {
4848
/* protected by adev->mn_lock */
4949
struct hlist_node node;
5050

51-
/* objects protected by mm->mmap_sem */
51+
/* objects protected by lock */
52+
struct mutex lock;
5253
struct rb_root objects;
5354
};
5455

@@ -72,7 +73,7 @@ static void amdgpu_mn_destroy(struct work_struct *work)
7273
struct amdgpu_bo *bo, *next_bo;
7374

7475
mutex_lock(&adev->mn_lock);
75-
down_write(&rmn->mm->mmap_sem);
76+
mutex_lock(&rmn->lock);
7677
hash_del(&rmn->node);
7778
rbtree_postorder_for_each_entry_safe(node, next_node, &rmn->objects,
7879
it.rb) {
@@ -82,7 +83,7 @@ static void amdgpu_mn_destroy(struct work_struct *work)
8283
}
8384
kfree(node);
8485
}
85-
up_write(&rmn->mm->mmap_sem);
86+
mutex_unlock(&rmn->lock);
8687
mutex_unlock(&adev->mn_lock);
8788
mmu_notifier_unregister_no_release(&rmn->mn, rmn->mm);
8889
kfree(rmn);
@@ -104,6 +105,76 @@ static void amdgpu_mn_release(struct mmu_notifier *mn,
104105
schedule_work(&rmn->work);
105106
}
106107

108+
/**
109+
* amdgpu_mn_invalidate_node - unmap all BOs of a node
110+
*
111+
* @node: the node with the BOs to unmap
112+
*
113+
* We block for all BOs and unmap them by move them
114+
* into system domain again.
115+
*/
116+
static void amdgpu_mn_invalidate_node(struct amdgpu_mn_node *node,
117+
unsigned long start,
118+
unsigned long end)
119+
{
120+
struct amdgpu_bo *bo;
121+
long r;
122+
123+
list_for_each_entry(bo, &node->bos, mn_list) {
124+
125+
if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start, end))
126+
continue;
127+
128+
r = amdgpu_bo_reserve(bo, true);
129+
if (r) {
130+
DRM_ERROR("(%ld) failed to reserve user bo\n", r);
131+
continue;
132+
}
133+
134+
r = reservation_object_wait_timeout_rcu(bo->tbo.resv,
135+
true, false, MAX_SCHEDULE_TIMEOUT);
136+
if (r <= 0)
137+
DRM_ERROR("(%ld) failed to wait for user bo\n", r);
138+
139+
amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU);
140+
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
141+
if (r)
142+
DRM_ERROR("(%ld) failed to validate user bo\n", r);
143+
144+
amdgpu_bo_unreserve(bo);
145+
}
146+
}
147+
148+
/**
149+
* amdgpu_mn_invalidate_page - callback to notify about mm change
150+
*
151+
* @mn: our notifier
152+
* @mn: the mm this callback is about
153+
* @address: address of invalidate page
154+
*
155+
* Invalidation of a single page. Blocks for all BOs mapping it
156+
* and unmap them by move them into system domain again.
157+
*/
158+
static void amdgpu_mn_invalidate_page(struct mmu_notifier *mn,
159+
struct mm_struct *mm,
160+
unsigned long address)
161+
{
162+
struct amdgpu_mn *rmn = container_of(mn, struct amdgpu_mn, mn);
163+
struct interval_tree_node *it;
164+
165+
mutex_lock(&rmn->lock);
166+
167+
it = interval_tree_iter_first(&rmn->objects, address, address);
168+
if (it) {
169+
struct amdgpu_mn_node *node;
170+
171+
node = container_of(it, struct amdgpu_mn_node, it);
172+
amdgpu_mn_invalidate_node(node, address, address);
173+
}
174+
175+
mutex_unlock(&rmn->lock);
176+
}
177+
107178
/**
108179
* amdgpu_mn_invalidate_range_start - callback to notify about mm change
109180
*
@@ -126,44 +197,24 @@ static void amdgpu_mn_invalidate_range_start(struct mmu_notifier *mn,
126197
/* notification is exclusive, but interval is inclusive */
127198
end -= 1;
128199

200+
mutex_lock(&rmn->lock);
201+
129202
it = interval_tree_iter_first(&rmn->objects, start, end);
130203
while (it) {
131204
struct amdgpu_mn_node *node;
132-
struct amdgpu_bo *bo;
133-
long r;
134205

135206
node = container_of(it, struct amdgpu_mn_node, it);
136207
it = interval_tree_iter_next(it, start, end);
137208

138-
list_for_each_entry(bo, &node->bos, mn_list) {
139-
140-
if (!amdgpu_ttm_tt_affect_userptr(bo->tbo.ttm, start,
141-
end))
142-
continue;
143-
144-
r = amdgpu_bo_reserve(bo, true);
145-
if (r) {
146-
DRM_ERROR("(%ld) failed to reserve user bo\n", r);
147-
continue;
148-
}
149-
150-
r = reservation_object_wait_timeout_rcu(bo->tbo.resv,
151-
true, false, MAX_SCHEDULE_TIMEOUT);
152-
if (r <= 0)
153-
DRM_ERROR("(%ld) failed to wait for user bo\n", r);
154-
155-
amdgpu_ttm_placement_from_domain(bo, AMDGPU_GEM_DOMAIN_CPU);
156-
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
157-
if (r)
158-
DRM_ERROR("(%ld) failed to validate user bo\n", r);
159-
160-
amdgpu_bo_unreserve(bo);
161-
}
209+
amdgpu_mn_invalidate_node(node, start, end);
162210
}
211+
212+
mutex_unlock(&rmn->lock);
163213
}
164214

165215
static const struct mmu_notifier_ops amdgpu_mn_ops = {
166216
.release = amdgpu_mn_release,
217+
.invalidate_page = amdgpu_mn_invalidate_page,
167218
.invalidate_range_start = amdgpu_mn_invalidate_range_start,
168219
};
169220

@@ -196,6 +247,7 @@ static struct amdgpu_mn *amdgpu_mn_get(struct amdgpu_device *adev)
196247
rmn->adev = adev;
197248
rmn->mm = mm;
198249
rmn->mn.ops = &amdgpu_mn_ops;
250+
mutex_init(&rmn->lock);
199251
rmn->objects = RB_ROOT;
200252

201253
r = __mmu_notifier_register(&rmn->mn, mm);
@@ -242,7 +294,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
242294

243295
INIT_LIST_HEAD(&bos);
244296

245-
down_write(&rmn->mm->mmap_sem);
297+
mutex_lock(&rmn->lock);
246298

247299
while ((it = interval_tree_iter_first(&rmn->objects, addr, end))) {
248300
kfree(node);
@@ -256,7 +308,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
256308
if (!node) {
257309
node = kmalloc(sizeof(struct amdgpu_mn_node), GFP_KERNEL);
258310
if (!node) {
259-
up_write(&rmn->mm->mmap_sem);
311+
mutex_unlock(&rmn->lock);
260312
return -ENOMEM;
261313
}
262314
}
@@ -271,7 +323,7 @@ int amdgpu_mn_register(struct amdgpu_bo *bo, unsigned long addr)
271323

272324
interval_tree_insert(&node->it, &rmn->objects);
273325

274-
up_write(&rmn->mm->mmap_sem);
326+
mutex_unlock(&rmn->lock);
275327

276328
return 0;
277329
}
@@ -297,7 +349,7 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo)
297349
return;
298350
}
299351

300-
down_write(&rmn->mm->mmap_sem);
352+
mutex_lock(&rmn->lock);
301353

302354
/* save the next list entry for later */
303355
head = bo->mn_list.next;
@@ -312,6 +364,6 @@ void amdgpu_mn_unregister(struct amdgpu_bo *bo)
312364
kfree(node);
313365
}
314366

315-
up_write(&rmn->mm->mmap_sem);
367+
mutex_unlock(&rmn->lock);
316368
mutex_unlock(&adev->mn_lock);
317369
}

drivers/gpu/drm/amd/powerplay/Makefile

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11

22
subdir-ccflags-y += -Iinclude/drm \
3-
-Idrivers/gpu/drm/amd/powerplay/inc/ \
4-
-Idrivers/gpu/drm/amd/include/asic_reg \
5-
-Idrivers/gpu/drm/amd/include \
6-
-Idrivers/gpu/drm/amd/powerplay/smumgr\
7-
-Idrivers/gpu/drm/amd/powerplay/hwmgr \
8-
-Idrivers/gpu/drm/amd/powerplay/eventmgr
3+
-I$(FULL_AMD_PATH)/powerplay/inc/ \
4+
-I$(FULL_AMD_PATH)/include/asic_reg \
5+
-I$(FULL_AMD_PATH)/include \
6+
-I$(FULL_AMD_PATH)/powerplay/smumgr\
7+
-I$(FULL_AMD_PATH)/powerplay/hwmgr \
8+
-I$(FULL_AMD_PATH)/powerplay/eventmgr
99

1010
AMD_PP_PATH = ../powerplay
1111

1212
PP_LIBS = smumgr hwmgr eventmgr
1313

14-
AMD_POWERPLAY = $(addsuffix /Makefile,$(addprefix drivers/gpu/drm/amd/powerplay/,$(PP_LIBS)))
14+
AMD_POWERPLAY = $(addsuffix /Makefile,$(addprefix $(FULL_AMD_PATH)/powerplay/,$(PP_LIBS)))
1515

1616
include $(AMD_POWERPLAY)
1717

drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,8 +512,10 @@ static int get_cac_tdp_table(
512512

513513
hwmgr->dyn_state.cac_dtp_table = kzalloc(table_size, GFP_KERNEL);
514514

515-
if (NULL == hwmgr->dyn_state.cac_dtp_table)
515+
if (NULL == hwmgr->dyn_state.cac_dtp_table) {
516+
kfree(tdp_table);
516517
return -ENOMEM;
518+
}
517519

518520
memset(hwmgr->dyn_state.cac_dtp_table, 0x00, table_size);
519521

drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p,
558558
if (!state->base.crtc || !fb)
559559
return 0;
560560

561-
crtc_state = s->state->crtc_states[drm_crtc_index(s->crtc)];
561+
crtc_state = drm_atomic_get_existing_crtc_state(s->state, s->crtc);
562562
mode = &crtc_state->adjusted_mode;
563563

564564
state->src_x = s->src_x;

drivers/gpu/drm/drm_atomic.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,6 @@ EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
380380
* drm_atomic_replace_property_blob - replace a blob property
381381
* @blob: a pointer to the member blob to be replaced
382382
* @new_blob: the new blob to replace with
383-
* @expected_size: the expected size of the new blob
384383
* @replaced: whether the blob has been replaced
385384
*
386385
* RETURNS:

drivers/gpu/drm/drm_atomic_helper.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
6767
struct drm_crtc_state *crtc_state;
6868

6969
if (plane->state->crtc) {
70-
crtc_state = state->crtc_states[drm_crtc_index(plane->state->crtc)];
70+
crtc_state = drm_atomic_get_existing_crtc_state(state,
71+
plane->state->crtc);
7172

7273
if (WARN_ON(!crtc_state))
7374
return;
@@ -76,8 +77,8 @@ drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
7677
}
7778

7879
if (plane_state->crtc) {
79-
crtc_state =
80-
state->crtc_states[drm_crtc_index(plane_state->crtc)];
80+
crtc_state = drm_atomic_get_existing_crtc_state(state,
81+
plane_state->crtc);
8182

8283
if (WARN_ON(!crtc_state))
8384
return;
@@ -374,8 +375,8 @@ mode_fixup(struct drm_atomic_state *state)
374375
if (!conn_state->crtc || !conn_state->best_encoder)
375376
continue;
376377

377-
crtc_state =
378-
state->crtc_states[drm_crtc_index(conn_state->crtc)];
378+
crtc_state = drm_atomic_get_existing_crtc_state(state,
379+
conn_state->crtc);
379380

380381
/*
381382
* Each encoder has at most one connector (since we always steal
@@ -679,7 +680,8 @@ disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
679680
if (!old_conn_state->crtc)
680681
continue;
681682

682-
old_crtc_state = old_state->crtc_states[drm_crtc_index(old_conn_state->crtc)];
683+
old_crtc_state = drm_atomic_get_existing_crtc_state(old_state,
684+
old_conn_state->crtc);
683685

684686
if (!old_crtc_state->active ||
685687
!drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state))

0 commit comments

Comments
 (0)