Message ID | 20231028000945.2428830-3-shr@devkernel.io (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | mm/ksm: Add ksm advisor | expand |
On 28.10.23 02:09, Stefan Roesch wrote: > This adds four new knobs for the KSM advisor to influence its behaviour. > > The knobs are: > - advisor_mode: > 0: no advisor (default) > 1: scan time advisor > - advisor_min_cpu: 15 (default, cpu usage percent) > - advisor_max_cpu: 70 (default, cpu usage percent) > - advisor_min_pages: 500 (default) > - advisor_max_pages: 30000 (default) > - advisor_target_scan_time: 200 (default in seconds) Is there a way we can avoid exposing advisor_min_pages/advisor_max_pages and just have this internal e.g., as defines?
On 28.10.23 02:09, Stefan Roesch wrote: > This adds four new knobs for the KSM advisor to influence its behaviour. > > The knobs are: > - advisor_mode: > 0: no advisor (default) > 1: scan time advisor > - advisor_min_cpu: 15 (default, cpu usage percent) > - advisor_max_cpu: 70 (default, cpu usage percent) > - advisor_min_pages: 500 (default) > - advisor_max_pages: 30000 (default) > - advisor_target_scan_time: 200 (default in seconds) > > The new values will take effect on the next scan round. > > Signed-off-by: Stefan Roesch <shr@devkernel.io> > --- > mm/ksm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 154 insertions(+) > > diff --git a/mm/ksm.c b/mm/ksm.c > index e18fecfb359d..042ecaeb0beb 100644 > --- a/mm/ksm.c > +++ b/mm/ksm.c > @@ -351,6 +351,14 @@ static void init_advisor(void) > advisor_ctx.cpu_time = 0; > } [...] > * Use previous scan time if available, otherwise use current scan time as an > * approximation for the previous scan time. > @@ -3719,6 +3727,146 @@ static ssize_t smart_scan_store(struct kobject *kobj, > } > KSM_ATTR(smart_scan); > > +static ssize_t advisor_mode_show(struct kobject *kobj, > + struct kobj_attribute *attr, char *buf) > +{ > + return sysfs_emit(buf, "%u\n", ksm_advisor); > +} > + > +static ssize_t advisor_mode_store(struct kobject *kobj, > + struct kobj_attribute *attr, const char *buf, > + size_t count) > +{ > + unsigned int mode; > + int err; > + > + err = kstrtouint(buf, 10, &mode); > + if (err) > + return -EINVAL; > + if (mode > KSM_ADVISOR_LAST) > + return -EINVAL; > + > + /* Set advisor default values */ > + ksm_advisor = mode; > + init_advisor(); > + set_advisor_defaults(); > + > + return count; Can we instead use human-readable strings? "none" and "scan-time" should be clearer.
David Hildenbrand <david@redhat.com> writes: > On 28.10.23 02:09, Stefan Roesch wrote: >> This adds four new knobs for the KSM advisor to influence its behaviour. >> The knobs are: >> - advisor_mode: >> 0: no advisor (default) >> 1: scan time advisor >> - advisor_min_cpu: 15 (default, cpu usage percent) >> - advisor_max_cpu: 70 (default, cpu usage percent) >> - advisor_min_pages: 500 (default) >> - advisor_max_pages: 30000 (default) >> - advisor_target_scan_time: 200 (default in seconds) >> The new values will take effect on the next scan round. >> Signed-off-by: Stefan Roesch <shr@devkernel.io> >> --- >> mm/ksm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 154 insertions(+) >> diff --git a/mm/ksm.c b/mm/ksm.c >> index e18fecfb359d..042ecaeb0beb 100644 >> --- a/mm/ksm.c >> +++ b/mm/ksm.c >> @@ -351,6 +351,14 @@ static void init_advisor(void) >> advisor_ctx.cpu_time = 0; >> } > > > [...] > >> * Use previous scan time if available, otherwise use current scan time as an >> * approximation for the previous scan time. >> @@ -3719,6 +3727,146 @@ static ssize_t smart_scan_store(struct kobject *kobj, >> } >> KSM_ATTR(smart_scan); >> +static ssize_t advisor_mode_show(struct kobject *kobj, >> + struct kobj_attribute *attr, char *buf) >> +{ >> + return sysfs_emit(buf, "%u\n", ksm_advisor); >> +} >> + >> +static ssize_t advisor_mode_store(struct kobject *kobj, >> + struct kobj_attribute *attr, const char *buf, >> + size_t count) >> +{ >> + unsigned int mode; >> + int err; >> + >> + err = kstrtouint(buf, 10, &mode); >> + if (err) >> + return -EINVAL; >> + if (mode > KSM_ADVISOR_LAST) >> + return -EINVAL; >> + >> + /* Set advisor default values */ >> + ksm_advisor = mode; >> + init_advisor(); >> + set_advisor_defaults(); >> + >> + return count; > > Can we instead use human-readable strings? > > "none" and "scan-time" should be clearer. > I'll change the interface to use strings instead of numbers.
David Hildenbrand <david@redhat.com> writes: > On 28.10.23 02:09, Stefan Roesch wrote: >> This adds four new knobs for the KSM advisor to influence its behaviour. >> The knobs are: >> - advisor_mode: >> 0: no advisor (default) >> 1: scan time advisor >> - advisor_min_cpu: 15 (default, cpu usage percent) >> - advisor_max_cpu: 70 (default, cpu usage percent) >> - advisor_min_pages: 500 (default) >> - advisor_max_pages: 30000 (default) >> - advisor_target_scan_time: 200 (default in seconds) > > Is there a way we can avoid exposing advisor_min_pages/advisor_max_pages and > just have this internal e.g., as defines? > Yes, we can.
David Hildenbrand <david@redhat.com> writes: > On 28.10.23 02:09, Stefan Roesch wrote: >> This adds four new knobs for the KSM advisor to influence its behaviour. >> The knobs are: >> - advisor_mode: >> 0: no advisor (default) >> 1: scan time advisor >> - advisor_min_cpu: 15 (default, cpu usage percent) >> - advisor_max_cpu: 70 (default, cpu usage percent) >> - advisor_min_pages: 500 (default) >> - advisor_max_pages: 30000 (default) >> - advisor_target_scan_time: 200 (default in seconds) > > Is there a way we can avoid exposing advisor_min_pages/advisor_max_pages and > just have this internal e.g., as defines? Yes, we can.
diff --git a/mm/ksm.c b/mm/ksm.c index e18fecfb359d..042ecaeb0beb 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -351,6 +351,14 @@ static void init_advisor(void) advisor_ctx.cpu_time = 0; } +static void set_advisor_defaults(void) +{ + if (ksm_advisor == KSM_ADVISOR_NONE) + ksm_thread_pages_to_scan = DEFAULT_PAGES_TO_SCAN; + else if (ksm_advisor == KSM_ADVISOR_SCAN_TIME) + ksm_thread_pages_to_scan = ksm_advisor_min_pages; +} + /* * Use previous scan time if available, otherwise use current scan time as an * approximation for the previous scan time. @@ -3719,6 +3727,146 @@ static ssize_t smart_scan_store(struct kobject *kobj, } KSM_ATTR(smart_scan); +static ssize_t advisor_mode_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%u\n", ksm_advisor); +} + +static ssize_t advisor_mode_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, + size_t count) +{ + unsigned int mode; + int err; + + err = kstrtouint(buf, 10, &mode); + if (err) + return -EINVAL; + if (mode > KSM_ADVISOR_LAST) + return -EINVAL; + + /* Set advisor default values */ + ksm_advisor = mode; + init_advisor(); + set_advisor_defaults(); + + return count; +} +KSM_ATTR(advisor_mode); + +static ssize_t advisor_min_cpu_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%u\n", ksm_advisor_min_cpu); +} + +static ssize_t advisor_min_cpu_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long value; + + err = kstrtoul(buf, 10, &value); + if (err) + return -EINVAL; + + ksm_advisor_min_cpu = value; + return count; +} +KSM_ATTR(advisor_min_cpu); + +static ssize_t advisor_max_cpu_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%u\n", ksm_advisor_max_cpu); +} + +static ssize_t advisor_max_cpu_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long value; + + err = kstrtoul(buf, 10, &value); + if (err) + return -EINVAL; + + ksm_advisor_max_cpu = value; + return count; +} +KSM_ATTR(advisor_max_cpu); + +static ssize_t advisor_min_pages_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%lu\n", ksm_advisor_min_pages); +} + +static ssize_t advisor_min_pages_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long value; + + err = kstrtoul(buf, 10, &value); + if (err) + return -EINVAL; + + ksm_advisor_min_pages = value; + return count; +} +KSM_ATTR(advisor_min_pages); + +static ssize_t advisor_max_pages_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%lu\n", ksm_advisor_max_pages); +} + +static ssize_t advisor_max_pages_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long value; + + err = kstrtoul(buf, 10, &value); + if (err) + return -EINVAL; + + ksm_advisor_max_pages = value; + return count; +} +KSM_ATTR(advisor_max_pages); + +static ssize_t advisor_target_scan_time_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%lu\n", ksm_advisor_target_scan_time); +} + +static ssize_t advisor_target_scan_time_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + int err; + unsigned long value; + + err = kstrtoul(buf, 10, &value); + if (err) + return -EINVAL; + if (value < 1) + return -EINVAL; + + ksm_advisor_target_scan_time = value; + return count; +} +KSM_ATTR(advisor_target_scan_time); + static struct attribute *ksm_attrs[] = { &sleep_millisecs_attr.attr, &pages_to_scan_attr.attr, @@ -3741,6 +3889,12 @@ static struct attribute *ksm_attrs[] = { &use_zero_pages_attr.attr, &general_profit_attr.attr, &smart_scan_attr.attr, + &advisor_mode_attr.attr, + &advisor_min_cpu_attr.attr, + &advisor_max_cpu_attr.attr, + &advisor_min_pages_attr.attr, + &advisor_max_pages_attr.attr, + &advisor_target_scan_time_attr.attr, NULL, };
This adds four new knobs for the KSM advisor to influence its behaviour. The knobs are: - advisor_mode: 0: no advisor (default) 1: scan time advisor - advisor_min_cpu: 15 (default, cpu usage percent) - advisor_max_cpu: 70 (default, cpu usage percent) - advisor_min_pages: 500 (default) - advisor_max_pages: 30000 (default) - advisor_target_scan_time: 200 (default in seconds) The new values will take effect on the next scan round. Signed-off-by: Stefan Roesch <shr@devkernel.io> --- mm/ksm.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+)