diff --git a/include/ircd/cl.h b/include/ircd/cl.h
index 3872795fc..9787c9313 100644
--- a/include/ircd/cl.h
+++ b/include/ircd/cl.h
@@ -210,12 +210,12 @@ struct ircd::cl::exec
 
 	static const opts opts_default;
 
+	// View buffer in the GTT which the device will read (synchronous closure).
+	exec(data &, const pair<size_t, off_t> &, const write_closure & = nullptr, const opts & = opts_default);
+
 	// View data written by the device to the GTT (synchronous closure).
 	exec(data &, const pair<size_t, off_t> &, const read_closure &, const opts & = opts_default);
 
-	// View buffer in the GTT which the device will read (synchronous closure).
-	exec(data &, const pair<size_t, off_t> &, const write_closure &, const opts & = opts_default);
-
 	// Copy data from the buffer to the GTT for use by the device.
 	exec(data &, const const_buffer &, const opts & = opts_default);
 
diff --git a/ircd/cl.cc b/ircd/cl.cc
index e18c925ae..9fb654928 100644
--- a/ircd/cl.cc
+++ b/ircd/cl.cc
@@ -1119,10 +1119,11 @@ try
 
 	// Wait for the mapping to complete before presenting the buffer.
 	wait();
-	closure(const_buffer
-	{
-		reinterpret_cast<const char *>(ptr), size
-	});
+	if(likely(closure))
+		closure(const_buffer
+		{
+			reinterpret_cast<const char *>(ptr), size
+		});
 }
 catch(const std::exception &e)
 {
@@ -1182,7 +1183,7 @@ try
 	};
 
 	cl_map_flags flags {0};
-	flags |= CL_MAP_WRITE;
+	flags |= opts.duplex || opts.blocking? CL_MAP_WRITE: CL_MAP_WRITE_INVALIDATE_REGION;
 	flags |= opts.duplex? CL_MAP_READ: 0;
 
 	int err {CL_SUCCESS};
@@ -1240,10 +1241,11 @@ try
 	}};
 
 	wait();
-	closure(mutable_buffer
-	{
-		reinterpret_cast<char *>(ptr), size
-	});
+	if(closure)
+		closure(mutable_buffer
+		{
+			reinterpret_cast<char *>(ptr), size
+		});
 }
 catch(const std::exception &e)
 {