-
-
Save agentzh/26deab4b091b43a8bcab81c3c6fc89e1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/runtime/print_flush.c b/runtime/print_flush.c | |
index 18b3e8f62..d707b95c3 100644 | |
--- a/runtime/print_flush.c | |
+++ b/runtime/print_flush.c | |
@@ -37,7 +37,19 @@ void stp_print_flush(_stp_pbuf *pb) | |
#ifdef STP_BULKMODE | |
#ifdef NO_PERCPU_HEADERS | |
{ | |
+ struct context* __restrict__ c = NULL; | |
char *bufp = pb->buf; | |
+ int inode_locked; | |
+ | |
+ c = _stp_runtime_entryfn_get_context(); | |
+ | |
+ if (!(inode_locked = _stp_transport_lock_relay_inode())) { | |
+ atomic_inc (&_stp_transport_failures); | |
+#ifndef STP_TRANSPORT_RISKY | |
+ _stp_runtime_entryfn_put_context(c); | |
+ return; | |
+#endif | |
+ } | |
while (len > 0) { | |
size_t bytes_reserved; | |
@@ -55,15 +67,32 @@ void stp_print_flush(_stp_pbuf *pb) | |
break; | |
} | |
} | |
+ | |
+ if (inode_locked) { | |
+ _stp_transport_unlock_relay_inode(); | |
+ _stp_runtime_entryfn_put_context(c); | |
+ } | |
} | |
#else /* !NO_PERCPU_HEADERS */ | |
{ | |
+ struct context* __restrict__ c = NULL; | |
char *bufp = pb->buf; | |
struct _stp_trace t = { .sequence = _stp_seq_inc(), | |
.pdu_len = len}; | |
size_t bytes_reserved; | |
+ int inode_locked; | |
+ | |
+ c = _stp_runtime_entryfn_get_context(); | |
+ | |
+ if (!(inode_locked = _stp_transport_lock_relay_inode())) { | |
+ atomic_inc (&_stp_transport_failures); | |
+#ifndef STP_TRANSPORT_RISKY | |
+ _stp_runtime_entryfn_put_context(c); | |
+ return; | |
+#endif | |
+ } | |
bytes_reserved = _stp_data_write_reserve(sizeof(struct _stp_trace), &entry); | |
if (likely(entry && bytes_reserved > 0)) { | |
@@ -73,7 +102,7 @@ void stp_print_flush(_stp_pbuf *pb) | |
} | |
else { | |
atomic_inc(&_stp_transport_failures); | |
- return; | |
+ goto done; | |
} | |
while (len > 0) { | |
@@ -90,6 +119,13 @@ void stp_print_flush(_stp_pbuf *pb) | |
break; | |
} | |
} | |
+ | |
+ done: | |
+ | |
+ if (inode_locked) { | |
+ _stp_transport_unlock_relay_inode(); | |
+ _stp_runtime_entryfn_put_context(c); | |
+ } | |
} | |
#endif /* !NO_PERCPU_HEADERS */ | |
@@ -110,6 +146,7 @@ void stp_print_flush(_stp_pbuf *pb) | |
unsigned long flags; | |
struct context* __restrict__ c = NULL; | |
char *bufp = pb->buf; | |
+ int inode_locked; | |
/* Prevent probe reentrancy on _stp_print_lock. | |
* | |
@@ -129,6 +166,14 @@ void stp_print_flush(_stp_pbuf *pb) | |
*/ | |
c = _stp_runtime_entryfn_get_context(); | |
+ if (!(inode_locked = _stp_transport_lock_relay_inode())) { | |
+ atomic_inc (&_stp_transport_failures); | |
+#ifndef STP_TRANSPORT_RISKY | |
+ _stp_runtime_entryfn_put_context(c); | |
+ return; | |
+#endif | |
+ } | |
+ | |
dbug_trans(1, "calling _stp_data_write...\n"); | |
stp_spin_lock_irqsave(&_stp_print_lock, flags); | |
while (len > 0) { | |
@@ -148,6 +193,10 @@ void stp_print_flush(_stp_pbuf *pb) | |
} | |
} | |
stp_spin_unlock_irqrestore(&_stp_print_lock, flags); | |
+ | |
+ if (inode_locked) | |
+ _stp_transport_unlock_relay_inode(); | |
+ | |
_stp_runtime_entryfn_put_context(c); | |
} | |
#endif /* STP_TRANSPORT_VERSION != 1 */ | |
diff --git a/runtime/transport/relay_v2.c b/runtime/transport/relay_v2.c | |
index 7a364efa5..d9fe7f6ce 100644 | |
--- a/runtime/transport/relay_v2.c | |
+++ b/runtime/transport/relay_v2.c | |
@@ -405,7 +405,12 @@ _stp_data_write_reserve(size_t size_request, void **entry) | |
return -EINVAL; | |
buf = _stp_get_rchan_subbuf(_stp_relay_data.rchan->buf, | |
- smp_processor_id()); | |
+#ifdef STP_BULKMODE | |
+ smp_processor_id() | |
+#else | |
+ 0 | |
+#endif | |
+ ); | |
if (unlikely(buf->offset + size_request > buf->chan->subbuf_size)) { | |
size_request = __stp_relay_switch_subbuf(buf, size_request); | |
if (!size_request) | |
@@ -428,3 +433,43 @@ static int _stp_data_write_commit(void *entry) | |
/* Nothing to do here. */ | |
return 0; | |
} | |
+ | |
+static int _stp_transport_lock_relay_inode(void) | |
+{ | |
+ struct rchan_buf *buf; | |
+ struct inode *inode; | |
+ | |
+ buf = _stp_get_rchan_subbuf(_stp_relay_data.rchan->buf, | |
+#ifdef STP_BULKMODE | |
+ smp_processor_id() | |
+#else | |
+ 0 | |
+#endif | |
+ ); | |
+ if (buf == NULL) | |
+ return 0; | |
+ | |
+ inode = buf->dentry->d_inode; | |
+ | |
+ return down_write_trylock(&inode->i_rwsem); | |
+} | |
+ | |
+static void _stp_transport_unlock_relay_inode(void) | |
+{ | |
+ struct rchan_buf *buf; | |
+ struct inode *inode; | |
+ | |
+ buf = _stp_get_rchan_subbuf(_stp_relay_data.rchan->buf, | |
+#ifdef STP_BULKMODE | |
+ smp_processor_id() | |
+#else | |
+ 0 | |
+#endif | |
+ ); | |
+ if (buf == NULL) | |
+ return; | |
+ | |
+ inode = buf->dentry->d_inode; | |
+ | |
+ up_write(&inode->i_rwsem); | |
+} | |
diff --git a/runtime/transport/relayfs.c b/runtime/transport/relayfs.c | |
index d8fa4e049..51c487b91 100644 | |
--- a/runtime/transport/relayfs.c | |
+++ b/runtime/transport/relayfs.c | |
@@ -186,3 +186,14 @@ static int _stp_data_write_commit(void *entry) | |
/* Nothing to do here. */ | |
return 0; | |
} | |
+ | |
+static int _stp_transport_lock_relay_inode(void) | |
+{ | |
+ /* Nothing to do here. */ | |
+ return 1; | |
+} | |
+ | |
+static void _stp_transport_unlock_relay_inode(void) | |
+{ | |
+ /* Nothing to do here. */ | |
+} | |
diff --git a/runtime/transport/ring_buffer.c b/runtime/transport/ring_buffer.c | |
index 43e014bae..d161c8660 100644 | |
--- a/runtime/transport/ring_buffer.c | |
+++ b/runtime/transport/ring_buffer.c | |
@@ -827,3 +827,14 @@ static void _stp_transport_data_fs_overwrite(int overwrite) | |
dbug_trans(0, "setting ovewrite to %d\n", overwrite); | |
_stp_relay_data.overwrite_flag = overwrite; | |
} | |
+ | |
+static int _stp_transport_lock_relay_inode(void) | |
+{ | |
+ /* Nothing to do here. */ | |
+ return 1; | |
+} | |
+ | |
+static void _stp_transport_unlock_relay_inode(void) | |
+{ | |
+ /* Nothing to do here. */ | |
+} | |
diff --git a/runtime/transport/transport.h b/runtime/transport/transport.h | |
index 0cf2a7ca3..030719564 100644 | |
--- a/runtime/transport/transport.h | |
+++ b/runtime/transport/transport.h | |
@@ -67,6 +67,23 @@ enum _stp_transport_state { | |
*/ | |
static enum _stp_transport_state _stp_transport_get_state(void); | |
+/* | |
+ * _stp_transport_lock_relay_inode | |
+ * | |
+ * This function locks the relay file inode to protect against relay readers | |
+ * (i.e., staprun/stapio). | |
+ * Returns whether the lock is successfully obtained. | |
+ */ | |
+static int _stp_transport_lock_relay_inode(void); | |
+ | |
+/* | |
+ * _stp_transport_unlock_relay_inode | |
+ * | |
+ * This function releases the lock obtained by _stp_transport_lock_relay_inode. | |
+ * should only call this when the lock is indeed obtained. | |
+ */ | |
+static int _stp_transport_lock_relay_inode(void); | |
+ | |
/* | |
* _stp_transport_data_fs_init | |
* |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment