From: sashiko-bot@kernel.org
To: "Jie Gan" <jie.gan@oss.qualcomm.com>
Cc: devicetree@vger.kernel.org, robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v22 7/8] coresight: ctcu: enable byte-cntr for TMC ETR devices
Date: Tue, 10 Nov 2026 03:59:07 +0000 [thread overview]
Message-ID: <sashiko-outbox-206158@kernel.org> (raw)
In-Reply-To: <20261110-enable-byte-cntr-for-ctcu-v22-7-05d48c0eb110@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 7 potential
issues to consider:
- [Medium] coresight: ctcu: unsynchronized concurrent read() in
tmc_byte_cntr_get_data()
- [Medium] coresight: ctcu: state desynchronization in
ctcu_byte_cntr_start() and stop()
- [Medium] coresight: tmc: broken ETR_MODE_RESRV fallback in
tmc_read_prepare_etr()
- [Medium] coresight: tmc: tmc_read() converts byte-cntr negative errors
into EOF
- [Medium] coresight: ctcu: BYTECNTRVAL register not reset in
ctcu_platform_remove()
- [Medium] coresight: ctcu: UAF race between byte_cntr_sysfs_ops and
CTCU teardown
- [Medium] coresight: ctcu: byte-cntr state desync on generic read
fallback and unprepare
--
commit a4fb3ce63a75e273453b0d77a16ba13d3f857042
Author: Jie Gan <jie.gan@oss.qualcomm.com>
coresight: ctcu: enable byte-cntr for TMC ETR devices
This commit adds CTCU byte-counter interrupt support for TMC ETR sinks so
trace data can be transferred from rotating ETR buffers to userspace while
tracing is active.
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c
> new file mode 100644
> index 0000000000000..56a9aa2f693ab
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-byte-cntr.c
[ ... ]
> +static struct ctcu_byte_cntr *ctcu_get_byte_cntr(struct coresight_device *ctcu,
> + struct coresight_device *etr)
> +{
> + struct ctcu_byte_cntr *byte_cntr_data;
> + struct ctcu_drvdata *drvdata;
> + int port;
> +
> + /* The ETR may not be connected to a CTCU device */
> + if (!ctcu)
> + return NULL;
> +
> + drvdata = dev_get_drvdata(ctcu->dev.parent);
> + port = coresight_get_in_port(etr, ctcu);
> + if (port < 0 || port >= ETR_MAX_NUM)
> + return NULL;
> +
> + byte_cntr_data = &drvdata->byte_cntr_data[port];
> + /* The port is not initialized by ctcu_byte_cntr_init() */
> + if (!byte_cntr_data->ctcu_drvdata)
> + return NULL;
> +
> + return byte_cntr_data;
> +}
[Severity: Medium]
Can an in-flight byte_cntr_sysfs_ops call race with ctcu_platform_remove()
and cause a use-after-free of ctcu, ctcu->pdata, or drvdata?
tmc_read_prepare_etr(), tmc_etr_get_sysfs_trace(), and
tmc_read_unprepare_etr() load byte_cntr_sysfs_ops with READ_ONCE() and call
into coresight-ctcu without holding a lock or pinning the CTCU device.
Because session_done is initialized as completed and is only reinitialized
after tmc_read_prepare_byte_cntr() looks up ctcu and byte_cntr_data (and
remains completed throughout generic ETR sysfs reads), ctcu_platform_remove()
does not wait for callers that have already loaded byte_cntr_sysfs_ops:
CPU0 CPU1
tmc_read_prepare_etr()
ops = READ_ONCE(byte_cntr_sysfs_ops)
ops->read_prepare(drvdata)
ctcu = tmc_etr_get_ctcu_device()
ctcu_platform_remove()
wait_for_completion(&session_done)
ctcu_byte_cntr_put_ops(drvdata)
ctcu_remove(pdev)
coresight_unregister(csdev)
ctcu_get_byte_cntr(ctcu, ...)
coresight_get_in_port(etr, ctcu) <-- use-after-free
If a second CTCU device is present, ctcu_byte_cntr_put_ops() does not clear
byte_cntr_sysfs_ops at all when the first CTCU is removed.
> +
> +/*
> + * ctcu_byte_cntr_get_data() - reads data from the deactivated and filled buffer.
> + * The byte-cntr reading work reads data from the deactivated and filled buffer.
> + * The read operation waits for a buffer to become available, either filled or
> + * upon timeout, and then reads trace data from the synced buffer.
> + */
> +static ssize_t tmc_byte_cntr_get_data(struct tmc_drvdata *etr_drvdata, loff_t pos,
> + size_t len, char **bufpp)
> +{
> + struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
> + struct device *dev = &etr_drvdata->csdev->dev;
> + struct ctcu_byte_cntr *byte_cntr_data;
> + struct etr_buf *sysfs_buf;
> + atomic_t *irq_cnt;
> + ssize_t actual;
> + int ret;
> +
> + /* No byte-cntr read session, let the caller use the generic read */
> + byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
> + if (!byte_cntr_data || !byte_cntr_data->irq_enabled ||
> + !byte_cntr_data->reading)
> + return -EINVAL;
> +
> + /*
> + * A zero-length read must not be treated as the end of the buffer,
> + * otherwise the unread data of the current buffer would be dropped.
> + */
> + if (!len)
> + return 0;
> +
> + irq_cnt = &byte_cntr_data->irq_cnt;
> +
> +wait_buffer:
> + if (!byte_cntr_data->buf_node) {
> + ret = wait_event_interruptible_timeout(byte_cntr_data->wq,
> + (atomic_read(irq_cnt) >= MAX_IRQ_CNT - 1) ||
> + !byte_cntr_data->enable,
> + BYTE_CNTR_TIMEOUT);
> + if (ret < 0)
> + return ret;
> + /*
> + * The current etr_buf is almost full or timeout is triggered,
> + * so switch the buffer and mark the switched buffer as reading.
> + */
> + if (byte_cntr_data->enable) {
> + byte_cntr_data->buf_node =
> + tmc_etr_switch_buf_node(etr_drvdata);
> + if (!byte_cntr_data->buf_node) {
> + /*
> + * The sink has stopped, let the generic read
> + * handle the last etr_buf.
> + */
> + if (coresight_get_mode(etr_drvdata->csdev) != CS_MODE_SYSFS)
> + return 0;
> +
> + dev_err(dev, "Switch buffer failed for the byte-cntr\n");
> + return -ENOMEM;
> + }
> +
> + /*
> + * Get the interrupt count of the switched out etr_buf
> + * and reset it for the next etr_buf.
> + */
> + if (atomic_xchg(irq_cnt, 0) >= MAX_IRQ_CNT)
> + dev_warn(dev, "Data overwrite happened\n");
> + } else {
> + /*
> + * The CTCU device is removed while the sink is still
> + * running. The generic read can't be used then as the
> + * buffer in use is not synced yet, end the reading.
> + */
> + if (READ_ONCE(byte_cntr_data->removing) &&
> + coresight_get_mode(etr_drvdata->csdev) == CS_MODE_SYSFS)
> + return -ENODEV;
> +
> + /* Exit byte-cntr reading */
> + return 0;
> + }
> + }
> +
> + pos = byte_cntr_data->buf_node->pos;
> + sysfs_buf = byte_cntr_data->buf_node->sysfs_buf;
> + actual = tmc_etr_read_sysfs_buf(sysfs_buf, pos, len, bufpp);
> + if (actual <= 0) {
> + /* Reset buf_node upon reading is finished or failed */
> + byte_cntr_data->buf_node->reading = false;
> + byte_cntr_data->buf_node = NULL;
> +
> + /*
> + * Nothing in the buffer, waiting for the next buffer
> + * to be filled.
> + */
> + if (actual == 0)
> + goto wait_buffer;
> + }
> +
> + return actual;
> +}
[Severity: Medium]
Can concurrent read() calls on the same open /dev/tmc_etrX file descriptor
race on byte_cntr_data->buf_node and cause a NULL pointer dereference?
/dev/tmc_etrX is a character device opened with nonseekable_open(), so VFS
does not serialize concurrent read() calls with file->f_pos_lock. While
byte_cntr_data->reading prevents a second open(), two threads sharing one
open file descriptor can enter tmc_byte_cntr_get_data() concurrently:
CPU0 CPU1
tmc_byte_cntr_get_data() tmc_byte_cntr_get_data()
if (!byte_cntr_data->buf_node) if (!byte_cntr_data->buf_node)
wait_event_interruptible_timeout() wait_event_interruptible_timeout()
buf_node = tmc_etr_switch_buf_node()
buf_node = tmc_etr_switch_buf_node()
/* returns NULL: no free node */
return -ENOMEM;
pos = byte_cntr_data->buf_node->pos; <-- NULL pointer dereference
Similarly, while one reader is in copy_to_user() in tmc_read() before
tmc_etr_update_buf_node_pos(), a second reader can reach the end of the
buffer, clear buf_node->reading, and call tmc_etr_switch_buf_node() to
restart ETR DMA into the buffer still being copied to userspace.
> +
> +static int tmc_read_prepare_byte_cntr(struct tmc_drvdata *etr_drvdata)
> +{
> + struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
> + struct ctcu_byte_cntr *byte_cntr_data;
> + unsigned long flags;
> + int ret = 0;
[ ... ]
> + reinit_completion(&byte_cntr_data->session_done);
> + byte_cntr_data->reading = true;
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
> +
> + /* Setup an available etr_buf_list for byte-cntr */
> + ret = tmc_create_etr_buf_list(etr_drvdata, 2);
> + if (ret)
> + goto err_reading;
[Severity: Medium]
What happens if the ETR is in ETR_MODE_RESRV when byte-cntr is enabled, or
if a second open() races with an active fallback read session?
ctcu_byte_cntr_start() does not reject ETR_MODE_RESRV, so
tmc_create_etr_buf_list() returns -EINVAL. tmc_read_prepare_etr() treats
-EINVAL from read_prepare() as meaning byte-cntr is not configured and falls
back to the generic sysfs read path, calling __tmc_etr_disable_hw() and
setting drvdata->reading = true while byte_cntr_data->enable and
byte_cntr_data->irq_enabled remain true.
Because tmc_read_prepare_byte_cntr() sets byte_cntr_data->reading = true
before tmc_create_etr_buf_list() allocates a node and checks
drvdata->reading, a subsequent open() during that fallback read session
briefly sets byte_cntr_data->reading = true. A concurrent read() in the
first session then enters tmc_byte_cntr_get_data() instead of reading
drvdata->sysfs_buf and fails with -ENOMEM because etr_buf_list is empty.
[ ... ]
> +static int tmc_read_unprepare_byte_cntr(struct tmc_drvdata *etr_drvdata)
> +{
> + struct coresight_device *ctcu = tmc_etr_get_ctcu_device(etr_drvdata);
> + struct ctcu_byte_cntr *byte_cntr_data;
> +
> + /*
> + * Do the unprepare operation only when the byte_cntr_data->reading
> + * is truly set
> + */
> + byte_cntr_data = ctcu_get_byte_cntr(ctcu, etr_drvdata->csdev);
> + if (!byte_cntr_data || !byte_cntr_data->irq_enabled ||
> + !byte_cntr_data->reading)
> + return -EINVAL;
> +
> + tmc_clean_etr_buf_list(etr_drvdata);
> +
> + /* disable_irq_wake() may sleep on slow-bus irqchips, call it unlocked */
> + disable_irq_wake(byte_cntr_data->irq);
> +
> + /*
> + * The byte-cntr register is not accessed here: the trace path, which
> + * keeps the CTCU powered, may have been released already. It is reset
> + * when the path is disabled.
> + */
> + scoped_guard(raw_spinlock_irqsave, &byte_cntr_data->spin_lock) {
> + byte_cntr_data->buf_node = NULL;
> + byte_cntr_data->reading = false;
[Severity: Medium]
Does clearing etr_buf_list before clearing byte_cntr_data->reading allow a
new trace session to start with byte-cntr skipped?
ctcu_byte_cntr_start() skips enabling byte-cntr when
byte_cntr_data->reading is set, relying on tmc_enable_etr_sink_sysfs() to
fail with -EBUSY while etr_buf_list is non-empty. Because
tmc_read_unprepare_byte_cntr() empties etr_buf_list and calls
disable_irq_wake() before clearing byte_cntr_data->reading, a concurrent
trace enable in that window sees byte_cntr_data->reading == true in
ctcu_byte_cntr_start() and an empty etr_buf_list in
tmc_enable_etr_sink_sysfs(), starting the trace without byte-cntr.
> + /*
> + * Complete the session with reading cleared in one critical
> + * section, so that a new session can't start in between.
> + * ctcu_platform_remove() may free byte_cntr_data after this,
> + * don't use it anymore.
> + */
> + complete_all(&byte_cntr_data->session_done);
> + }
> +
> + module_put(THIS_MODULE);
> +
> + return 0;
> +}
> +
> +static const struct tmc_sysfs_ops byte_cntr_sysfs_ops = {
> + .read_prepare = tmc_read_prepare_byte_cntr,
> + .read_unprepare = tmc_read_unprepare_byte_cntr,
> + .get_trace_data = tmc_byte_cntr_get_data,
> +};
> +
> +/* Start the byte-cntr function when the path is enabled. */
> +void ctcu_byte_cntr_start(struct coresight_device *csdev, struct coresight_path *path)
> +{
> + struct coresight_device *sink = coresight_get_sink(path);
> + struct tmc_drvdata *etr_drvdata;
> + struct ctcu_byte_cntr *byte_cntr_data;
> +
> + byte_cntr_data = ctcu_get_byte_cntr(csdev, sink);
> + if (!byte_cntr_data)
> + return;
> +
> + etr_drvdata = dev_get_drvdata(sink->dev.parent);
> + guard(raw_spinlock_irqsave)(&byte_cntr_data->spin_lock);
> + /*
> + * Don't start byte-cntr function when irq_enabled is not set, when the
> + * CTCU device is being removed, or when the read of the previous trace
> + * is still in progress: the sink can't be enabled until it is finished.
> + */
> + if (!byte_cntr_data->irq_enabled || byte_cntr_data->removing ||
> + byte_cntr_data->reading)
> + return;
> +
> + /*
> + * Don't touch the count and the threshold if the byte-cntr is already
> + * started by another path of the same sink, as the buffer_size may have
> + * been changed since then while the etr_buf in use is not.
> + */
> + if (byte_cntr_data->enable)
> + return;
> +
> + /* A new trace starts with an empty etr_buf */
> + atomic_set(&byte_cntr_data->irq_cnt, 0);
> +
> + /*
> + * Configure the byte-cntr register to enable IRQ while the path is
> + * enabled, the CTCU is powered then. The configured size is 5% of the
> + * buffer_size.
> + */
> + ctcu_cfg_byte_cntr_reg(byte_cntr_data->ctcu_drvdata,
> + etr_drvdata->size / MAX_IRQ_CNT,
> + byte_cntr_data->irq_ctrl_offset);
> + byte_cntr_data->enable = true;
> +}
> +
> +/* Stop the byte-cntr function when the path is disabled. */
> +void ctcu_byte_cntr_stop(struct coresight_device *csdev, struct coresight_path *path)
> +{
> + struct coresight_device *sink = coresight_get_sink(path);
> + struct ctcu_byte_cntr *byte_cntr_data;
> +
> + if (coresight_get_mode(sink) == CS_MODE_SYSFS)
> + return;
[Severity: Medium]
Can byte_cntr_data->irq_enabled, byte_cntr_data->enable, and the ETR sink
state get out of sync across start, read prepare, and stop?
The ABI documentation states that changing irq_enabled while tracing does
not start or stop byte-cntr for the running trace, but irq_enabled_store()
only checks byte_cntr_data[port].reading:
1. If a trace is started with irq_enabled == 1 and irq_enabled is set to 0
before opening /dev/tmc_etrX, tmc_read_prepare_byte_cntr() sees
!byte_cntr_data->irq_enabled and returns -EINVAL. tmc_read_prepare_etr()
then falls back to the generic read and stops the ETR while
byte_cntr_data->enable and the IRQCTRL register remain active.
2. If a first path starts tracing on the ETR with irq_enabled == 0, and
irq_enabled is then set to 1 before a second path to the same ETR is
enabled, ctcu_byte_cntr_start() only checks byte_cntr_data->enable (not
whether the sink is already active) and starts byte-cntr mid-trace using
etr_drvdata->size. If enabling a later component on that second path
fails, ctcu_byte_cntr_stop() sees coresight_get_mode(sink) == CS_MODE_SYSFS
from the first path and returns without undoing byte_cntr_data->enable or
zeroing irq_ctrl_offset.
3. If a fallback generic read is open (etr_drvdata->reading == true) when
the trace path is disabled, tmc_disable_etr_sink() returns -EBUSY and
leaves the sink mode as CS_MODE_SYSFS, so ctcu_byte_cntr_stop() returns
early without disabling irq_ctrl_offset or clearing byte_cntr_data->enable
before the path is released.
> diff --git a/drivers/hwtracing/coresight/coresight-ctcu-core.c b/drivers/hwtracing/coresight/coresight-ctcu-core.c
> index 739105acb0a13..564ecc5ad5153 100644
> --- a/drivers/hwtracing/coresight/coresight-ctcu-core.c
> +++ b/drivers/hwtracing/coresight/coresight-ctcu-core.c
[ ... ]
> @@ -244,10 +355,59 @@ static int ctcu_platform_probe(struct platform_device *pdev)
> static void ctcu_platform_remove(struct platform_device *pdev)
> {
> struct ctcu_drvdata *drvdata = platform_get_drvdata(pdev);
> + struct ctcu_byte_cntr *byte_cntr_data;
> + unsigned long flags;
> + int i;
>
> if (WARN_ON(!drvdata))
> return;
>
> + /*
> + * Signal all active byte-cntr readers to exit, then wait for them to
> + * finish before resetting the ops pointer and freeing driver data.
> + * Without this, a reader blocked in wait_event_interruptible_timeout()
> + * would access the freed ctcu_drvdata wait-queue head (use-after-free).
> + *
> + * The wait ends only when the userspace closes the tmc_etr file, so an
> + * unbind with the file left open blocks until then. Unloading the module
> + * is rejected with -EBUSY while a read session is open, so only a manual
> + * unbind can block here.
> + */
> + for (i = 0; i < ETR_MAX_NUM; i++) {
> + byte_cntr_data = &drvdata->byte_cntr_data[i];
> + /* The port was not initialized by ctcu_byte_cntr_init() */
> + if (!byte_cntr_data->irq)
> + continue;
> +
> + raw_spin_lock_irqsave(&byte_cntr_data->spin_lock, flags);
> + /*
> + * Set enable=false to signal teardown to racing readers, and
> + * removing=true to keep a new path from enabling byte-cntr again.
> + */
> + byte_cntr_data->enable = false;
> + byte_cntr_data->removing = true;
> + raw_spin_unlock_irqrestore(&byte_cntr_data->spin_lock, flags);
[Severity: Medium]
Should ctcu_platform_remove() clear the hardware irq_ctrl_offset register
when byte_cntr_data->enable is true?
Setting byte_cntr_data->enable = false here without writing 0 to
irq_ctrl_offset means ctcu_byte_cntr_stop() will see enable == false and
skip clearing the register as well, leaving the CTCU hardware firing
byte-counter interrupts while wait_for_completion() waits for the file to be
closed and until the trace path is disabled.
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index cc341cdf8d8e5..d856f0a190f72 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
[ ... ]
> +ssize_t tmc_etr_get_sysfs_trace(struct tmc_drvdata *drvdata,
> + loff_t pos, size_t len, char **bufpp)
> +{
> + ssize_t ret;
> + const struct tmc_sysfs_ops *byte_cntr_ops = READ_ONCE(byte_cntr_sysfs_ops);
> +
> + if (byte_cntr_ops) {
> + ret = byte_cntr_ops->get_trace_data(drvdata, pos, len, bufpp);
> + /*
> + * -EINVAL means byte-cntr has no active read session. 0 means
> + * byte-cntr has no more data because the sink has stopped, the
> + * last etr_buf is read by the generic read. Anything else is
> + * the result of the byte-cntr session.
> + */
> + if (ret != -EINVAL && ret != 0)
> + return ret;
> + }
> +
> + return tmc_etr_read_sysfs_buf(drvdata->sysfs_buf, pos, len, bufpp);
> +}
[Severity: Medium]
Doesn't tmc_read() turn negative error codes from tmc_etr_get_sysfs_trace()
into 0 (EOF)?
tmc_byte_cntr_get_data() returns -ERESTARTSYS when interrupted by a signal
(as well as -ENOMEM and -ENODEV on failure), and tmc_etr_get_sysfs_trace()
propagates those negative values. However, the caller in tmc_read() drops
all negative returns:
drivers/hwtracing/coresight/coresight-tmc-core.c:tmc_read() {
...
actual = tmc_get_sysfs_trace(drvdata, *ppos, len, &bufp);
if (actual <= 0)
return 0;
...
}
Any signal delivered while waiting in wait_event_interruptible_timeout()
causes read() to return 0 (EOF) instead of -ERESTARTSYS, terminating trace
collection early while the ETR is still tracing.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261110-enable-byte-cntr-for-ctcu-v22-0-05d48c0eb110@oss.qualcomm.com?part=7
next prev parent reply other threads:[~2026-11-10 3:59 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-10 3:21 [PATCH v22 0/8] coresight: ctcu: Enable byte-cntr function for TMC ETR Jie Gan
2026-11-10 3:21 ` [PATCH v22 1/8] coresight: core: refactor ctcu_get_active_port and make it generic Jie Gan
2026-11-10 3:21 ` [PATCH v22 2/8] coresight: tmc: add create/clean functions for etr_buf_list Jie Gan
2026-11-10 3:21 ` [PATCH v22 3/8] coresight: tmc: add a function to switch the ETR to a free etr_buf Jie Gan
2026-11-10 3:50 ` sashiko-bot
2026-11-10 3:21 ` [PATCH v22 4/8] coresight: tmc: introduce tmc_sysfs_ops to wrap sysfs read operations Jie Gan
2026-11-10 3:21 ` [PATCH v22 5/8] coresight: etr: add a new function to retrieve the CTCU device Jie Gan
2026-11-10 3:21 ` [PATCH v22 6/8] dt-bindings: arm: add an interrupt property for Coresight CTCU Jie Gan
2026-11-10 3:21 ` [PATCH v22 7/8] coresight: ctcu: enable byte-cntr for TMC ETR devices Jie Gan
2026-11-10 3:59 ` sashiko-bot [this message]
2026-11-10 3:21 ` [PATCH v22 8/8] arm64: dts: qcom: lemans: add interrupts to CTCU device Jie Gan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-206158@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=jie.gan@oss.qualcomm.com \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox