diff --git a/src/cell.c b/src/cell.c
index abc349e8290aeaeae22ce8d6cfc046bf5c3ecc3a..b18be6372042bba11a7a0c8002e4e41be90a0a2f 100644
--- a/src/cell.c
+++ b/src/cell.c
@@ -3615,26 +3615,28 @@ int cell_unskip_black_holes_tasks(struct cell *c, struct scheduler *s) {
       /* Activate the send/recv tasks. */
       if (ci_nodeID != nodeID) {
         if (cj_active) {
-          scheduler_activate(s, ci->mpi.hydro.recv_xv);
-          scheduler_activate(s, ci->mpi.hydro.recv_rho);
+          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
+          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
 
           /* If the local cell is active, more stuff will be needed. */
-          scheduler_activate_send(s, cj->mpi.black_holes.send, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart,
+                                  ci_nodeID);
           cell_activate_drift_bpart(cj, s);
 
           /* If the local cell is active, send its ti_end values. */
-          scheduler_activate_send(s, cj->mpi.black_holes.send_ti, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.send, task_subtype_spart,
+                                  ci_nodeID);
         }
 
         if (ci_active) {
-          scheduler_activate(s, ci->mpi.black_holes.recv);
+          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart);
 
           /* If the foreign cell is active, we want its ti_end values. */
-          scheduler_activate(s, ci->mpi.black_holes.recv_ti);
+          scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_bpart);
 
           /* Is the foreign cell active and will need stuff from us? */
-          scheduler_activate_send(s, cj->mpi.hydro.send_xv, ci_nodeID);
-          scheduler_activate_send(s, cj->mpi.hydro.send_rho, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.send, task_subtype_xv, ci_nodeID);
+          scheduler_activate_send(s, cj->mpi.send, task_subtype_rho, ci_nodeID);
 
           /* Drift the cell which will be sent; note that not all sent
              particles will be drifted, only those that are needed. */
@@ -3644,26 +3646,28 @@ int cell_unskip_black_holes_tasks(struct cell *c, struct scheduler *s) {
       } else if (cj_nodeID != nodeID) {
         /* If the local cell is active, receive data from the foreign cell. */
         if (ci_active) {
-          scheduler_activate(s, cj->mpi.hydro.recv_xv);
-          scheduler_activate(s, cj->mpi.hydro.recv_rho);
+          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
+          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
 
           /* If the local cell is active, more stuff will be needed. */
-          scheduler_activate_send(s, ci->mpi.black_holes.send, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart,
+                                  cj_nodeID);
           cell_activate_drift_bpart(ci, s);
 
           /* If the local cell is active, send its ti_end values. */
-          scheduler_activate_send(s, ci->mpi.black_holes.send_ti, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart,
+                                  cj_nodeID);
         }
 
         if (cj_active) {
-          scheduler_activate(s, cj->mpi.black_holes.recv);
+          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart);
 
           /* If the foreign cell is active, we want its ti_end values. */
-          scheduler_activate(s, cj->mpi.black_holes.recv_ti);
+          scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_bpart);
 
           /* Is the foreign cell active and will need stuff from us? */
-          scheduler_activate_send(s, ci->mpi.hydro.send_xv, cj_nodeID);
-          scheduler_activate_send(s, ci->mpi.hydro.send_rho, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.send, task_subtype_xv, cj_nodeID);
+          scheduler_activate_send(s, ci->mpi.send, task_subtype_rho, cj_nodeID);
 
           /* Drift the cell which will be sent; note that not all sent
              particles will be drifted, only those that are needed. */
diff --git a/src/engine.c b/src/engine.c
index 2457b364ae2d9b2df0d045695633eb86c63cee61..238820420d80c86d8d1359b78e6c9ee5b4b58f8e 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2873,11 +2873,10 @@ void engine_collect_end_of_step_recurse_stars(struct cell *c,
 void engine_collect_end_of_step_recurse_black_holes(struct cell *c,
                                                     const struct engine *e) {
 
-/* Skip super-cells (Their values are already set) */
-#ifdef WITH_MPI
-  if (c->timestep != NULL || c->mpi.black_holes.recv_ti != NULL) return;
-#else
+  /* Skip super-cells (Their values are already set) */
   if (c->timestep != NULL) return;
+#ifdef WITH_MPI
+  if (cell_get_recv(c, task_subtype_tend_bpart) != NULL) return;
 #endif /* WITH_MPI */
 
 #ifdef SWIFT_DEBUG_CHECKS
diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c
index 47e8f18bf9af21aac4439eb2ae37abad308fb607..e5e570064be12b031e24fa8622c7c49f254c6b0b 100644
--- a/src/engine_maketasks.c
+++ b/src/engine_maketasks.c
@@ -345,8 +345,8 @@ void engine_addtasks_send_black_holes(struct engine *e, struct cell *ci,
       scheduler_addunlock(s, ci->super->timestep, t_ti);
     }
 
-    engine_addlink(e, &ci->mpi.black_holes.send, t_feedback);
-    engine_addlink(e, &ci->mpi.black_holes.send_ti, t_ti);
+    engine_addlink(e, &ci->mpi.send, t_feedback);
+    engine_addlink(e, &ci->mpi.send, t_ti);
   }
 
   /* Recurse? */
@@ -545,20 +545,22 @@ void engine_addtasks_recv_black_holes(struct engine *e, struct cell *c,
                              c->mpi.tag, 0, c, NULL);
   }
 
-  c->mpi.black_holes.recv = t_feedback;
-  c->mpi.black_holes.recv_ti = t_ti;
+  if (t_feedback != NULL) {
+    engine_addlink(e, &c->mpi.recv, t_feedback);
+    engine_addlink(e, &c->mpi.recv, t_ti);
 
 #ifdef SWIFT_DEBUG_CHECKS
-  if (c->nodeID == e->nodeID) error("Local cell!");
+    if (c->nodeID == e->nodeID) error("Local cell!");
 #endif
 
-  for (struct link *l = c->black_holes.density; l != NULL; l = l->next) {
-    scheduler_addunlock(s, l->t, t_feedback);
-  }
+    for (struct link *l = c->black_holes.density; l != NULL; l = l->next) {
+      scheduler_addunlock(s, l->t, t_feedback);
+    }
 
-  for (struct link *l = c->black_holes.feedback; l != NULL; l = l->next) {
-    scheduler_addunlock(s, t_feedback, l->t);
-    scheduler_addunlock(s, l->t, t_ti);
+    for (struct link *l = c->black_holes.feedback; l != NULL; l = l->next) {
+      scheduler_addunlock(s, t_feedback, l->t);
+      scheduler_addunlock(s, l->t, t_ti);
+    }
   }
 
   /* Recurse? */
diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c
index e7be14e267d48cb1a187fd2322be74718b46e110..ef6f1fbea2acfda9abc86ed15dd0abc4ca46e923 100644
--- a/src/engine_marktasks.c
+++ b/src/engine_marktasks.c
@@ -633,26 +633,30 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
         if (ci_nodeID != nodeID) {
 
           if (cj_active_black_holes) {
-            scheduler_activate(s, ci->mpi.hydro.recv_xv);
-            scheduler_activate(s, ci->mpi.hydro.recv_rho);
+            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_xv);
+            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_rho);
 
             /* If the local cell is active, more stuff will be needed. */
-            scheduler_activate_send(s, cj->mpi.black_holes.send, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.send, task_subtype_bpart,
+                                    ci_nodeID);
             cell_activate_drift_bpart(cj, s);
 
             /* If the local cell is active, send its ti_end values. */
-            scheduler_activate_send(s, cj->mpi.black_holes.send_ti, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.send, task_subtype_tend_bpart,
+                                    ci_nodeID);
           }
 
           if (ci_active_black_holes) {
-            scheduler_activate(s, ci->mpi.black_holes.recv);
+            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_bpart);
 
             /* If the foreign cell is active, we want its ti_end values. */
-            scheduler_activate(s, ci->mpi.black_holes.recv_ti);
+            scheduler_activate_recv(s, ci->mpi.recv, task_subtype_tend_bpart);
 
             /* Is the foreign cell active and will need stuff from us? */
-            scheduler_activate_send(s, cj->mpi.hydro.send_xv, ci_nodeID);
-            scheduler_activate_send(s, cj->mpi.hydro.send_rho, ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.send, task_subtype_xv,
+                                    ci_nodeID);
+            scheduler_activate_send(s, cj->mpi.send, task_subtype_rho,
+                                    ci_nodeID);
 
             /* Drift the cell which will be sent; note that not all sent
                particles will be drifted, only those that are needed. */
@@ -663,26 +667,30 @@ void engine_marktasks_mapper(void *map_data, int num_elements,
 
           /* If the local cell is active, receive data from the foreign cell. */
           if (ci_active_black_holes) {
-            scheduler_activate(s, cj->mpi.hydro.recv_xv);
-            scheduler_activate(s, cj->mpi.hydro.recv_rho);
+            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_xv);
+            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_rho);
 
             /* If the local cell is active, more stuff will be needed. */
-            scheduler_activate_send(s, ci->mpi.black_holes.send, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.send, task_subtype_bpart,
+                                    cj_nodeID);
             cell_activate_drift_bpart(ci, s);
 
             /* If the local cell is active, send its ti_end values. */
-            scheduler_activate_send(s, ci->mpi.black_holes.send_ti, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.send, task_subtype_tend_bpart,
+                                    cj_nodeID);
           }
 
           if (cj_active_black_holes) {
-            scheduler_activate(s, cj->mpi.black_holes.recv);
+            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_bpart);
 
             /* If the foreign cell is active, we want its ti_end values. */
-            scheduler_activate(s, cj->mpi.black_holes.recv_ti);
+            scheduler_activate_recv(s, cj->mpi.recv, task_subtype_tend_bpart);
 
             /* Is the foreign cell active and will need stuff from us? */
-            scheduler_activate_send(s, ci->mpi.hydro.send_xv, cj_nodeID);
-            scheduler_activate_send(s, ci->mpi.hydro.send_rho, cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.send, task_subtype_xv,
+                                    cj_nodeID);
+            scheduler_activate_send(s, ci->mpi.send, task_subtype_rho,
+                                    cj_nodeID);
 
             /* Drift the cell which will be sent; note that not all sent
                particles will be drifted, only those that are needed. */