cregit-Linux how code gets into the kernel

Release 4.11 drivers/gpu/drm/msm/msm_gem_shrinker.c

/*
 * Copyright (C) 2016 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "msm_drv.h"
#include "msm_gem.h"


static bool msm_gem_shrinker_lock(struct drm_device *dev, bool *unlock) { switch (mutex_trylock_recursive(&dev->struct_mutex)) { case MUTEX_TRYLOCK_FAILED: return false; case MUTEX_TRYLOCK_SUCCESS: *unlock = true; return true; case MUTEX_TRYLOCK_RECURSIVE: *unlock = false; return true; } BUG(); }

Contributors

PersonTokensPropCommitsCommitProp
Rob Clark3458.62%150.00%
Peter Zijlstra2441.38%150.00%
Total58100.00%2100.00%


static unsigned long msm_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) { struct msm_drm_private *priv = container_of(shrinker, struct msm_drm_private, shrinker); struct drm_device *dev = priv->dev; struct msm_gem_object *msm_obj; unsigned long count = 0; bool unlock; if (!msm_gem_shrinker_lock(dev, &unlock)) return 0; list_for_each_entry(msm_obj, &priv->inactive_list, mm_list) { if (is_purgeable(msm_obj)) count += msm_obj->base.size >> PAGE_SHIFT; } if (unlock) mutex_unlock(&dev->struct_mutex); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Rob Clark111100.00%1100.00%
Total111100.00%1100.00%


static unsigned long msm_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) { struct msm_drm_private *priv = container_of(shrinker, struct msm_drm_private, shrinker); struct drm_device *dev = priv->dev; struct msm_gem_object *msm_obj; unsigned long freed = 0; bool unlock; if (!msm_gem_shrinker_lock(dev, &unlock)) return SHRINK_STOP; list_for_each_entry(msm_obj, &priv->inactive_list, mm_list) { if (freed >= sc->nr_to_scan) break; if (is_purgeable(msm_obj)) { msm_gem_purge(&msm_obj->base); freed += msm_obj->base.size >> PAGE_SHIFT; } } if (unlock) mutex_unlock(&dev->struct_mutex); if (freed > 0) pr_info_ratelimited("Purging %lu bytes\n", freed << PAGE_SHIFT); return freed; }

Contributors

PersonTokensPropCommitsCommitProp
Rob Clark145100.00%1100.00%
Total145100.00%1100.00%


static int msm_gem_shrinker_vmap(struct notifier_block *nb, unsigned long event, void *ptr) { struct msm_drm_private *priv = container_of(nb, struct msm_drm_private, vmap_notifier); struct drm_device *dev = priv->dev; struct msm_gem_object *msm_obj; unsigned unmapped = 0; bool unlock; if (!msm_gem_shrinker_lock(dev, &unlock)) return NOTIFY_DONE; list_for_each_entry(msm_obj, &priv->inactive_list, mm_list) { if (is_vunmapable(msm_obj)) { msm_gem_vunmap(&msm_obj->base); /* since we don't know any better, lets bail after a few * and if necessary the shrinker will be invoked again. * Seems better than unmapping *everything* */ if (++unmapped >= 15) break; } } if (unlock) mutex_unlock(&dev->struct_mutex); *(unsigned long *)ptr += unmapped; if (unmapped > 0) pr_info_ratelimited("Purging %u vmaps\n", unmapped); return NOTIFY_DONE; }

Contributors

PersonTokensPropCommitsCommitProp
Rob Clark144100.00%1100.00%
Total144100.00%1100.00%

/** * msm_gem_shrinker_init - Initialize msm shrinker * @dev_priv: msm device * * This function registers and sets up the msm shrinker. */
void msm_gem_shrinker_init(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; priv->shrinker.count_objects = msm_gem_shrinker_count; priv->shrinker.scan_objects = msm_gem_shrinker_scan; priv->shrinker.seeks = DEFAULT_SEEKS; WARN_ON(register_shrinker(&priv->shrinker)); priv->vmap_notifier.notifier_call = msm_gem_shrinker_vmap; WARN_ON(register_vmap_purge_notifier(&priv->vmap_notifier)); }

Contributors

PersonTokensPropCommitsCommitProp
Rob Clark73100.00%2100.00%
Total73100.00%2100.00%

/** * msm_gem_shrinker_cleanup - Clean up msm shrinker * @dev_priv: msm device * * This function unregisters the msm shrinker. */
void msm_gem_shrinker_cleanup(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; if (priv->shrinker.nr_deferred) { WARN_ON(unregister_vmap_purge_notifier(&priv->vmap_notifier)); unregister_shrinker(&priv->shrinker); } }

Contributors

PersonTokensPropCommitsCommitProp
Rob Clark3879.17%266.67%
Archit Taneja1020.83%133.33%
Total48100.00%3100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Rob Clark55494.22%250.00%
Peter Zijlstra244.08%125.00%
Archit Taneja101.70%125.00%
Total588100.00%4100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.