mirror of https://gitee.com/openkylin/linux.git
-mgag200: more startadd mitigation (Thomas)
-panfrost: devfreq fix + several memory fixes (Steven, Boris) Cc: Boris Brezillon <boris.brezillon@collabora.com> Cc: Steven Price <steven.price@arm.com> Cc: Thomas Zimmermann <tzimmermann@suse.de> -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEHF6rntfJ3enn8gh8cywAJXLcr3kFAl3ySAcACgkQcywAJXLc r3mIGwf7BZZuH+0OTq4QPas7T8vQ5wKSgAB5zN6QQ7nNDlUZUHeWhJ8bouTdOrZ8 VarzfQwUvEIXWdTWU7hlcZ8bmoJ+7BTXjeZQKdoHLPphueq//GhlJJ2Mxz4wVBDL akQniUktv803Rh18VZBeh5h9tC3k+fJeykGw5pepvoA5/vSTQPKAjVPCwT0V/l01 5N+tzXOylsiUosUgiex2X1d8vDEEo36wBBqd+696ClRPCvkv+14N6et/uLv+a1q/ d4CIF2wtsfSM817S8jsHg43/XLWtUHVRKMygCLDa6sEj+dtqVyTDMGewLf55m6zw +mMZ5ApKFO24oUoUbg0vB5ooFoY0SA== =FXVI -----END PGP SIGNATURE----- Merge tag 'drm-misc-next-fixes-2019-12-12' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes -mgag200: more startadd mitigation (Thomas) -panfrost: devfreq fix + several memory fixes (Steven, Boris) Cc: Boris Brezillon <boris.brezillon@collabora.com> Cc: Steven Price <steven.price@arm.com> Cc: Thomas Zimmermann <tzimmermann@suse.de> Signed-off-by: Dave Airlie <airlied@redhat.com> From: Sean Paul <sean@poorly.run> Link: https://patchwork.freedesktop.org/patch/msgid/20191212140145.GA145200@art_vandelay
This commit is contained in:
commit
7315c0edb4
|
@ -30,9 +30,8 @@ module_param_named(modeset, mgag200_modeset, int, 0400);
|
|||
static struct drm_driver driver;
|
||||
|
||||
static const struct pci_device_id pciidlist[] = {
|
||||
{ PCI_VENDOR_ID_MATROX, 0x522, PCI_VENDOR_ID_SUN, 0x4852, 0, 0,
|
||||
{ PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},
|
||||
{ PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A },
|
||||
{ PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },
|
||||
{ PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV },
|
||||
{ PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB },
|
||||
|
|
|
@ -18,15 +18,18 @@ static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev);
|
|||
static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
|
||||
u32 flags)
|
||||
{
|
||||
struct panfrost_device *pfdev = dev_get_drvdata(dev);
|
||||
struct dev_pm_opp *opp;
|
||||
int err;
|
||||
|
||||
opp = devfreq_recommended_opp(dev, freq, flags);
|
||||
if (IS_ERR(opp))
|
||||
return PTR_ERR(opp);
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
err = dev_pm_opp_set_rate(dev, *freq);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*freq = clk_get_rate(pfdev->clock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -60,20 +63,10 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int panfrost_devfreq_get_cur_freq(struct device *dev, unsigned long *freq)
|
||||
{
|
||||
struct panfrost_device *pfdev = platform_get_drvdata(to_platform_device(dev));
|
||||
|
||||
*freq = clk_get_rate(pfdev->clock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct devfreq_dev_profile panfrost_devfreq_profile = {
|
||||
.polling_ms = 50, /* ~3 frames */
|
||||
.target = panfrost_devfreq_target,
|
||||
.get_dev_status = panfrost_devfreq_get_dev_status,
|
||||
.get_cur_freq = panfrost_devfreq_get_cur_freq,
|
||||
};
|
||||
|
||||
int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
||||
|
|
|
@ -303,14 +303,17 @@ static int panfrost_ioctl_mmap_bo(struct drm_device *dev, void *data,
|
|||
}
|
||||
|
||||
/* Don't allow mmapping of heap objects as pages are not pinned. */
|
||||
if (to_panfrost_bo(gem_obj)->is_heap)
|
||||
return -EINVAL;
|
||||
if (to_panfrost_bo(gem_obj)->is_heap) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = drm_gem_create_mmap_offset(gem_obj);
|
||||
if (ret == 0)
|
||||
args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
|
||||
drm_gem_object_put_unlocked(gem_obj);
|
||||
|
||||
out:
|
||||
drm_gem_object_put_unlocked(gem_obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -347,20 +350,19 @@ static int panfrost_ioctl_madvise(struct drm_device *dev, void *data,
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
mutex_lock(&pfdev->shrinker_lock);
|
||||
args->retained = drm_gem_shmem_madvise(gem_obj, args->madv);
|
||||
|
||||
if (args->retained) {
|
||||
struct panfrost_gem_object *bo = to_panfrost_bo(gem_obj);
|
||||
|
||||
mutex_lock(&pfdev->shrinker_lock);
|
||||
|
||||
if (args->madv == PANFROST_MADV_DONTNEED)
|
||||
list_add_tail(&bo->base.madv_list, &pfdev->shrinker_list);
|
||||
list_add_tail(&bo->base.madv_list,
|
||||
&pfdev->shrinker_list);
|
||||
else if (args->madv == PANFROST_MADV_WILLNEED)
|
||||
list_del_init(&bo->base.madv_list);
|
||||
|
||||
mutex_unlock(&pfdev->shrinker_lock);
|
||||
}
|
||||
mutex_unlock(&pfdev->shrinker_lock);
|
||||
|
||||
drm_gem_object_put_unlocked(gem_obj);
|
||||
return 0;
|
||||
|
@ -443,7 +445,7 @@ panfrost_postclose(struct drm_device *dev, struct drm_file *file)
|
|||
{
|
||||
struct panfrost_file_priv *panfrost_priv = file->driver_priv;
|
||||
|
||||
panfrost_perfcnt_close(panfrost_priv);
|
||||
panfrost_perfcnt_close(file);
|
||||
panfrost_job_close(panfrost_priv);
|
||||
|
||||
panfrost_mmu_pgtable_free(panfrost_priv);
|
||||
|
|
|
@ -19,6 +19,16 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
|
|||
struct panfrost_gem_object *bo = to_panfrost_bo(obj);
|
||||
struct panfrost_device *pfdev = obj->dev->dev_private;
|
||||
|
||||
/*
|
||||
* Make sure the BO is no longer inserted in the shrinker list before
|
||||
* taking care of the destruction itself. If we don't do that we have a
|
||||
* race condition between this function and what's done in
|
||||
* panfrost_gem_shrinker_scan().
|
||||
*/
|
||||
mutex_lock(&pfdev->shrinker_lock);
|
||||
list_del_init(&bo->base.madv_list);
|
||||
mutex_unlock(&pfdev->shrinker_lock);
|
||||
|
||||
if (bo->sgts) {
|
||||
int i;
|
||||
int n_sgt = bo->base.base.size / SZ_2M;
|
||||
|
@ -33,15 +43,10 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
|
|||
kfree(bo->sgts);
|
||||
}
|
||||
|
||||
mutex_lock(&pfdev->shrinker_lock);
|
||||
if (!list_empty(&bo->base.madv_list))
|
||||
list_del(&bo->base.madv_list);
|
||||
mutex_unlock(&pfdev->shrinker_lock);
|
||||
|
||||
drm_gem_shmem_free_object(obj);
|
||||
}
|
||||
|
||||
static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv)
|
||||
int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv)
|
||||
{
|
||||
int ret;
|
||||
size_t size = obj->size;
|
||||
|
@ -80,7 +85,7 @@ static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_p
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)
|
||||
void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)
|
||||
{
|
||||
struct panfrost_gem_object *bo = to_panfrost_bo(obj);
|
||||
struct panfrost_file_priv *priv = file_priv->driver_priv;
|
||||
|
|
|
@ -45,6 +45,10 @@ panfrost_gem_create_with_handle(struct drm_file *file_priv,
|
|||
u32 flags,
|
||||
uint32_t *handle);
|
||||
|
||||
int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv);
|
||||
void panfrost_gem_close(struct drm_gem_object *obj,
|
||||
struct drm_file *file_priv);
|
||||
|
||||
void panfrost_gem_shrinker_init(struct drm_device *dev);
|
||||
void panfrost_gem_shrinker_cleanup(struct drm_device *dev);
|
||||
|
||||
|
|
|
@ -67,9 +67,10 @@ static int panfrost_perfcnt_dump_locked(struct panfrost_device *pfdev)
|
|||
}
|
||||
|
||||
static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
|
||||
struct panfrost_file_priv *user,
|
||||
struct drm_file *file_priv,
|
||||
unsigned int counterset)
|
||||
{
|
||||
struct panfrost_file_priv *user = file_priv->driver_priv;
|
||||
struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;
|
||||
struct drm_gem_shmem_object *bo;
|
||||
u32 cfg;
|
||||
|
@ -91,14 +92,14 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
|
|||
perfcnt->bo = to_panfrost_bo(&bo->base);
|
||||
|
||||
/* Map the perfcnt buf in the address space attached to file_priv. */
|
||||
ret = panfrost_mmu_map(perfcnt->bo);
|
||||
ret = panfrost_gem_open(&perfcnt->bo->base.base, file_priv);
|
||||
if (ret)
|
||||
goto err_put_bo;
|
||||
|
||||
perfcnt->buf = drm_gem_shmem_vmap(&bo->base);
|
||||
if (IS_ERR(perfcnt->buf)) {
|
||||
ret = PTR_ERR(perfcnt->buf);
|
||||
goto err_put_bo;
|
||||
goto err_close_bo;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -157,14 +158,17 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
|
|||
|
||||
err_vunmap:
|
||||
drm_gem_shmem_vunmap(&perfcnt->bo->base.base, perfcnt->buf);
|
||||
err_close_bo:
|
||||
panfrost_gem_close(&perfcnt->bo->base.base, file_priv);
|
||||
err_put_bo:
|
||||
drm_gem_object_put_unlocked(&bo->base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev,
|
||||
struct panfrost_file_priv *user)
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct panfrost_file_priv *user = file_priv->driver_priv;
|
||||
struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;
|
||||
|
||||
if (user != perfcnt->user)
|
||||
|
@ -180,6 +184,7 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev,
|
|||
perfcnt->user = NULL;
|
||||
drm_gem_shmem_vunmap(&perfcnt->bo->base.base, perfcnt->buf);
|
||||
perfcnt->buf = NULL;
|
||||
panfrost_gem_close(&perfcnt->bo->base.base, file_priv);
|
||||
drm_gem_object_put_unlocked(&perfcnt->bo->base.base);
|
||||
perfcnt->bo = NULL;
|
||||
pm_runtime_mark_last_busy(pfdev->dev);
|
||||
|
@ -191,7 +196,6 @@ static int panfrost_perfcnt_disable_locked(struct panfrost_device *pfdev,
|
|||
int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct panfrost_file_priv *pfile = file_priv->driver_priv;
|
||||
struct panfrost_device *pfdev = dev->dev_private;
|
||||
struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;
|
||||
struct drm_panfrost_perfcnt_enable *req = data;
|
||||
|
@ -207,10 +211,10 @@ int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data,
|
|||
|
||||
mutex_lock(&perfcnt->lock);
|
||||
if (req->enable)
|
||||
ret = panfrost_perfcnt_enable_locked(pfdev, pfile,
|
||||
ret = panfrost_perfcnt_enable_locked(pfdev, file_priv,
|
||||
req->counterset);
|
||||
else
|
||||
ret = panfrost_perfcnt_disable_locked(pfdev, pfile);
|
||||
ret = panfrost_perfcnt_disable_locked(pfdev, file_priv);
|
||||
mutex_unlock(&perfcnt->lock);
|
||||
|
||||
return ret;
|
||||
|
@ -248,15 +252,16 @@ int panfrost_ioctl_perfcnt_dump(struct drm_device *dev, void *data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
void panfrost_perfcnt_close(struct panfrost_file_priv *pfile)
|
||||
void panfrost_perfcnt_close(struct drm_file *file_priv)
|
||||
{
|
||||
struct panfrost_file_priv *pfile = file_priv->driver_priv;
|
||||
struct panfrost_device *pfdev = pfile->pfdev;
|
||||
struct panfrost_perfcnt *perfcnt = pfdev->perfcnt;
|
||||
|
||||
pm_runtime_get_sync(pfdev->dev);
|
||||
mutex_lock(&perfcnt->lock);
|
||||
if (perfcnt->user == pfile)
|
||||
panfrost_perfcnt_disable_locked(pfdev, pfile);
|
||||
panfrost_perfcnt_disable_locked(pfdev, file_priv);
|
||||
mutex_unlock(&perfcnt->lock);
|
||||
pm_runtime_mark_last_busy(pfdev->dev);
|
||||
pm_runtime_put_autosuspend(pfdev->dev);
|
||||
|
|
|
@ -9,7 +9,7 @@ void panfrost_perfcnt_sample_done(struct panfrost_device *pfdev);
|
|||
void panfrost_perfcnt_clean_cache_done(struct panfrost_device *pfdev);
|
||||
int panfrost_perfcnt_init(struct panfrost_device *pfdev);
|
||||
void panfrost_perfcnt_fini(struct panfrost_device *pfdev);
|
||||
void panfrost_perfcnt_close(struct panfrost_file_priv *pfile);
|
||||
void panfrost_perfcnt_close(struct drm_file *file_priv);
|
||||
int panfrost_ioctl_perfcnt_enable(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int panfrost_ioctl_perfcnt_dump(struct drm_device *dev, void *data,
|
||||
|
|
Loading…
Reference in New Issue