* @is_add: whether to add or remove
  *
  * Depending on @is_add, add or remove files defined by @cfts on @cgrp.
- * For removals, this function never fails.  If addition fails, this
- * function doesn't remove files already added.  The caller is responsible
- * for cleaning up.
+ * For removals, this function never fails.
  */
 static int cgroup_addrm_files(struct cgroup *cgrp, struct cftype cfts[],
                              bool is_add)
 {
-       struct cftype *cft;
+       struct cftype *cft, *cft_end = NULL;
        int ret;
 
        lockdep_assert_held(&cgroup_mutex);
 
-       for (cft = cfts; cft->name[0] != '\0'; cft++) {
+restart:
+       for (cft = cfts; cft != cft_end && cft->name[0] != '\0'; cft++) {
                /* does cft->flags tell us to skip this file on @cgrp? */
                if ((cft->flags & __CFTYPE_ONLY_ON_DFL) && !cgroup_on_dfl(cgrp))
                        continue;
                        if (ret) {
                                pr_warn("%s: failed to add %s, err=%d\n",
                                        __func__, cft->name, ret);
-                               return ret;
+                               cft_end = cft;
+                               is_add = false;
+                               goto restart;
                        }
                } else {
                        cgroup_rm_file(cgrp, cft);