The resctrl task assignment for MONITOR or CONTROL group needs to be done one at a time. For example: $mount -t resctrl resctrl /sys/fs/resctrl/ $mkdir /sys/fs/resctrl/clos1 $echo 123 > /sys/fs/resctrl/clos1/tasks $echo 456 > /sys/fs/resctrl/clos1/tasks $echo 789 > /sys/fs/resctrl/clos1/tasks This is not user-friendly when dealing with hundreds of tasks. It can be improved by supporting the multiple task id assignment in one command with the tasks separated by commas. For example: $echo 123,456,789 > /sys/fs/resctrl/clos1/tasks Signed-off-by: Babu Moger <babu.moger@xxxxxxx> --- Documentation/x86/resctrl.rst | 9 ++++++++- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/Documentation/x86/resctrl.rst b/Documentation/x86/resctrl.rst index 387ccbcb558f..f28ed1443a6a 100644 --- a/Documentation/x86/resctrl.rst +++ b/Documentation/x86/resctrl.rst @@ -292,7 +292,14 @@ All groups contain the following files: "tasks": Reading this file shows the list of all tasks that belong to this group. Writing a task id to the file will add a task to the - group. If the group is a CTRL_MON group the task is removed from + group. Multiple tasks can be added by separating the task ids + with commas. Tasks will be assigned sequentially in the order it + is entered. Failures while assigning the tasks will be aborted + immediately and tasks next in the sequence will not be assigned. + Users may need to retry them again. Failure details possibly with + pid will be logged in /sys/fs/resctrl/info/last_cmd_status file. + + If the group is a CTRL_MON group the task is removed from whichever previous CTRL_MON group owned the task and also from any MON group that owned the task. If the group is a MON group, then the task must already belong to the CTRL_MON parent of this diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index 6ad33f355861..df5bd13440b0 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -696,18 +696,41 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { struct rdtgroup *rdtgrp; + char *pid_str; int ret = 0; pid_t pid; - if (kstrtoint(strstrip(buf), 0, &pid) || pid < 0) + if (nbytes == 0) return -EINVAL; + + buf[nbytes - 1] = '\0'; + rdtgrp = rdtgroup_kn_lock_live(of->kn); if (!rdtgrp) { rdtgroup_kn_unlock(of->kn); return -ENOENT; } + +next: + if (!buf || buf[0] == '\0') + goto unlock; + rdt_last_cmd_clear(); + pid_str = strim(strsep(&buf, ",")); + + if (kstrtoint(pid_str, 0, &pid)) { + rdt_last_cmd_printf("Task list parsing error\n"); + ret = -EINVAL; + goto unlock; + } + + if (pid < 0) { + rdt_last_cmd_printf("Invalid pid %d value\n", pid); + ret = -EINVAL; + goto unlock; + } + if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED || rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP) { ret = -EINVAL; @@ -716,6 +739,12 @@ static ssize_t rdtgroup_tasks_write(struct kernfs_open_file *of, } ret = rdtgroup_move_task(pid, rdtgrp, of); + if (ret) { + rdt_last_cmd_printf("Error while processing task %d\n", pid); + goto unlock; + } else { + goto next; + } unlock: rdtgroup_kn_unlock(of->kn);