Skip to content

Instantly share code, notes, and snippets.

@agentzh
Created June 18, 2020 23:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agentzh/26deab4b091b43a8bcab81c3c6fc89e1 to your computer and use it in GitHub Desktop.
Save agentzh/26deab4b091b43a8bcab81c3c6fc89e1 to your computer and use it in GitHub Desktop.
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