[PATCH 59/62] relay

Chris Wilson chris at chris-wilson.co.uk
Wed Sep 19 21:47:44 UTC 2018


---
 kernel/relay.c | 39 +++++++++++++++++----------------------
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/kernel/relay.c b/kernel/relay.c
index 04f248644e06..53a4dbe4b7ee 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -24,7 +24,6 @@
 #include <linux/splice.h>
 
 /* list of open channels, for cpu hotplug */
-static DEFINE_MUTEX(relay_channels_mutex);
 static LIST_HEAD(relay_channels);
 
 /*
@@ -397,11 +396,11 @@ void relay_reset(struct rchan *chan)
 		return;
 	}
 
-	mutex_lock(&relay_channels_mutex);
+	cpus_read_lock();
 	for_each_possible_cpu(i)
 		if ((buf = *per_cpu_ptr(chan->buf, i)))
 			__relay_reset(buf, 0);
-	mutex_unlock(&relay_channels_mutex);
+	cpus_read_unlock();
 }
 EXPORT_SYMBOL_GPL(relay_reset);
 
@@ -522,19 +521,19 @@ int relay_prepare_cpu(unsigned int cpu)
 	struct rchan *chan;
 	struct rchan_buf *buf;
 
-	mutex_lock(&relay_channels_mutex);
 	list_for_each_entry(chan, &relay_channels, list) {
 		if ((buf = *per_cpu_ptr(chan->buf, cpu)))
 			continue;
+
 		buf = relay_open_buf(chan, cpu);
 		if (!buf) {
 			pr_err("relay: cpu %d buffer creation failed\n", cpu);
-			mutex_unlock(&relay_channels_mutex);
 			return -ENOMEM;
 		}
+
 		*per_cpu_ptr(chan->buf, cpu) = buf;
 	}
-	mutex_unlock(&relay_channels_mutex);
+
 	return 0;
 }
 
@@ -592,15 +591,16 @@ struct rchan *relay_open(const char *base_filename,
 	setup_callbacks(chan, cb);
 	kref_init(&chan->kref);
 
-	mutex_lock(&relay_channels_mutex);
+	cpus_read_lock();
 	for_each_online_cpu(i) {
 		buf = relay_open_buf(chan, i);
 		if (!buf)
 			goto free_bufs;
+
 		*per_cpu_ptr(chan->buf, i) = buf;
 	}
 	list_add(&chan->list, &relay_channels);
-	mutex_unlock(&relay_channels_mutex);
+	cpus_read_unlock();
 
 	return chan;
 
@@ -609,9 +609,9 @@ struct rchan *relay_open(const char *base_filename,
 		if ((buf = *per_cpu_ptr(chan->buf, i)))
 			relay_close_buf(buf);
 	}
+	cpus_read_unlock();
 
 	kref_put(&chan->kref, relay_destroy_channel);
-	mutex_unlock(&relay_channels_mutex);
 	return NULL;
 }
 EXPORT_SYMBOL_GPL(relay_open);
@@ -658,15 +658,11 @@ int relay_late_setup_files(struct rchan *chan,
 	if (!chan || !base_filename)
 		return -EINVAL;
 
-	strlcpy(chan->base_filename, base_filename, NAME_MAX);
-
-	mutex_lock(&relay_channels_mutex);
 	/* Is chan already set up? */
-	if (unlikely(chan->has_base_filename)) {
-		mutex_unlock(&relay_channels_mutex);
+	if (unlikely(cmpxchg(&chan->has_base_filename, 0, 1)))
 		return -EEXIST;
-	}
-	chan->has_base_filename = 1;
+
+	strlcpy(chan->base_filename, base_filename, NAME_MAX);
 	chan->parent = parent;
 
 	if (chan->is_global) {
@@ -679,7 +675,6 @@ int relay_late_setup_files(struct rchan *chan,
 				err = 0;
 			}
 		}
-		mutex_unlock(&relay_channels_mutex);
 		return err;
 	}
 
@@ -720,7 +715,6 @@ int relay_late_setup_files(struct rchan *chan,
 			break;
 	}
 	put_cpu();
-	mutex_unlock(&relay_channels_mutex);
 
 	return err;
 }
@@ -837,7 +831,7 @@ void relay_close(struct rchan *chan)
 	if (!chan)
 		return;
 
-	mutex_lock(&relay_channels_mutex);
+	cpus_read_lock();
 	if (chan->is_global && (buf = *per_cpu_ptr(chan->buf, 0)))
 		relay_close_buf(buf);
 	else
@@ -851,8 +845,9 @@ void relay_close(struct rchan *chan)
 		       chan->last_toobig, chan->subbuf_size);
 
 	list_del(&chan->list);
+	cpus_read_unlock();
+
 	kref_put(&chan->kref, relay_destroy_channel);
-	mutex_unlock(&relay_channels_mutex);
 }
 EXPORT_SYMBOL_GPL(relay_close);
 
@@ -875,11 +870,11 @@ void relay_flush(struct rchan *chan)
 		return;
 	}
 
-	mutex_lock(&relay_channels_mutex);
+	cpus_read_lock();
 	for_each_possible_cpu(i)
 		if ((buf = *per_cpu_ptr(chan->buf, i)))
 			relay_switch_subbuf(buf, 0);
-	mutex_unlock(&relay_channels_mutex);
+	cpus_read_unlock();
 }
 EXPORT_SYMBOL_GPL(relay_flush);
 
-- 
2.19.0



More information about the Intel-gfx-trybot mailing list