Skip to content

Commit b7dc79a

Browse files
committed
Merge tag 'drm-misc-fixes-2025-07-10' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes
drm-misc-fixes for v6.16-rc6 or final: - Fix nouveau fail on debugfs errors. - Magic 50 ms to fix nouveau suspend. - Call rust destructor on drm device release. - Fix DMA api error handling in tegra/nvdec. - Fix PVR device reset. - Habanalabs maintainer update. - Small memory leak fix when nouveau acpi init fails. - Do not attempt to bind to any PCI device with AGP capability. - Make FB's acquire handles on backing object, same as i915/xe already does. - Fix race in drm_gem_handle_create_tail. Signed-off-by: Simona Vetter <[email protected]> From: Maarten Lankhorst <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 14e85fa + bd46cec commit b7dc79a

File tree

17 files changed

+130
-62
lines changed

17 files changed

+130
-62
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10504,7 +10504,7 @@ S: Maintained
1050410504
F: block/partitions/efi.*
1050510505

1050610506
HABANALABS PCI DRIVER
10507-
M: Ofir Bitton <[email protected]>
10507+
M: Yaron Avizrat <[email protected]>
1050810508
1050910509
S: Supported
1051010510
C: irc://irc.oftc.net/dri-devel

drivers/char/agp/amd64-agp.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -720,11 +720,6 @@ static const struct pci_device_id agp_amd64_pci_table[] = {
720720

721721
MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
722722

723-
static const struct pci_device_id agp_amd64_pci_promisc_table[] = {
724-
{ PCI_DEVICE_CLASS(0, 0) },
725-
{ }
726-
};
727-
728723
static DEFINE_SIMPLE_DEV_PM_OPS(agp_amd64_pm_ops, NULL, agp_amd64_resume);
729724

730725
static struct pci_driver agp_amd64_pci_driver = {
@@ -739,6 +734,7 @@ static struct pci_driver agp_amd64_pci_driver = {
739734
/* Not static due to IOMMU code calling it early. */
740735
int __init agp_amd64_init(void)
741736
{
737+
struct pci_dev *pdev = NULL;
742738
int err = 0;
743739

744740
if (agp_off)
@@ -767,9 +763,13 @@ int __init agp_amd64_init(void)
767763
}
768764

769765
/* Look for any AGP bridge */
770-
agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table;
771-
err = driver_attach(&agp_amd64_pci_driver.driver);
772-
if (err == 0 && agp_bridges_found == 0) {
766+
for_each_pci_dev(pdev)
767+
if (pci_find_capability(pdev, PCI_CAP_ID_AGP))
768+
pci_add_dynid(&agp_amd64_pci_driver,
769+
pdev->vendor, pdev->device,
770+
pdev->subsystem_vendor,
771+
pdev->subsystem_device, 0, 0, 0);
772+
if (agp_bridges_found == 0) {
773773
pci_unregister_driver(&agp_amd64_pci_driver);
774774
err = -ENODEV;
775775
}

drivers/gpu/drm/drm_framebuffer.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -862,11 +862,23 @@ EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_free);
862862
int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
863863
const struct drm_framebuffer_funcs *funcs)
864864
{
865+
unsigned int i;
865866
int ret;
867+
bool exists;
866868

867869
if (WARN_ON_ONCE(fb->dev != dev || !fb->format))
868870
return -EINVAL;
869871

872+
for (i = 0; i < fb->format->num_planes; i++) {
873+
if (drm_WARN_ON_ONCE(dev, fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)))
874+
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
875+
if (fb->obj[i]) {
876+
exists = drm_gem_object_handle_get_if_exists_unlocked(fb->obj[i]);
877+
if (exists)
878+
fb->internal_flags |= DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
879+
}
880+
}
881+
870882
INIT_LIST_HEAD(&fb->filp_head);
871883

872884
fb->funcs = funcs;
@@ -875,15 +887,24 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
875887
ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,
876888
false, drm_framebuffer_free);
877889
if (ret)
878-
goto out;
890+
goto err;
879891

880892
mutex_lock(&dev->mode_config.fb_lock);
881893
dev->mode_config.num_fb++;
882894
list_add(&fb->head, &dev->mode_config.fb_list);
883895
mutex_unlock(&dev->mode_config.fb_lock);
884896

885897
drm_mode_object_register(dev, &fb->base);
886-
out:
898+
899+
return 0;
900+
901+
err:
902+
for (i = 0; i < fb->format->num_planes; i++) {
903+
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)) {
904+
drm_gem_object_handle_put_unlocked(fb->obj[i]);
905+
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
906+
}
907+
}
887908
return ret;
888909
}
889910
EXPORT_SYMBOL(drm_framebuffer_init);
@@ -960,6 +981,12 @@ EXPORT_SYMBOL(drm_framebuffer_unregister_private);
960981
void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
961982
{
962983
struct drm_device *dev = fb->dev;
984+
unsigned int i;
985+
986+
for (i = 0; i < fb->format->num_planes; i++) {
987+
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i))
988+
drm_gem_object_handle_put_unlocked(fb->obj[i]);
989+
}
963990

964991
mutex_lock(&dev->mode_config.fb_lock);
965992
list_del(&fb->head);

drivers/gpu/drm/drm_gem.c

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -223,23 +223,34 @@ static void drm_gem_object_handle_get(struct drm_gem_object *obj)
223223
}
224224

225225
/**
226-
* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles
226+
* drm_gem_object_handle_get_if_exists_unlocked - acquire reference on user-space handle, if any
227227
* @obj: GEM object
228228
*
229-
* Acquires a reference on the GEM buffer object's handle. Required
230-
* to keep the GEM object alive. Call drm_gem_object_handle_put_unlocked()
231-
* to release the reference.
229+
* Acquires a reference on the GEM buffer object's handle. Required to keep
230+
* the GEM object alive. Call drm_gem_object_handle_put_if_exists_unlocked()
231+
* to release the reference. Does nothing if the buffer object has no handle.
232+
*
233+
* Returns:
234+
* True if a handle exists, or false otherwise
232235
*/
233-
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj)
236+
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj)
234237
{
235238
struct drm_device *dev = obj->dev;
236239

237240
guard(mutex)(&dev->object_name_lock);
238241

239-
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
242+
/*
243+
* First ref taken during GEM object creation, if any. Some
244+
* drivers set up internal framebuffers with GEM objects that
245+
* do not have a GEM handle. Hence, this counter can be zero.
246+
*/
247+
if (!obj->handle_count)
248+
return false;
249+
240250
drm_gem_object_handle_get(obj);
251+
252+
return true;
241253
}
242-
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
243254

244255
/**
245256
* drm_gem_object_handle_free - release resources bound to userspace handles
@@ -272,7 +283,7 @@ static void drm_gem_object_exported_dma_buf_free(struct drm_gem_object *obj)
272283
}
273284

274285
/**
275-
* drm_gem_object_handle_put_unlocked - releases reference on user-space handles
286+
* drm_gem_object_handle_put_unlocked - releases reference on user-space handle
276287
* @obj: GEM object
277288
*
278289
* Releases a reference on the GEM buffer object's handle. Possibly releases
@@ -283,14 +294,14 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
283294
struct drm_device *dev = obj->dev;
284295
bool final = false;
285296

286-
if (WARN_ON(READ_ONCE(obj->handle_count) == 0))
297+
if (drm_WARN_ON(dev, READ_ONCE(obj->handle_count) == 0))
287298
return;
288299

289300
/*
290-
* Must bump handle count first as this may be the last
291-
* ref, in which case the object would disappear before we
292-
* checked for a name
293-
*/
301+
* Must bump handle count first as this may be the last
302+
* ref, in which case the object would disappear before
303+
* we checked for a name.
304+
*/
294305

295306
mutex_lock(&dev->object_name_lock);
296307
if (--obj->handle_count == 0) {
@@ -303,7 +314,6 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
303314
if (final)
304315
drm_gem_object_put(obj);
305316
}
306-
EXPORT_SYMBOL(drm_gem_object_handle_put_unlocked);
307317

308318
/*
309319
* Called at device or object close to release the file's
@@ -315,6 +325,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
315325
struct drm_file *file_priv = data;
316326
struct drm_gem_object *obj = ptr;
317327

328+
if (drm_WARN_ON(obj->dev, !data))
329+
return 0;
330+
318331
if (obj->funcs->close)
319332
obj->funcs->close(obj, file_priv);
320333

@@ -435,7 +448,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
435448
idr_preload(GFP_KERNEL);
436449
spin_lock(&file_priv->table_lock);
437450

438-
ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
451+
ret = idr_alloc(&file_priv->object_idr, NULL, 1, 0, GFP_NOWAIT);
439452

440453
spin_unlock(&file_priv->table_lock);
441454
idr_preload_end();
@@ -456,6 +469,11 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
456469
goto err_revoke;
457470
}
458471

472+
/* mirrors drm_gem_handle_delete to avoid races */
473+
spin_lock(&file_priv->table_lock);
474+
obj = idr_replace(&file_priv->object_idr, obj, handle);
475+
WARN_ON(obj != NULL);
476+
spin_unlock(&file_priv->table_lock);
459477
*handlep = handle;
460478
return 0;
461479

