diff --git a/src/cell.c b/src/cell.c
index 4502f5d265dc68540e16ed0e51e681cf5733f842..f85e4dbd2a71033b10852bc65a97b8eec6bf75f9 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -1328,7 +1328,7 @@ void cell_clear_drift_flags(struct cell *c, void *data) {
 }
 
 /**
- * @brief Activate the drifts on the given cell.
+ * @brief Activate the #part drifts on the given cell.
  */
 void cell_activate_drift_part(struct cell *c, struct scheduler *s) {
 
@@ -1354,6 +1354,14 @@ void cell_activate_drift_part(struct cell *c, struct scheduler *s) {
   }
 }
 
+/**
+ * @brief Activate the #gpart drifts on the given cell.
+ */
+void cell_activate_drift_gpart(struct cell *c, struct scheduler *s) {
+
+  scheduler_activate(s, c->super->drift_gpart);
+}
+
 /**
  * @brief Activate the sorts up a cell hierarchy.
  */
@@ -1843,6 +1851,25 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) {
     }
   }
 
+  /* Un-skip the gravity tasks involved with this cell. */
+  for (struct link *l = c->grav; l != NULL; l = l->next) {
+    struct task *t = l->t;
+    struct cell *ci = t->ci;
+    struct cell *cj = t->cj;
+
+    /* Only activate tasks that involve a local active cell. */
+    if ((cell_is_active(ci, e) && ci->nodeID == engine_rank) ||
+        (cj != NULL && cell_is_active(cj, e) && cj->nodeID == engine_rank)) {
+      scheduler_activate(s, t);
+
+      /* Set the drifting flags */
+      if (t->type == task_type_pair) {
+        cell_activate_drift_gpart(ci, s);
+        cell_activate_drift_gpart(cj, s);
+      }
+    }
+  }
+
   /* Unskip all the other task types. */
   if (c->nodeID == engine_rank && cell_is_active(c, e)) {
 
@@ -1850,15 +1877,12 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) {
       scheduler_activate(s, l->t);
     for (struct link *l = c->force; l != NULL; l = l->next)
       scheduler_activate(s, l->t);
-    for (struct link *l = c->grav; l != NULL; l = l->next)
-      scheduler_activate(s, l->t);
 
     if (c->extra_ghost != NULL) scheduler_activate(s, c->extra_ghost);
     if (c->ghost_in != NULL) scheduler_activate(s, c->ghost_in);
     if (c->ghost_out != NULL) scheduler_activate(s, c->ghost_out);
     if (c->ghost != NULL) scheduler_activate(s, c->ghost);
     if (c->init_grav != NULL) scheduler_activate(s, c->init_grav);
-    if (c->drift_gpart != NULL) scheduler_activate(s, c->drift_gpart);
     if (c->kick1 != NULL) scheduler_activate(s, c->kick1);
     if (c->kick2 != NULL) scheduler_activate(s, c->kick2);
     if (c->timestep != NULL) scheduler_activate(s, c->timestep);
diff --git a/src/cell.h b/src/cell.h
index e97400623dbb7a66aee981d21883fe4d8f73406a..82cda87444e60fde9eb4b9a6914c2ed1ba3a470d 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -402,6 +402,7 @@ void cell_store_pre_drift_values(struct cell *c);
 void cell_activate_subcell_tasks(struct cell *ci, struct cell *cj,
                                  struct scheduler *s);
 void cell_activate_drift_part(struct cell *c, struct scheduler *s);
+void cell_activate_drift_gpart(struct cell *c, struct scheduler *s);
 void cell_activate_sorts(struct cell *c, int sid, struct scheduler *s);
 void cell_clear_drift_flags(struct cell *c, void *data);
 void cell_set_super_mapper(void *map_data, int num_elements, void *extra_data);
diff --git a/src/engine.c b/src/engine.c
index 5cade0e2b25c1354df5d61a5a3662054a4475f70..5ed61430c47cbdd2030fd0b53473aca519cebb3e 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -156,6 +156,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) {
   const int periodic = e->s->periodic;
   const int is_with_hydro = (e->policy & engine_policy_hydro);
   const int is_self_gravity = (e->policy & engine_policy_self_gravity);
+  const int is_external_gravity = (e->policy & engine_policy_external_gravity);
   const int is_with_cooling = (e->policy & engine_policy_cooling);
   const int is_with_sourceterms = (e->policy & engine_policy_sourceterms);
 
@@ -171,11 +172,15 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) {
     /* Local tasks only... */
     if (c->nodeID == e->nodeID) {
 
-      /* Add the drift task. */
+      /* Add the drift tasks corresponding to the policy. */
       if (is_with_hydro) {
         c->drift_part = scheduler_addtask(s, task_type_drift_part,
                                           task_subtype_none, 0, 0, c, NULL);
       }
+      if (is_self_gravity || is_external_gravity) {
+        c->drift_gpart = scheduler_addtask(s, task_type_drift_gpart,
+                                           task_subtype_none, 0, 0, c, NULL);
+      }
 
       /* Add the two half kicks */
       c->kick1 = scheduler_addtask(s, task_type_kick1, task_subtype_none, 0, 0,
@@ -191,6 +196,7 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) {
       scheduler_addunlock(s, c->kick2, c->timestep);
       scheduler_addunlock(s, c->timestep, c->kick1);
 
+      /* Add the gravity tasks */
       if (is_self_gravity) {
 
         /* Initialisation of the multipoles */
@@ -220,14 +226,13 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) {
             scheduler_addtask(s, task_type_ghost, task_subtype_none, 0,
                               /* implicit = */ 1, c, NULL);
         engine_add_ghosts(e, c, c->ghost_in, c->ghost_out);
-      }
 
+/* Generate the extra ghost task. */
 #ifdef EXTRA_HYDRO_LOOP
-      /* Generate the extra ghost task. */
-      if (is_hydro)
         c->extra_ghost = scheduler_addtask(s, task_type_extra_ghost,
                                            task_subtype_none, 0, 0, c, NULL);
 #endif
+      }
 
       /* Cooling task */
       if (is_with_cooling) {
@@ -1840,11 +1845,9 @@ void engine_make_self_gravity_tasks(struct engine *e) {
     /* Make the ghosts implicit and add the dependencies */
     for (int n = 0; n < n_ghosts / 2; ++n) {
       ghosts[2 * n + 0] = scheduler_addtask(
-          sched, task_type_grav_ghost, task_subtype_none, 0, 0, NULL, NULL);
+          sched, task_type_grav_ghost, task_subtype_none, 0, 1, NULL, NULL);
       ghosts[2 * n + 1] = scheduler_addtask(
-          sched, task_type_grav_ghost, task_subtype_none, 0, 0, NULL, NULL);
-      ghosts[2 * n + 0]->implicit = 1;
-      ghosts[2 * n + 1]->implicit = 1;
+          sched, task_type_grav_ghost, task_subtype_none, 0, 1, NULL, NULL);
       scheduler_addunlock(sched, ghosts[2 * n + 0], s->grav_top_level);
       scheduler_addunlock(sched, s->grav_top_level, ghosts[2 * n + 1]);
     }
@@ -2064,6 +2067,7 @@ static inline void engine_make_self_gravity_dependencies(
     struct scheduler *sched, struct task *gravity, struct cell *c) {
 
   /* init --> gravity --> grav_down --> kick */
+  scheduler_addunlock(sched, c->super->drift_gpart, gravity);
   scheduler_addunlock(sched, c->super->init_grav, gravity);
   scheduler_addunlock(sched, gravity, c->super->grav_down);
 }
diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h
index 01ea6a073211a08430e77721f4c2e60ef7adfd04..d018ec8839036eaba5e7b581e4a2b990186cb673 100644
--- a/src/runner_doiact_grav.h
+++ b/src/runner_doiact_grav.h
@@ -78,6 +78,8 @@ void runner_do_grav_down(struct runner *r, struct cell *c, int timer) {
 
   } else { /* Leaf case */
 
+    if (!cell_are_gpart_drifted(c, e)) error("Un-drifted gparts");
+
     /* Apply accelerations to the particles */
     for (int i = 0; i < gcount; ++i) {
 
@@ -880,8 +882,8 @@ void runner_dopair_grav_pp(struct runner *r, struct cell *ci, struct cell *cj) {
   if (!cell_is_active(ci, e) && !cell_is_active(cj, e)) return;
 
   /* Let's start by drifting things */
-  if (!cell_are_gpart_drifted(ci, e)) cell_drift_gpart(ci, e);
-  if (!cell_are_gpart_drifted(cj, e)) cell_drift_gpart(cj, e);
+  if (!cell_are_gpart_drifted(ci, e)) error("Un-drifted gparts");
+  if (!cell_are_gpart_drifted(cj, e)) error("Un-drifted gparts");
 
   /* Can we use the Newtonian version or do we need the truncated one ? */
   if (!periodic) {
@@ -1365,7 +1367,7 @@ void runner_doself_grav_pp(struct runner *r, struct cell *c) {
   if (!cell_is_active(c, e)) return;
 
   /* Do we need to start by drifting things ? */
-  if (!cell_are_gpart_drifted(c, e)) cell_drift_gpart(c, e);
+  if (!cell_are_gpart_drifted(c, e)) error("Un-drifted gparts");
 
   /* Can we use the Newtonian version or do we need the truncated one ? */
   if (!periodic) {
diff --git a/src/scheduler.c b/src/scheduler.c
index 4081cde0489b1b439ceb46fc9b4e191541f15bef..fccad7eb54890f4ec585ed98aa74d9508ff88d59 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -649,18 +649,8 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
                                         ci->progeny[k]),
                       s);
         }
-      }
-
-      /* Otherwise, make sure the self task has a drift task */
-      else {
-
-        lock_lock(&ci->lock);
+      } /* Cell is split */
 
-        if (ci->drift_gpart == NULL)
-          ci->drift_gpart = scheduler_addtask(
-              s, task_type_drift_gpart, task_subtype_none, 0, 0, ci, NULL);
-        lock_unlock_blind(&ci->lock);
-      }
     } /* Self interaction */
 
     /* Pair interaction? */
@@ -675,28 +665,6 @@ static void scheduler_splittask_gravity(struct task *t, struct scheduler *s) {
         t->skip = 1;
         break;
       }
-
-      /* Should this task be split-up? */
-      if (0 && ci->split && cj->split) {
-
-        // MATTHIEU: nothing here for now
-
-      } else {
-
-        /* Create the drift for ci. */
-        lock_lock(&ci->lock);
-        if (ci->drift_gpart == NULL && ci->nodeID == engine_rank)
-          ci->drift_gpart = scheduler_addtask(
-              s, task_type_drift_gpart, task_subtype_none, 0, 0, ci, NULL);
-        lock_unlock_blind(&ci->lock);
-
-        /* Create the drift for cj. */
-        lock_lock(&cj->lock);
-        if (cj->drift_gpart == NULL && cj->nodeID == engine_rank)
-          cj->drift_gpart = scheduler_addtask(
-              s, task_type_drift_gpart, task_subtype_none, 0, 0, cj, NULL);
-        lock_unlock_blind(&cj->lock);
-      }
     } /* pair interaction? */
   }   /* iterate over the current task. */
 }