drm.buffer.peak.default A read-only flat-keyed file which exists on the root cgroup. Each entry is keyed by the drm device's major:minor. Default limits on the largest GEM buffer allocation in bytes. drm.buffer.peak.max A read-write flat-keyed file which exists on all cgroups. Each entry is keyed by the drm device's major:minor. Per device limits on the largest GEM buffer allocation in bytes. This is a hard limit. Attempts in allocating beyond the cgroup limit will result in ENOMEM. Shorthand understood by memparse (such as k, m, g) can be used. Set largest allocation for /dev/dri/card1 to 4MB echo "226:1 4m" > drm.buffer.peak.max Change-Id: I0830d56775568e1cf215b56cc892d5e7945e9f25 Signed-off-by: Kenny Ho <Kenny.Ho@xxxxxxx> --- Documentation/admin-guide/cgroup-v2.rst | 18 ++++++++++ include/drm/drm_cgroup.h | 1 + include/linux/cgroup_drm.h | 1 + kernel/cgroup/drm.c | 48 +++++++++++++++++++++++++ 4 files changed, 68 insertions(+) diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index e8fac2684179..87a195133eaa 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst @@ -1940,6 +1940,24 @@ DRM Interface Files Set allocation limit for /dev/dri/card0 to 512MB echo "226:0 512m" > drm.buffer.total.max + drm.buffer.peak.default + A read-only flat-keyed file which exists on the root cgroup. + Each entry is keyed by the drm device's major:minor. + + Default limits on the largest GEM buffer allocation in bytes. + + drm.buffer.peak.max + A read-write flat-keyed file which exists on all cgroups. Each + entry is keyed by the drm device's major:minor. + + Per device limits on the largest GEM buffer allocation in bytes. + This is a hard limit. Attempts in allocating beyond the cgroup + limit will result in ENOMEM. Shorthand understood by memparse + (such as k, m, g) can be used. + + Set largest allocation for /dev/dri/card1 to 4MB + echo "226:1 4m" > drm.buffer.peak.max + GEM Buffer Ownership ~~~~~~~~~~~~~~~~~~~~ diff --git a/include/drm/drm_cgroup.h b/include/drm/drm_cgroup.h index 49c5d35ff6e1..d61b90beded5 100644 --- a/include/drm/drm_cgroup.h +++ b/include/drm/drm_cgroup.h @@ -14,6 +14,7 @@ struct drmcg_props { bool limit_enforced; s64 bo_limits_total_allocated_default; + s64 bo_limits_peak_allocated_default; }; #ifdef CONFIG_CGROUP_DRM diff --git a/include/linux/cgroup_drm.h b/include/linux/cgroup_drm.h index eb54e56f20ae..87a2566c9fdd 100644 --- a/include/linux/cgroup_drm.h +++ b/include/linux/cgroup_drm.h @@ -29,6 +29,7 @@ struct drmcg_device_resource { s64 bo_limits_total_allocated; s64 bo_stats_peak_allocated; + s64 bo_limits_peak_allocated; s64 bo_stats_count_allocated; }; diff --git a/kernel/cgroup/drm.c b/kernel/cgroup/drm.c index 7161fa40e156..2f54bff291e5 100644 --- a/kernel/cgroup/drm.c +++ b/kernel/cgroup/drm.c @@ -75,6 +75,9 @@ static inline int init_drmcg_single(struct drmcg *drmcg, struct drm_device *dev) ddr->bo_limits_total_allocated = dev->drmcg_props.bo_limits_total_allocated_default; + ddr->bo_limits_peak_allocated = + dev->drmcg_props.bo_limits_peak_allocated_default; + mutex_unlock(&dev->drmcg_mutex); return 0; } @@ -157,6 +160,9 @@ static void drmcg_print_limits(struct drmcg_device_resource *ddr, case DRMCG_TYPE_BO_TOTAL: seq_printf(sf, "%lld\n", ddr->bo_limits_total_allocated); break; + case DRMCG_TYPE_BO_PEAK: + seq_printf(sf, "%lld\n", ddr->bo_limits_peak_allocated); + break; default: seq_puts(sf, "\n"); break; @@ -171,6 +177,10 @@ static void drmcg_print_default(struct drmcg_props *props, seq_printf(sf, "%lld\n", props->bo_limits_total_allocated_default); break; + case DRMCG_TYPE_BO_PEAK: + seq_printf(sf, "%lld\n", + props->bo_limits_peak_allocated_default); + break; default: seq_puts(sf, "\n"); break; @@ -327,6 +337,24 @@ static ssize_t drmcg_limit_write(struct kernfs_open_file *of, char *buf, drmcg_value_apply(dm->dev, &ddr->bo_limits_total_allocated, val); break; + case DRMCG_TYPE_BO_PEAK: + p_max = parent == NULL ? S64_MAX : + parent->dev_resources[minor]-> + bo_limits_peak_allocated; + + rc = drmcg_process_limit_s64_val(sattr, true, + props->bo_limits_peak_allocated_default, + p_max, + &val); + + if (rc || val < 0) { + drmcg_pr_cft_err(drmcg, rc, cft_name, minor); + break; + } + + drmcg_value_apply(dm->dev, + &ddr->bo_limits_peak_allocated, val); + break; default: break; } @@ -363,6 +391,20 @@ struct cftype files[] = { .private = DRMCG_CTF_PRIV(DRMCG_TYPE_BO_PEAK, DRMCG_FTYPE_STATS), }, + { + .name = "buffer.peak.default", + .seq_show = drmcg_seq_show, + .flags = CFTYPE_ONLY_ON_ROOT, + .private = DRMCG_CTF_PRIV(DRMCG_TYPE_BO_PEAK, + DRMCG_FTYPE_DEFAULT), + }, + { + .name = "buffer.peak.max", + .write = drmcg_limit_write, + .seq_show = drmcg_seq_show, + .private = DRMCG_CTF_PRIV(DRMCG_TYPE_BO_PEAK, + DRMCG_FTYPE_LIMIT), + }, { .name = "buffer.count.stats", .seq_show = drmcg_seq_show, @@ -427,6 +469,7 @@ void drmcg_device_early_init(struct drm_device *dev) dev->drmcg_props.limit_enforced = false; dev->drmcg_props.bo_limits_total_allocated_default = S64_MAX; + dev->drmcg_props.bo_limits_peak_allocated_default = S64_MAX; drmcg_update_cg_tree(dev); } @@ -466,6 +509,11 @@ bool drmcg_try_chg_bo_alloc(struct drmcg *drmcg, struct drm_device *dev, result = false; break; } + + if (ddr->bo_limits_peak_allocated < size) { + result = false; + break; + } } } -- 2.22.0 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx