From: David Marchand <david.marchand@6wind.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v3 08/20] i40e: use the right debug macro
Date: Wed, 17 Sep 2014 15:46:40 +0200 [thread overview]
Message-ID: <1410961612-8571-9-git-send-email-david.marchand@6wind.com> (raw)
In-Reply-To: <1410961612-8571-1-git-send-email-david.marchand@6wind.com>
- Don't use DEBUGFUNC macro in non-shared code.
- Don't use printf for logs.
- We should avoid calling RTE_LOG directly as pmd provides a wrapper for logs.
- Replace some PMD_INIT_LOG(DEBUG, "some_func") with PMD_INIT_FUNC_TRACE().
Signed-off-by: David Marchand <david.marchand@6wind.com>
v2 Reviewed-by: Jay Rolette <rolette@infiniteio.com>
v2 Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
lib/librte_pmd_i40e/i40e_ethdev.c | 146 +++++++++++++++++-----------------
lib/librte_pmd_i40e/i40e_ethdev_vf.c | 4 +-
lib/librte_pmd_i40e/i40e_pf.c | 6 +-
lib/librte_pmd_i40e/i40e_rxtx.c | 64 +++++++--------
4 files changed, 111 insertions(+), 109 deletions(-)
diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c
index 4e65ca4..af2e1cb 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev.c
@@ -1059,24 +1059,23 @@ i40e_update_vsi_stats(struct i40e_vsi *vsi)
&oes->tx_errors, &nes->tx_errors);
vsi->offset_loaded = true;
-#ifdef RTE_LIBRTE_I40E_DEBUG_DRIVER
- printf("***************** VSI[%u] stats start *******************\n",
- vsi->vsi_id);
- printf("rx_bytes: %lu\n", nes->rx_bytes);
- printf("rx_unicast: %lu\n", nes->rx_unicast);
- printf("rx_multicast: %lu\n", nes->rx_multicast);
- printf("rx_broadcast: %lu\n", nes->rx_broadcast);
- printf("rx_discards: %lu\n", nes->rx_discards);
- printf("rx_unknown_protocol: %lu\n", nes->rx_unknown_protocol);
- printf("tx_bytes: %lu\n", nes->tx_bytes);
- printf("tx_unicast: %lu\n", nes->tx_unicast);
- printf("tx_multicast: %lu\n", nes->tx_multicast);
- printf("tx_broadcast: %lu\n", nes->tx_broadcast);
- printf("tx_discards: %lu\n", nes->tx_discards);
- printf("tx_errors: %lu\n", nes->tx_errors);
- printf("***************** VSI[%u] stats end *******************\n",
- vsi->vsi_id);
-#endif /* RTE_LIBRTE_I40E_DEBUG_DRIVER */
+ PMD_DRV_LOG(DEBUG, "***************** VSI[%u] stats start *******************",
+ vsi->vsi_id);
+ PMD_DRV_LOG(DEBUG, "rx_bytes: %lu", nes->rx_bytes);
+ PMD_DRV_LOG(DEBUG, "rx_unicast: %lu", nes->rx_unicast);
+ PMD_DRV_LOG(DEBUG, "rx_multicast: %lu", nes->rx_multicast);
+ PMD_DRV_LOG(DEBUG, "rx_broadcast: %lu", nes->rx_broadcast);
+ PMD_DRV_LOG(DEBUG, "rx_discards: %lu", nes->rx_discards);
+ PMD_DRV_LOG(DEBUG, "rx_unknown_protocol: %lu",
+ nes->rx_unknown_protocol);
+ PMD_DRV_LOG(DEBUG, "tx_bytes: %lu", nes->tx_bytes);
+ PMD_DRV_LOG(DEBUG, "tx_unicast: %lu", nes->tx_unicast);
+ PMD_DRV_LOG(DEBUG, "tx_multicast: %lu", nes->tx_multicast);
+ PMD_DRV_LOG(DEBUG, "tx_broadcast: %lu", nes->tx_broadcast);
+ PMD_DRV_LOG(DEBUG, "tx_discards: %lu", nes->tx_discards);
+ PMD_DRV_LOG(DEBUG, "tx_errors: %lu", nes->tx_errors);
+ PMD_DRV_LOG(DEBUG, "***************** VSI[%u] stats end *******************",
+ vsi->vsi_id);
}
/* Get all statistics of a port */
@@ -1277,69 +1276,74 @@ i40e_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
if (pf->main_vsi)
i40e_update_vsi_stats(pf->main_vsi);
-#ifdef RTE_LIBRTE_I40E_DEBUG_DRIVER
- printf("***************** PF stats start *******************\n");
- printf("rx_bytes: %lu\n", ns->eth.rx_bytes);
- printf("rx_unicast: %lu\n", ns->eth.rx_unicast);
- printf("rx_multicast: %lu\n", ns->eth.rx_multicast);
- printf("rx_broadcast: %lu\n", ns->eth.rx_broadcast);
- printf("rx_discards: %lu\n", ns->eth.rx_discards);
- printf("rx_unknown_protocol: %lu\n", ns->eth.rx_unknown_protocol);
- printf("tx_bytes: %lu\n", ns->eth.tx_bytes);
- printf("tx_unicast: %lu\n", ns->eth.tx_unicast);
- printf("tx_multicast: %lu\n", ns->eth.tx_multicast);
- printf("tx_broadcast: %lu\n", ns->eth.tx_broadcast);
- printf("tx_discards: %lu\n", ns->eth.tx_discards);
- printf("tx_errors: %lu\n", ns->eth.tx_errors);
-
- printf("tx_dropped_link_down: %lu\n", ns->tx_dropped_link_down);
- printf("crc_errors: %lu\n", ns->crc_errors);
- printf("illegal_bytes: %lu\n", ns->illegal_bytes);
- printf("error_bytes: %lu\n", ns->error_bytes);
- printf("mac_local_faults: %lu\n", ns->mac_local_faults);
- printf("mac_remote_faults: %lu\n", ns->mac_remote_faults);
- printf("rx_length_errors: %lu\n", ns->rx_length_errors);
- printf("link_xon_rx: %lu\n", ns->link_xon_rx);
- printf("link_xoff_rx: %lu\n", ns->link_xoff_rx);
+ PMD_DRV_LOG(DEBUG, "***************** PF stats start *******************");
+ PMD_DRV_LOG(DEBUG, "rx_bytes: %lu", ns->eth.rx_bytes);
+ PMD_DRV_LOG(DEBUG, "rx_unicast: %lu", ns->eth.rx_unicast);
+ PMD_DRV_LOG(DEBUG, "rx_multicast: %lu", ns->eth.rx_multicast);
+ PMD_DRV_LOG(DEBUG, "rx_broadcast: %lu", ns->eth.rx_broadcast);
+ PMD_DRV_LOG(DEBUG, "rx_discards: %lu", ns->eth.rx_discards);
+ PMD_DRV_LOG(DEBUG, "rx_unknown_protocol: %lu",
+ ns->eth.rx_unknown_protocol);
+ PMD_DRV_LOG(DEBUG, "tx_bytes: %lu", ns->eth.tx_bytes);
+ PMD_DRV_LOG(DEBUG, "tx_unicast: %lu", ns->eth.tx_unicast);
+ PMD_DRV_LOG(DEBUG, "tx_multicast: %lu", ns->eth.tx_multicast);
+ PMD_DRV_LOG(DEBUG, "tx_broadcast: %lu", ns->eth.tx_broadcast);
+ PMD_DRV_LOG(DEBUG, "tx_discards: %lu", ns->eth.tx_discards);
+ PMD_DRV_LOG(DEBUG, "tx_errors: %lu", ns->eth.tx_errors);
+
+ PMD_DRV_LOG(DEBUG, "tx_dropped_link_down: %lu",
+ ns->tx_dropped_link_down);
+ PMD_DRV_LOG(DEBUG, "crc_errors: %lu", ns->crc_errors);
+ PMD_DRV_LOG(DEBUG, "illegal_bytes: %lu",
+ ns->illegal_bytes);
+ PMD_DRV_LOG(DEBUG, "error_bytes: %lu", ns->error_bytes);
+ PMD_DRV_LOG(DEBUG, "mac_local_faults: %lu",
+ ns->mac_local_faults);
+ PMD_DRV_LOG(DEBUG, "mac_remote_faults: %lu",
+ ns->mac_remote_faults);
+ PMD_DRV_LOG(DEBUG, "rx_length_errors: %lu",
+ ns->rx_length_errors);
+ PMD_DRV_LOG(DEBUG, "link_xon_rx: %lu", ns->link_xon_rx);
+ PMD_DRV_LOG(DEBUG, "link_xoff_rx: %lu", ns->link_xoff_rx);
for (i = 0; i < 8; i++) {
- printf("priority_xon_rx[%d]: %lu\n",
+ PMD_DRV_LOG(DEBUG, "priority_xon_rx[%d]: %lu",
i, ns->priority_xon_rx[i]);
- printf("priority_xoff_rx[%d]: %lu\n",
+ PMD_DRV_LOG(DEBUG, "priority_xoff_rx[%d]: %lu",
i, ns->priority_xoff_rx[i]);
}
- printf("link_xon_tx: %lu\n", ns->link_xon_tx);
- printf("link_xoff_tx: %lu\n", ns->link_xoff_tx);
+ PMD_DRV_LOG(DEBUG, "link_xon_tx: %lu", ns->link_xon_tx);
+ PMD_DRV_LOG(DEBUG, "link_xoff_tx: %lu", ns->link_xoff_tx);
for (i = 0; i < 8; i++) {
- printf("priority_xon_tx[%d]: %lu\n",
+ PMD_DRV_LOG(DEBUG, "priority_xon_tx[%d]: %lu",
i, ns->priority_xon_tx[i]);
- printf("priority_xoff_tx[%d]: %lu\n",
+ PMD_DRV_LOG(DEBUG, "priority_xoff_tx[%d]: %lu",
i, ns->priority_xoff_tx[i]);
- printf("priority_xon_2_xoff[%d]: %lu\n",
+ PMD_DRV_LOG(DEBUG, "priority_xon_2_xoff[%d]: %lu",
i, ns->priority_xon_2_xoff[i]);
}
- printf("rx_size_64: %lu\n", ns->rx_size_64);
- printf("rx_size_127: %lu\n", ns->rx_size_127);
- printf("rx_size_255: %lu\n", ns->rx_size_255);
- printf("rx_size_511: %lu\n", ns->rx_size_511);
- printf("rx_size_1023: %lu\n", ns->rx_size_1023);
- printf("rx_size_1522: %lu\n", ns->rx_size_1522);
- printf("rx_size_big: %lu\n", ns->rx_size_big);
- printf("rx_undersize: %lu\n", ns->rx_undersize);
- printf("rx_fragments: %lu\n", ns->rx_fragments);
- printf("rx_oversize: %lu\n", ns->rx_oversize);
- printf("rx_jabber: %lu\n", ns->rx_jabber);
- printf("tx_size_64: %lu\n", ns->tx_size_64);
- printf("tx_size_127: %lu\n", ns->tx_size_127);
- printf("tx_size_255: %lu\n", ns->tx_size_255);
- printf("tx_size_511: %lu\n", ns->tx_size_511);
- printf("tx_size_1023: %lu\n", ns->tx_size_1023);
- printf("tx_size_1522: %lu\n", ns->tx_size_1522);
- printf("tx_size_big: %lu\n", ns->tx_size_big);
- printf("mac_short_packet_dropped: %lu\n",
+ PMD_DRV_LOG(DEBUG, "rx_size_64: %lu", ns->rx_size_64);
+ PMD_DRV_LOG(DEBUG, "rx_size_127: %lu", ns->rx_size_127);
+ PMD_DRV_LOG(DEBUG, "rx_size_255: %lu", ns->rx_size_255);
+ PMD_DRV_LOG(DEBUG, "rx_size_511: %lu", ns->rx_size_511);
+ PMD_DRV_LOG(DEBUG, "rx_size_1023: %lu", ns->rx_size_1023);
+ PMD_DRV_LOG(DEBUG, "rx_size_1522: %lu", ns->rx_size_1522);
+ PMD_DRV_LOG(DEBUG, "rx_size_big: %lu", ns->rx_size_big);
+ PMD_DRV_LOG(DEBUG, "rx_undersize: %lu", ns->rx_undersize);
+ PMD_DRV_LOG(DEBUG, "rx_fragments: %lu", ns->rx_fragments);
+ PMD_DRV_LOG(DEBUG, "rx_oversize: %lu", ns->rx_oversize);
+ PMD_DRV_LOG(DEBUG, "rx_jabber: %lu", ns->rx_jabber);
+ PMD_DRV_LOG(DEBUG, "tx_size_64: %lu", ns->tx_size_64);
+ PMD_DRV_LOG(DEBUG, "tx_size_127: %lu", ns->tx_size_127);
+ PMD_DRV_LOG(DEBUG, "tx_size_255: %lu", ns->tx_size_255);
+ PMD_DRV_LOG(DEBUG, "tx_size_511: %lu", ns->tx_size_511);
+ PMD_DRV_LOG(DEBUG, "tx_size_1023: %lu", ns->tx_size_1023);
+ PMD_DRV_LOG(DEBUG, "tx_size_1522: %lu", ns->tx_size_1522);
+ PMD_DRV_LOG(DEBUG, "tx_size_big: %lu", ns->tx_size_big);
+ PMD_DRV_LOG(DEBUG, "mac_short_packet_dropped: %lu",
ns->mac_short_packet_dropped);
- printf("checksum_error: %lu\n", ns->checksum_error);
- printf("***************** PF stats end ********************\n");
-#endif /* RTE_LIBRTE_I40E_DEBUG_DRIVER */
+ PMD_DRV_LOG(DEBUG, "checksum_error: %lu",
+ ns->checksum_error);
+ PMD_DRV_LOG(DEBUG, "***************** PF stats end ********************");
}
/* Reset the statistics */
diff --git a/lib/librte_pmd_i40e/i40e_ethdev_vf.c b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
index d8552ad..ed62668 100644
--- a/lib/librte_pmd_i40e/i40e_ethdev_vf.c
+++ b/lib/librte_pmd_i40e/i40e_ethdev_vf.c
@@ -1132,7 +1132,7 @@ static int
rte_i40evf_pmd_init(const char *name __rte_unused,
const char *params __rte_unused)
{
- DEBUGFUNC("rte_i40evf_pmd_init");
+ PMD_INIT_FUNC_TRACE();
rte_eth_driver_register(&rte_i40evf_pmd);
@@ -1384,7 +1384,7 @@ i40evf_dev_start(struct rte_eth_dev *dev)
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ether_addr mac_addr;
- PMD_DRV_LOG(DEBUG, "i40evf_dev_start");
+ PMD_INIT_FUNC_TRACE();
vf->max_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
if (dev->data->dev_conf.rxmode.jumbo_frame == 1) {
diff --git a/lib/librte_pmd_i40e/i40e_pf.c b/lib/librte_pmd_i40e/i40e_pf.c
index e8b154d..4e1e043 100644
--- a/lib/librte_pmd_i40e/i40e_pf.c
+++ b/lib/librte_pmd_i40e/i40e_pf.c
@@ -253,10 +253,8 @@ i40e_pf_host_send_msg_to_vf(struct i40e_pf_vf *vf,
ret = i40e_aq_send_msg_to_vf(hw, abs_vf_id, opcode, retval,
msg, msglen, NULL);
if (ret) {
- PMD_DRV_LOG(ERR, "Fail to send message to VF, err %u\n",
- hw->aq.asq_last_status);
- printf("Fail to send message to VF, err %u\n",
- hw->aq.asq_last_status);
+ PMD_INIT_LOG(ERR, "Fail to send message to VF, err %u",
+ hw->aq.asq_last_status);
}
return ret;
diff --git a/lib/librte_pmd_i40e/i40e_rxtx.c b/lib/librte_pmd_i40e/i40e_rxtx.c
index e41e8d0..70e2bd4 100644
--- a/lib/librte_pmd_i40e/i40e_rxtx.c
+++ b/lib/librte_pmd_i40e/i40e_rxtx.c
@@ -1787,50 +1787,50 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
tx_free_thresh = (uint16_t)((tx_conf->tx_free_thresh) ?
tx_conf->tx_free_thresh : DEFAULT_TX_FREE_THRESH);
if (tx_rs_thresh >= (nb_desc - 2)) {
- RTE_LOG(ERR, PMD, "tx_rs_thresh must be less than the "
- "number of TX descriptors minus 2. "
- "(tx_rs_thresh=%u port=%d queue=%d)\n",
- (unsigned int)tx_rs_thresh,
- (int)dev->data->port_id,
- (int)queue_idx);
+ PMD_INIT_LOG(ERR, "tx_rs_thresh must be less than the "
+ "number of TX descriptors minus 2. "
+ "(tx_rs_thresh=%u port=%d queue=%d)",
+ (unsigned int)tx_rs_thresh,
+ (int)dev->data->port_id,
+ (int)queue_idx);
return I40E_ERR_PARAM;
}
if (tx_free_thresh >= (nb_desc - 3)) {
- RTE_LOG(ERR, PMD, "tx_rs_thresh must be less than the "
- "tx_free_thresh must be less than the "
- "number of TX descriptors minus 3. "
- "(tx_free_thresh=%u port=%d queue=%d)\n",
- (unsigned int)tx_free_thresh,
- (int)dev->data->port_id,
- (int)queue_idx);
+ PMD_INIT_LOG(ERR, "tx_rs_thresh must be less than the "
+ "tx_free_thresh must be less than the "
+ "number of TX descriptors minus 3. "
+ "(tx_free_thresh=%u port=%d queue=%d)",
+ (unsigned int)tx_free_thresh,
+ (int)dev->data->port_id,
+ (int)queue_idx);
return I40E_ERR_PARAM;
}
if (tx_rs_thresh > tx_free_thresh) {
- RTE_LOG(ERR, PMD, "tx_rs_thresh must be less than or "
- "equal to tx_free_thresh. (tx_free_thresh=%u"
- " tx_rs_thresh=%u port=%d queue=%d)\n",
- (unsigned int)tx_free_thresh,
- (unsigned int)tx_rs_thresh,
- (int)dev->data->port_id,
- (int)queue_idx);
+ PMD_INIT_LOG(ERR, "tx_rs_thresh must be less than or "
+ "equal to tx_free_thresh. (tx_free_thresh=%u"
+ " tx_rs_thresh=%u port=%d queue=%d)",
+ (unsigned int)tx_free_thresh,
+ (unsigned int)tx_rs_thresh,
+ (int)dev->data->port_id,
+ (int)queue_idx);
return I40E_ERR_PARAM;
}
if ((nb_desc % tx_rs_thresh) != 0) {
- RTE_LOG(ERR, PMD, "tx_rs_thresh must be a divisor of the "
- "number of TX descriptors. (tx_rs_thresh=%u"
- " port=%d queue=%d)\n",
- (unsigned int)tx_rs_thresh,
- (int)dev->data->port_id,
- (int)queue_idx);
+ PMD_INIT_LOG(ERR, "tx_rs_thresh must be a divisor of the "
+ "number of TX descriptors. (tx_rs_thresh=%u"
+ " port=%d queue=%d)",
+ (unsigned int)tx_rs_thresh,
+ (int)dev->data->port_id,
+ (int)queue_idx);
return I40E_ERR_PARAM;
}
if ((tx_rs_thresh > 1) && (tx_conf->tx_thresh.wthresh != 0)) {
- RTE_LOG(ERR, PMD, "TX WTHRESH must be set to 0 if "
- "tx_rs_thresh is greater than 1. "
- "(tx_rs_thresh=%u port=%d queue=%d)\n",
- (unsigned int)tx_rs_thresh,
- (int)dev->data->port_id,
- (int)queue_idx);
+ PMD_INIT_LOG(ERR, "TX WTHRESH must be set to 0 if "
+ "tx_rs_thresh is greater than 1. "
+ "(tx_rs_thresh=%u port=%d queue=%d)",
+ (unsigned int)tx_rs_thresh,
+ (int)dev->data->port_id,
+ (int)queue_idx);
return I40E_ERR_PARAM;
}
--
1.7.10.4
next prev parent reply other threads:[~2014-09-17 13:41 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-09-17 13:46 [dpdk-dev] [PATCH v3 00/20] cleanup logs in main PMDs David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 01/20] ixgbe: use the right debug macro David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 02/20] ixgbe/base: add a raw macro for use by shared code David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 03/20] ixgbe: indent logs sections David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 04/20] ixgbe: clean log messages David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 05/20] ixgbe: always log init messages David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 06/20] ixgbe: add a message when forcing scatter mode David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 07/20] ixgbe: add log messages when rx bulk mode is not usable David Marchand
2014-09-17 13:46 ` David Marchand [this message]
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 09/20] i40e/base: add a raw macro for use by shared code David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 10/20] i40e: indent logs sections David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 11/20] i40e: clean log messages David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 12/20] i40e: always log init messages David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 13/20] i40e: add log messages when rx bulk mode is not usable David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 14/20] e1000: use the right debug macro David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 15/20] e1000/base: add a raw macro for use by shared code David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 16/20] e1000: indent logs sections David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 17/20] e1000: clean log messages David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 18/20] e1000: always log init messages David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 19/20] e1000: add a message when forcing scatter mode David Marchand
2014-09-17 13:46 ` [dpdk-dev] [PATCH v3 20/20] eal: set log level from command line David Marchand
2014-09-17 14:45 ` Neil Horman
2014-09-18 7:46 ` David Marchand
2014-09-18 10:27 ` Neil Horman
2014-09-19 7:52 ` [dpdk-dev] [PATCH v3 00/20] cleanup logs in main PMDs Thomas Monjalon
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=1410961612-8571-9-git-send-email-david.marchand@6wind.com \
--to=david.marchand@6wind.com \
--cc=dev@dpdk.org \
/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).