drivers/gpu/drm/drm_gem_framebuffer_helper.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ void drm_gem_fb_destroy(struct drm_framebuffer *fb)
9999
unsigned int i;
100100

101101
for (i = 0; i < fb->format->num_planes; i++)
102-
drm_gem_object_handle_put_unlocked(fb->obj[i]);
102+
drm_gem_object_put(fb->obj[i]);
103103

104104
drm_framebuffer_cleanup(fb);
105105
kfree(fb);
@@ -182,10 +182,8 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
182182
if (!objs[i]) {
183183
drm_dbg_kms(dev, "Failed to lookup GEM object\n");
184184
ret = -ENOENT;
185-
goto err_gem_object_handle_put_unlocked;
185+
goto err_gem_object_put;
186186
}
187-
drm_gem_object_handle_get_unlocked(objs[i]);
188-
drm_gem_object_put(objs[i]);
189187

190188
min_size = (height - 1) * mode_cmd->pitches[i]
191189
+ drm_format_info_min_pitch(info, i, width)
@@ -195,22 +193,22 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
195193
drm_dbg_kms(dev,
196194
"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n",
197195
objs[i]->size, min_size, i);
198-
drm_gem_object_handle_put_unlocked(objs[i]);
196+
drm_gem_object_put(objs[i]);
199197
ret = -EINVAL;
200-
goto err_gem_object_handle_put_unlocked;
198+
goto err_gem_object_put;
201199
}
202200
}
203201

204202
ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
205203
if (ret)
206-
goto err_gem_object_handle_put_unlocked;
204+
goto err_gem_object_put;
207205

208206
return 0;
209207

210-
err_gem_object_handle_put_unlocked:
208+
err_gem_object_put:
211209
while (i > 0) {
212210
--i;
213-
drm_gem_object_handle_put_unlocked(objs[i]);
211+
drm_gem_object_put(objs[i]);
214212
}
215213
return ret;
216214
}

drivers/gpu/drm/drm_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ void drm_sysfs_lease_event(struct drm_device *dev);
161161

162162
/* drm_gem.c */
163163
int drm_gem_init(struct drm_device *dev);
164-
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj);
164+
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj);
165165
void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj);
166166
int drm_gem_handle_create_tail(struct drm_file *file_priv,
167167
struct drm_gem_object *obj,

drivers/gpu/drm/drm_panic_qr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
//! * <https://github.com/erwanvivien/fast_qr>
2828
//! * <https://github.com/bjguillot/qr>
2929
30-
use kernel::{prelude::*, str::CStr};
30+
use kernel::prelude::*;
3131

3232
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
3333
struct Version(usize);

drivers/gpu/drm/imagination/pvr_power.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,13 @@ pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset)
386386
if (!err) {
387387
if (hard_reset) {
388388
pvr_dev->fw_dev.booted = false;
389-
WARN_ON(pm_runtime_force_suspend(from_pvr_device(pvr_dev)->dev));
389+
WARN_ON(pvr_power_device_suspend(from_pvr_device(pvr_dev)->dev));
390390

391391
err = pvr_fw_hard_reset(pvr_dev);
392392
if (err)
393393
goto err_device_lost;
394394

395-
err = pm_runtime_force_resume(from_pvr_device(pvr_dev)->dev);
395+
err = pvr_power_device_resume(from_pvr_device(pvr_dev)->dev);
396396
pvr_dev->fw_dev.booted = true;
397397
if (err)
398398
goto err_device_lost;

drivers/gpu/drm/nouveau/nouveau_debugfs.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,10 @@ nouveau_debugfs_fini(struct nouveau_drm *drm)
314314
drm->debugfs = NULL;
315315
}
316316

317-
int
317+
void
318318
nouveau_module_debugfs_init(void)
319319
{
320320
nouveau_debugfs_root = debugfs_create_dir("nouveau", NULL);
321-
if (IS_ERR(nouveau_debugfs_root))
322-
return PTR_ERR(nouveau_debugfs_root);
323-
324-
return 0;
325321
}
326322

327323
void

drivers/gpu/drm/nouveau/nouveau_debugfs.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ extern void nouveau_debugfs_fini(struct nouveau_drm *);
2424

2525
extern struct dentry *nouveau_debugfs_root;
2626

27-
int nouveau_module_debugfs_init(void);
27+
void nouveau_module_debugfs_init(void);
2828
void nouveau_module_debugfs_fini(void);
2929
#else
3030
static inline void
@@ -42,10 +42,9 @@ nouveau_debugfs_fini(struct nouveau_drm *drm)
4242
{
4343
}
4444

45-
static inline int
45+
static inline void
4646
nouveau_module_debugfs_init(void)
4747
{
48-
return 0;
4948
}
5049

5150
static inline void

0 commit comments

Comments
 (0)