From: <shaibran@amazon.com>
To: <ferruh.yigit@amd.com>
Cc: <dev@dpdk.org>, Shai Brandes <shaibran@amazon.com>
Subject: [PATCH v4 14/31] net/ena/base: phc feature modifications
Date: Tue, 12 Mar 2024 20:06:59 +0200 [thread overview]
Message-ID: <20240312180716.8515-15-shaibran@amazon.com> (raw)
In-Reply-To: <20240312180716.8515-1-shaibran@amazon.com>
From: Shai Brandes <shaibran@amazon.com>
1. PHC algorithm is updated to support reading new PHC values.
2. Update default PHC expiration timeout.
3. Fix a theoretical PHC destroy race.
4. Adjust PHC for multiple devices.
5. PHC activation version check point.
Signed-off-by: Shai Brandes <shaibran@amazon.com>
Reviewed-by: Amit Bernstein <amitbern@amazon.com>
---
drivers/net/ena/base/ena_com.c | 111 ++++++++++++------
drivers/net/ena/base/ena_com.h | 31 +++--
.../net/ena/base/ena_defs/ena_admin_defs.h | 45 +++++--
3 files changed, 135 insertions(+), 52 deletions(-)
diff --git a/drivers/net/ena/base/ena_com.c b/drivers/net/ena/base/ena_com.c
index 31c37b0ab3..fb3ad27d0a 100644
--- a/drivers/net/ena/base/ena_com.c
+++ b/drivers/net/ena/base/ena_com.c
@@ -41,10 +41,12 @@
#define ENA_MAX_ADMIN_POLL_US 5000
/* PHC definitions */
-#define ENA_PHC_DEFAULT_EXPIRE_TIMEOUT_USEC 20
+#define ENA_PHC_DEFAULT_EXPIRE_TIMEOUT_USEC 10
#define ENA_PHC_DEFAULT_BLOCK_TIMEOUT_USEC 1000
-#define ENA_PHC_TIMESTAMP_ERROR 0xFFFFFFFFFFFFFFFF
+#define ENA_PHC_MAX_ERROR_BOUND 0xFFFFFFFF
#define ENA_PHC_REQ_ID_OFFSET 0xDEAD
+#define ENA_PHC_ERROR_FLAGS (ENA_ADMIN_PHC_ERROR_FLAG_TIMESTAMP | \
+ ENA_ADMIN_PHC_ERROR_FLAG_ERROR_BOUND)
/*****************************************************************************/
/*****************************************************************************/
@@ -1778,16 +1780,21 @@ int ena_com_phc_config(struct ena_com_dev *ena_dev)
struct ena_admin_set_feat_cmd set_feat_cmd;
int ret = 0;
- /* Get device PHC default configuration */
- ret = ena_com_get_feature(ena_dev, &get_feat_resp, ENA_ADMIN_PHC_CONFIG, 0);
+ /* Get default device PHC configuration */
+ ret = ena_com_get_feature(ena_dev,
+ &get_feat_resp,
+ ENA_ADMIN_PHC_CONFIG,
+ ENA_ADMIN_PHC_FEATURE_VERSION_0);
if (unlikely(ret)) {
ena_trc_err(ena_dev, "Failed to get PHC feature configuration, error: %d\n", ret);
return ret;
}
- /* Supporting only readless PHC retrieval */
- if (get_feat_resp.u.phc.type != ENA_ADMIN_PHC_TYPE_READLESS) {
- ena_trc_err(ena_dev, "Unsupported PHC type, error: %d\n", ENA_COM_UNSUPPORTED);
+ /* Supporting only PHC V0 (readless mode with error bound) */
+ if (get_feat_resp.u.phc.version != ENA_ADMIN_PHC_FEATURE_VERSION_0) {
+ ena_trc_err(ena_dev, "Unsupported PHC version (0x%X), error: %d\n",
+ get_feat_resp.u.phc.version,
+ ENA_COM_UNSUPPORTED);
return ENA_COM_UNSUPPORTED;
}
@@ -1804,11 +1811,11 @@ int ena_com_phc_config(struct ena_com_dev *ena_dev)
get_feat_resp.u.phc.block_timeout_usec :
ENA_PHC_DEFAULT_BLOCK_TIMEOUT_USEC;
- /* Sanity check - expire timeout must not be above skip timeout */
+ /* Sanity check - expire timeout must not exceed block timeout */
if (phc->expire_timeout_usec > phc->block_timeout_usec)
phc->expire_timeout_usec = phc->block_timeout_usec;
- /* Prepare PHC feature command with PHC output address */
+ /* Prepare PHC config feature command */
memset(&set_feat_cmd, 0x0, sizeof(set_feat_cmd));
set_feat_cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE;
set_feat_cmd.feat_common.feature_id = ENA_ADMIN_PHC_CONFIG;
@@ -1840,13 +1847,16 @@ int ena_com_phc_config(struct ena_com_dev *ena_dev)
void ena_com_phc_destroy(struct ena_com_dev *ena_dev)
{
struct ena_com_phc_info *phc = &ena_dev->phc;
-
- phc->active = false;
+ unsigned long flags = 0;
/* In case PHC is not supported by the device, silently exiting */
if (!phc->virt_addr)
return;
+ ENA_SPINLOCK_LOCK(phc->lock, flags);
+ phc->active = false;
+ ENA_SPINLOCK_UNLOCK(phc->lock, flags);
+
ENA_MEM_FREE_COHERENT(ena_dev->dmadev,
sizeof(*phc->virt_addr),
phc->virt_addr,
@@ -1857,15 +1867,14 @@ void ena_com_phc_destroy(struct ena_com_dev *ena_dev)
ENA_SPINLOCK_DESTROY(phc->lock);
}
-int ena_com_phc_get(struct ena_com_dev *ena_dev, u64 *timestamp)
+int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp)
{
volatile struct ena_admin_phc_resp *read_resp = ena_dev->phc.virt_addr;
+ const ena_time_high_res_t zero_system_time = ENA_TIME_INIT_HIGH_RES();
struct ena_com_phc_info *phc = &ena_dev->phc;
- ena_time_high_res_t initial_time = ENA_TIME_INIT_HIGH_RES();
- static ena_time_high_res_t start_time;
- unsigned long flags = 0;
ena_time_high_res_t expire_time;
ena_time_high_res_t block_time;
+ unsigned long flags = 0;
int ret = ENA_COM_OK;
if (!phc->active) {
@@ -1876,9 +1885,10 @@ int ena_com_phc_get(struct ena_com_dev *ena_dev, u64 *timestamp)
ENA_SPINLOCK_LOCK(phc->lock, flags);
/* Check if PHC is in blocked state */
- if (unlikely(ENA_TIME_COMPARE_HIGH_RES(start_time, initial_time))) {
+ if (unlikely(ENA_TIME_COMPARE_HIGH_RES(phc->system_time, zero_system_time))) {
/* Check if blocking time expired */
- block_time = ENA_GET_SYSTEM_TIMEOUT_HIGH_RES(start_time, phc->block_timeout_usec);
+ block_time = ENA_GET_SYSTEM_TIMEOUT_HIGH_RES(phc->system_time,
+ phc->block_timeout_usec);
if (!ENA_TIME_EXPIRE_HIGH_RES(block_time)) {
/* PHC is still in blocked state, skip PHC request */
phc->stats.phc_skp++;
@@ -1886,22 +1896,23 @@ int ena_com_phc_get(struct ena_com_dev *ena_dev, u64 *timestamp)
goto skip;
}
- /* PHC is in active state, update statistics according to req_id and timestamp */
+ /* PHC is in active state, update statistics according to req_id and error_flags */
if ((READ_ONCE16(read_resp->req_id) != phc->req_id) ||
- read_resp->timestamp == ENA_PHC_TIMESTAMP_ERROR)
+ (read_resp->error_flags & ENA_PHC_ERROR_FLAGS)) {
/* Device didn't update req_id during blocking time or timestamp is invalid,
* this indicates on a device error
*/
phc->stats.phc_err++;
- else
+ } else {
/* Device updated req_id during blocking time with valid timestamp */
phc->stats.phc_exp++;
+ }
}
/* Setting relative timeouts */
- start_time = ENA_GET_SYSTEM_TIME_HIGH_RES();
- block_time = ENA_GET_SYSTEM_TIMEOUT_HIGH_RES(start_time, phc->block_timeout_usec);
- expire_time = ENA_GET_SYSTEM_TIMEOUT_HIGH_RES(start_time, phc->expire_timeout_usec);
+ phc->system_time = ENA_GET_SYSTEM_TIME_HIGH_RES();
+ block_time = ENA_GET_SYSTEM_TIMEOUT_HIGH_RES(phc->system_time, phc->block_timeout_usec);
+ expire_time = ENA_GET_SYSTEM_TIMEOUT_HIGH_RES(phc->system_time, phc->expire_timeout_usec);
/* We expect the device to return this req_id once the new PHC timestamp is updated */
phc->req_id++;
@@ -1918,35 +1929,45 @@ int ena_com_phc_get(struct ena_com_dev *ena_dev, u64 *timestamp)
while (1) {
if (unlikely(ENA_TIME_EXPIRE_HIGH_RES(expire_time))) {
/* Gave up waiting for updated req_id, PHC enters into blocked state until
- * passing blocking time
+ * passing blocking time, during this time any get PHC timestamp or
+ * error bound requests will fail with device busy error
*/
+ phc->error_bound = ENA_PHC_MAX_ERROR_BOUND;
ret = ENA_COM_DEVICE_BUSY;
break;
}
/* Check if req_id was updated by the device */
if (READ_ONCE16(read_resp->req_id) != phc->req_id) {
- /* req_id was not updated by the device, check again on next loop */
+ /* req_id was not updated by the device yet, check again on next loop */
continue;
}
- /* req_id was updated which indicates that PHC timestamp was updated too */
- *timestamp = read_resp->timestamp;
-
- /* PHC timestamp validty check */
- if (unlikely(*timestamp == ENA_PHC_TIMESTAMP_ERROR)) {
- /* Retrieved invalid PHC timestamp, PHC enters into blocked state until
- * passing blocking time
+ /* req_id was updated by the device which indicates that PHC timestamp, error_bound
+ * and error_flags are updated too, checking errors before retrieving timestamp and
+ * error_bound values
+ */
+ if (unlikely(read_resp->error_flags & ENA_PHC_ERROR_FLAGS)) {
+ /* Retrieved timestamp or error bound errors, PHC enters into blocked state
+ * until passing blocking time, during this time any get PHC timestamp or
+ * error bound requests will fail with device busy error
*/
+ phc->error_bound = ENA_PHC_MAX_ERROR_BOUND;
ret = ENA_COM_DEVICE_BUSY;
break;
}
- /* Retrieved valid PHC timestamp */
+ /* PHC timestamp value is returned to the caller */
+ *timestamp = read_resp->timestamp;
+
+ /* Error bound value is cached for future retrieval by caller */
+ phc->error_bound = read_resp->error_bound;
+
+ /* Update statistic on valid PHC timestamp retrieval */
phc->stats.phc_cnt++;
/* This indicates PHC state is active */
- start_time = initial_time;
+ phc->system_time = zero_system_time;
break;
}
@@ -1956,6 +1977,24 @@ int ena_com_phc_get(struct ena_com_dev *ena_dev, u64 *timestamp)
return ret;
}
+int ena_com_phc_get_error_bound(struct ena_com_dev *ena_dev, u32 *error_bound)
+{
+ struct ena_com_phc_info *phc = &ena_dev->phc;
+ u32 local_error_bound = phc->error_bound;
+
+ if (!phc->active) {
+ ena_trc_err(ena_dev, "PHC feature is not active in the device\n");
+ return ENA_COM_UNSUPPORTED;
+ }
+
+ if (local_error_bound == ENA_PHC_MAX_ERROR_BOUND)
+ return ENA_COM_DEVICE_BUSY;
+
+ *error_bound = local_error_bound;
+
+ return ENA_COM_OK;
+}
+
int ena_com_mmio_reg_read_request_init(struct ena_com_dev *ena_dev)
{
struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
@@ -2453,9 +2492,9 @@ int ena_com_dev_reset(struct ena_com_dev *ena_dev,
reset_val |= reset_reason_lsb << ENA_REGS_DEV_CTL_RESET_REASON_SHIFT;
- if (ena_com_get_cap(ena_dev, ENA_ADMIN_EXTENDED_RESET_REASONS)) {
+ if (ena_com_get_cap(ena_dev, ENA_ADMIN_EXTENDED_RESET_REASONS))
reset_val |= reset_reason_msb << ENA_REGS_DEV_CTL_RESET_REASON_EXT_SHIFT;
- } else if (reset_reason_msb) {
+ else if (reset_reason_msb) {
/* In case the device does not support intended
* extended reset reason fallback to generic
*/
diff --git a/drivers/net/ena/base/ena_com.h b/drivers/net/ena/base/ena_com.h
index cd054595d7..c62016cc06 100644
--- a/drivers/net/ena/base/ena_com.h
+++ b/drivers/net/ena/base/ena_com.h
@@ -274,6 +274,9 @@ struct ena_com_phc_info {
/* PHC shared memory - virtual address */
struct ena_admin_phc_resp *virt_addr;
+ /* System time of last PHC request */
+ ena_time_high_res_t system_time;
+
/* Spin lock to ensure a single outstanding PHC read */
ena_spinlock_t lock;
@@ -293,17 +296,20 @@ struct ena_com_phc_info {
*/
u32 block_timeout_usec;
+ /* PHC shared memory - physical address */
+ dma_addr_t phys_addr;
+
+ /* PHC shared memory handle */
+ ena_mem_handle_t mem_handle;
+
+ /* Cached error bound per timestamp sample */
+ u32 error_bound;
+
/* Request id sent to the device */
u16 req_id;
/* True if PHC is active in the device */
bool active;
-
- /* PHC shared memory - memory handle */
- ena_mem_handle_t mem_handle;
-
- /* PHC shared memory - physical address */
- dma_addr_t phys_addr;
};
struct ena_rss {
@@ -468,12 +474,19 @@ int ena_com_phc_config(struct ena_com_dev *ena_dev);
*/
void ena_com_phc_destroy(struct ena_com_dev *ena_dev);
-/* ena_com_phc_get - Retrieve PHC timestamp
+/* ena_com_phc_get_timestamp - Retrieve PHC timestamp
+ * @ena_dev: ENA communication layer struct
+ * @timestamp: Retrieved PHC timestamp
+ * @return - 0 on success, negative value on failure
+ */
+int ena_com_phc_get_timestamp(struct ena_com_dev *ena_dev, u64 *timestamp);
+
+/* ena_com_phc_get_error_bound - Retrieve cached PHC error bound
* @ena_dev: ENA communication layer struct
- * @timestamp: Retrieve PHC timestamp
+ * @error_bound: Cached PHC error bound
* @return - 0 on success, negative value on failure
*/
-int ena_com_phc_get(struct ena_com_dev *ena_dev, u64 *timestamp);
+int ena_com_phc_get_error_bound(struct ena_com_dev *ena_dev, u32 *error_bound);
/* ena_com_set_mmio_read_mode - Enable/disable the indirect mmio reg read mechanism
* @ena_dev: ENA communication layer struct
diff --git a/drivers/net/ena/base/ena_defs/ena_admin_defs.h b/drivers/net/ena/base/ena_defs/ena_admin_defs.h
index 438e4a1085..ce8a26721e 100644
--- a/drivers/net/ena/base/ena_defs/ena_admin_defs.h
+++ b/drivers/net/ena/base/ena_defs/ena_admin_defs.h
@@ -144,8 +144,14 @@ enum ena_admin_get_stats_scope {
ENA_ADMIN_ETH_TRAFFIC = 1,
};
-enum ena_admin_get_phc_type {
- ENA_ADMIN_PHC_TYPE_READLESS = 0,
+enum ena_admin_phc_feature_version {
+ /* Readless with error_bound */
+ ENA_ADMIN_PHC_FEATURE_VERSION_0 = 0,
+};
+
+enum ena_admin_phc_error_flags {
+ ENA_ADMIN_PHC_ERROR_FLAG_TIMESTAMP = BIT(0),
+ ENA_ADMIN_PHC_ERROR_FLAG_ERROR_BOUND = BIT(1),
};
/* ENA SRD configuration for ENI */
@@ -987,7 +993,8 @@ struct ena_admin_host_info {
* 5 : reserved
* 6 : rx_page_reuse
* 7 : tx_ipv6_csum_offload
- * 31:8 : reserved
+ * 8 : phc
+ * 31:9 : reserved
*/
uint32_t driver_supported_features;
};
@@ -1073,10 +1080,10 @@ struct ena_admin_queue_ext_feature_desc {
};
struct ena_admin_feature_phc_desc {
- /* PHC type as defined in enum ena_admin_get_phc_type,
- * used only for GET command.
+ /* PHC version as defined in enum ena_admin_phc_feature_version,
+ * used only for GET command as max supported PHC version by the device.
*/
- uint8_t type;
+ uint8_t version;
/* Reserved - MBZ */
uint8_t reserved1[3];
@@ -1272,13 +1279,23 @@ struct ena_admin_ena_mmio_req_read_less_resp {
};
struct ena_admin_phc_resp {
+ /* Request Id, received from DB register */
uint16_t req_id;
uint8_t reserved1[6];
+ /* PHC timestamp (nsec) */
uint64_t timestamp;
- uint8_t reserved2[48];
+ uint8_t reserved2[8];
+
+ /* Timestamp error limit (nsec) */
+ uint32_t error_bound;
+
+ /* Bit field of enum ena_admin_phc_error_flags */
+ uint32_t error_flags;
+
+ uint8_t reserved3[32];
};
/* aq_common_desc */
@@ -1381,6 +1398,8 @@ struct ena_admin_phc_resp {
#define ENA_ADMIN_HOST_INFO_RX_PAGE_REUSE_MASK BIT(6)
#define ENA_ADMIN_HOST_INFO_TX_IPV6_CSUM_OFFLOAD_SHIFT 7
#define ENA_ADMIN_HOST_INFO_TX_IPV6_CSUM_OFFLOAD_MASK BIT(7)
+#define ENA_ADMIN_HOST_INFO_PHC_SHIFT 8
+#define ENA_ADMIN_HOST_INFO_PHC_MASK BIT(8)
/* feature_rss_ind_table */
#define ENA_ADMIN_FEATURE_RSS_IND_TABLE_ONE_ENTRY_UPDATE_MASK BIT(0)
@@ -1879,6 +1898,18 @@ static inline void set_ena_admin_feature_rss_ind_table_one_entry_update(struct e
p->flags |= val & ENA_ADMIN_FEATURE_RSS_IND_TABLE_ONE_ENTRY_UPDATE_MASK;
}
+static inline uint32_t get_ena_admin_host_info_phc(const struct ena_admin_host_info *p)
+{
+ return (p->driver_supported_features &
+ ENA_ADMIN_HOST_INFO_PHC_MASK) >> ENA_ADMIN_HOST_INFO_PHC_SHIFT;
+}
+
+static inline void set_ena_admin_host_info_phc(struct ena_admin_host_info *p, uint32_t val)
+{
+ p->driver_supported_features |= (val << ENA_ADMIN_HOST_INFO_PHC_SHIFT) &
+ ENA_ADMIN_HOST_INFO_PHC_MASK;
+}
+
static inline uint8_t get_ena_admin_aenq_common_desc_phase(const struct ena_admin_aenq_common_desc *p)
{
return p->flags & ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK;
--
2.17.1
next prev parent reply other threads:[~2024-03-12 18:09 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-12 18:06 [PATCH v4 00/31] net/ena: v2.9.0 driver release shaibran
2024-03-12 18:06 ` [PATCH v4 01/31] net/ena: rework the metrics multi-process functions shaibran
2024-03-12 18:06 ` [PATCH v4 02/31] net/ena: report new supported link speed capabilities shaibran
2024-03-12 18:06 ` [PATCH v4 03/31] net/ena: update imissed stat with Rx overruns shaibran
2024-03-13 15:59 ` Ferruh Yigit
2024-03-12 18:06 ` [PATCH v4 04/31] net/ena: sub-optimal configuration notifications support shaibran
2024-03-12 18:06 ` [PATCH v4 05/31] net/ena: fix fast mbuf free shaibran
2024-03-13 15:58 ` Ferruh Yigit
2024-03-12 18:06 ` [PATCH v4 06/31] net/ena: restructure the llq policy setting process shaibran
2024-03-12 18:06 ` [PATCH v4 07/31] net/ena/base: limit exponential backoff exp shaibran
2024-03-13 15:58 ` Ferruh Yigit
2024-03-12 18:06 ` [PATCH v4 08/31] net/ena/base: add a new csum offload bit shaibran
2024-03-13 15:58 ` Ferruh Yigit
2024-03-12 18:06 ` [PATCH v4 09/31] net/ena/base: optimize Rx ring submission queue shaibran
2024-03-12 18:06 ` [PATCH v4 10/31] net/ena/base: rename fields in completion descriptors shaibran
2024-03-12 18:06 ` [PATCH v4 11/31] net/ena/base: use correct read once on u8 field shaibran
2024-03-12 18:06 ` [PATCH v4 12/31] net/ena/base: add completion descriptor corruption check shaibran
2024-03-12 18:06 ` [PATCH v4 13/31] net/ena/base: malformed Tx descriptor error reason shaibran
2024-03-13 15:58 ` Ferruh Yigit
2024-03-12 18:06 ` shaibran [this message]
2024-03-12 18:07 ` [PATCH v4 15/31] net/ena/base: restructure interrupt handling shaibran
2024-03-13 15:58 ` Ferruh Yigit
2024-03-12 18:07 ` [PATCH v4 16/31] net/ena/base: add unlikely to error checks shaibran
2024-03-12 18:07 ` [PATCH v4 17/31] net/ena/base: missing admin interrupt reset reason shaibran
2024-03-12 18:07 ` [PATCH v4 18/31] net/ena/base: check for existing keep alive notification shaibran
2024-03-12 18:07 ` [PATCH v4 19/31] net/ena/base: modify memory barrier comment shaibran
2024-03-12 18:07 ` [PATCH v4 20/31] net/ena/base: rework Rx ring submission queue shaibran
2024-03-12 18:07 ` [PATCH v4 21/31] net/ena/base: remove operating system type enum shaibran
2024-03-12 18:07 ` [PATCH v4 22/31] net/ena/base: handle command abort shaibran
2024-03-12 18:07 ` [PATCH v4 23/31] net/ena/base: add support for device reset request shaibran
2024-03-12 18:07 ` [PATCH v4 24/31] net/ena: cosmetic changes shaibran
2024-03-13 15:58 ` Ferruh Yigit
2024-03-12 18:07 ` [PATCH v4 25/31] net/ena/base: modify customer metrics memory management shaibran
2024-03-12 18:07 ` [PATCH v4 26/31] net/ena/base: modify logs to use unsigned format specifier shaibran
2024-03-12 18:07 ` [PATCH v4 27/31] net/ena: update device-preferred size of rings shaibran
2024-03-12 18:07 ` [PATCH v4 28/31] net/ena: exhaust interrupt callbacks in device close shaibran
2024-03-12 18:07 ` [PATCH v4 29/31] net/ena: support max large llq depth from the device shaibran
2024-03-12 18:07 ` [PATCH v4 30/31] net/ena: control path pure polling mode shaibran
2024-03-12 18:07 ` [PATCH v4 31/31] net/ena: upgrade driver version to 2.9.0 shaibran
2024-03-13 16:00 ` [PATCH v4 00/31] net/ena: v2.9.0 driver release Ferruh Yigit
2024-03-13 17:07 ` Brandes, Shai
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=20240312180716.8515-15-shaibran@amazon.com \
--to=shaibran@amazon.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@amd.com \
/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;
as well as URLs for NNTP newsgroup(s).