if (!unsched && assign) {
                for (i = 0; i < n; i++) {
                        e = cpuc->event_list[i];
-                       e->hw.flags |= PERF_X86_EVENT_COMMITTED;
                        if (x86_pmu.commit_scheduling)
                                x86_pmu.commit_scheduling(cpuc, i, assign[i]);
                }
        } else {
-               for (i = 0; i < n; i++) {
+               /*
+                * Compute the number of events already present; see
+                * x86_pmu_add(), validate_group() and x86_pmu_commit_txn().
+                * For the former two cpuc->n_events hasn't been updated yet,
+                * while for the latter cpuc->n_txn contains the number of
+                * events added in the current transaction.
+                */
+               i = cpuc->n_events;
+               if (cpuc->txn_flags & PERF_PMU_TXN_ADD)
+                       i -= cpuc->n_txn;
+
+               for (; i < n; i++) {
                        e = cpuc->event_list[i];
-                       /*
-                        * do not put_constraint() on comitted events,
-                        * because they are good to go
-                        */
-                       if ((e->hw.flags & PERF_X86_EVENT_COMMITTED))
-                               continue;
 
                        /*
                         * release events that failed scheduling
        struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
        int i;
 
-       /*
-        * event is descheduled
-        */
-       event->hw.flags &= ~PERF_X86_EVENT_COMMITTED;
-
        /*
         * If we're called during a txn, we only need to undo x86_pmu.add.
         * The events never got scheduled and ->cancel_txn will truncate
        if (n < 0)
                goto out;
 
-       fake_cpuc->n_events = n;
-
+       fake_cpuc->n_events = 0;
        ret = x86_pmu.schedule_events(fake_cpuc, n, NULL);
 
 out:
 
        int     overlap;
        int     flags;
 };
+
 /*
  * struct hw_perf_event.flags flags
  */
 #define PERF_X86_EVENT_PEBS_LDLAT      0x0001 /* ld+ldlat data address sampling */
 #define PERF_X86_EVENT_PEBS_ST         0x0002 /* st data address sampling */
 #define PERF_X86_EVENT_PEBS_ST_HSW     0x0004 /* haswell style datala, store */
-#define PERF_X86_EVENT_COMMITTED       0x0008 /* event passed commit_txn */
-#define PERF_X86_EVENT_PEBS_LD_HSW     0x0010 /* haswell style datala, load */
-#define PERF_X86_EVENT_PEBS_NA_HSW     0x0020 /* haswell style datala, unknown */
-#define PERF_X86_EVENT_EXCL            0x0040 /* HT exclusivity on counter */
-#define PERF_X86_EVENT_DYNAMIC         0x0080 /* dynamic alloc'd constraint */
-#define PERF_X86_EVENT_RDPMC_ALLOWED   0x0100 /* grant rdpmc permission */
-#define PERF_X86_EVENT_EXCL_ACCT       0x0200 /* accounted EXCL event */
-#define PERF_X86_EVENT_AUTO_RELOAD     0x0400 /* use PEBS auto-reload */
-#define PERF_X86_EVENT_LARGE_PEBS      0x0800 /* use large PEBS */
-
+#define PERF_X86_EVENT_PEBS_LD_HSW     0x0008 /* haswell style datala, load */
+#define PERF_X86_EVENT_PEBS_NA_HSW     0x0010 /* haswell style datala, unknown */
+#define PERF_X86_EVENT_EXCL            0x0020 /* HT exclusivity on counter */
+#define PERF_X86_EVENT_DYNAMIC         0x0040 /* dynamic alloc'd constraint */
+#define PERF_X86_EVENT_RDPMC_ALLOWED   0x0080 /* grant rdpmc permission */
+#define PERF_X86_EVENT_EXCL_ACCT       0x0100 /* accounted EXCL event */
+#define PERF_X86_EVENT_AUTO_RELOAD     0x0200 /* use PEBS auto-reload */
+#define PERF_X86_EVENT_LARGE_PEBS      0x0400 /* use large PEBS */
 
 struct amd_nb {
        int nb_id;  /* NorthBridge id */