* [GIT PULL] turbostat fixes @ 2017-06-25 3:12 Len Brown 2017-06-25 3:12 ` [PATCH 1/5] tools/power turbostat: hide SKL counters, when not requested Len Brown 2017-06-26 23:45 ` [GIT PULL] turbostat fixes Rafael J. Wysocki 0 siblings, 2 replies; 7+ messages in thread From: Len Brown @ 2017-06-25 3:12 UTC (permalink / raw) To: linux-pm Hi Rafael, Please pull these turbostat patches. thanks! Len Brown, Intel Open Source Technology Center The following changes since commit 3c2993b8c6143d8a5793746a54eba8f86f95240f: Linux 4.12-rc4 (2017-06-04 16:47:43 -0700) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git turbostat for you to fetch changes up to f7d44a8f3fd7f13770470a306a233acbaad5e96d: tools/power turbostat: update version number (2017-06-24 20:03:42 -0700) ---------------------------------------------------------------- Len Brown (5): tools/power turbostat: hide SKL counters, when not requested tools/power turbostat: if --debug, print sampling overhead tools/power turbostat: stop migrating, unless '-m' tools/power turbostat: decode MSR_IA32_MISC_ENABLE only on Intel tools/power turbostat: update version number tools/power/x86/turbostat/turbostat.c | 94 ++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 17 deletions(-) ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/5] tools/power turbostat: hide SKL counters, when not requested 2017-06-25 3:12 [GIT PULL] turbostat fixes Len Brown @ 2017-06-25 3:12 ` Len Brown 2017-06-25 3:12 ` [PATCH 2/5] tools/power turbostat: if --debug, print sampling overhead Len Brown ` (3 more replies) 2017-06-26 23:45 ` [GIT PULL] turbostat fixes Rafael J. Wysocki 1 sibling, 4 replies; 7+ messages in thread From: Len Brown @ 2017-06-25 3:12 UTC (permalink / raw) To: linux-pm; +Cc: Len Brown From: Len Brown <len.brown@intel.com> Skylake has some new counters, and they were erroneously exempt from --show and --hide eg. turbostat --quiet --show CPU CPU Totl%C0 Any%C0 GFX%C0 CPUGFX% - 116.73 90.56 85.69 79.00 0 117.78 91.38 86.47 79.71 2 1 3 is now CPU - 0 2 1 3 Signed-off-by: Len Brown <len.brown@intel.com> --- tools/power/x86/turbostat/turbostat.c | 58 +++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index b112947..2b25727 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -57,7 +57,6 @@ unsigned int list_header_only; unsigned int dump_only; unsigned int do_snb_cstates; unsigned int do_knl_cstates; -unsigned int do_skl_residency; unsigned int do_slm_cstates; unsigned int use_c1_residency_msr; unsigned int has_aperf; @@ -384,8 +383,14 @@ struct msr_counter bic[] = { { 0x0, "CPU" }, { 0x0, "Mod%c6" }, { 0x0, "sysfs" }, + { 0x0, "Totl%C0" }, + { 0x0, "Any%C0" }, + { 0x0, "GFX%C0" }, + { 0x0, "CPUGFX%" }, }; + + #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) #define BIC_Package (1ULL << 0) #define BIC_Avg_MHz (1ULL << 1) @@ -426,6 +431,10 @@ struct msr_counter bic[] = { #define BIC_CPU (1ULL << 36) #define BIC_Mod_c6 (1ULL << 37) #define BIC_sysfs (1ULL << 38) +#define BIC_Totl_c0 (1ULL << 39) +#define BIC_Any_c0 (1ULL << 40) +#define BIC_GFX_c0 (1ULL << 41) +#define BIC_CPUGFX (1ULL << 42) unsigned long long bic_enabled = 0xFFFFFFFFFFFFFFFFULL; unsigned long long bic_present = BIC_sysfs; @@ -599,12 +608,14 @@ void print_header(char *delim) if (DO_BIC(BIC_GFXMHz)) outp += sprintf(outp, "%sGFXMHz", (printed++ ? delim : "")); - if (do_skl_residency) { + if (DO_BIC(BIC_Totl_c0)) outp += sprintf(outp, "%sTotl%%C0", (printed++ ? delim : "")); + if (DO_BIC(BIC_Any_c0)) outp += sprintf(outp, "%sAny%%C0", (printed++ ? delim : "")); + if (DO_BIC(BIC_GFX_c0)) outp += sprintf(outp, "%sGFX%%C0", (printed++ ? delim : "")); + if (DO_BIC(BIC_CPUGFX)) outp += sprintf(outp, "%sCPUGFX%%", (printed++ ? delim : "")); - } if (DO_BIC(BIC_Pkgpc2)) outp += sprintf(outp, "%sPkg%%pc2", (printed++ ? delim : "")); @@ -912,12 +923,14 @@ int format_counters(struct thread_data *t, struct core_data *c, outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->gfx_mhz); /* Totl%C0, Any%C0 GFX%C0 CPUGFX% */ - if (do_skl_residency) { + if (DO_BIC(BIC_Totl_c0)) outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_wtd_core_c0/tsc); + if (DO_BIC(BIC_Any_c0)) outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_core_c0/tsc); + if (DO_BIC(BIC_GFX_c0)) outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_any_gfxe_c0/tsc); + if (DO_BIC(BIC_CPUGFX)) outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pkg_both_core_gfxe_c0/tsc); - } if (DO_BIC(BIC_Pkgpc2)) outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100.0 * p->pc2/tsc); @@ -1038,12 +1051,16 @@ delta_package(struct pkg_data *new, struct pkg_data *old) int i; struct msr_counter *mp; - if (do_skl_residency) { + + if (DO_BIC(BIC_Totl_c0)) old->pkg_wtd_core_c0 = new->pkg_wtd_core_c0 - old->pkg_wtd_core_c0; + if (DO_BIC(BIC_Any_c0)) old->pkg_any_core_c0 = new->pkg_any_core_c0 - old->pkg_any_core_c0; + if (DO_BIC(BIC_GFX_c0)) old->pkg_any_gfxe_c0 = new->pkg_any_gfxe_c0 - old->pkg_any_gfxe_c0; + if (DO_BIC(BIC_CPUGFX)) old->pkg_both_core_gfxe_c0 = new->pkg_both_core_gfxe_c0 - old->pkg_both_core_gfxe_c0; - } + old->pc2 = new->pc2 - old->pc2; if (DO_BIC(BIC_Pkgpc3)) old->pc3 = new->pc3 - old->pc3; @@ -1292,12 +1309,14 @@ int sum_counters(struct thread_data *t, struct core_data *c, if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) return 0; - if (do_skl_residency) { + if (DO_BIC(BIC_Totl_c0)) average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0; + if (DO_BIC(BIC_Any_c0)) average.packages.pkg_any_core_c0 += p->pkg_any_core_c0; + if (DO_BIC(BIC_GFX_c0)) average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0; + if (DO_BIC(BIC_CPUGFX)) average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0; - } average.packages.pc2 += p->pc2; if (DO_BIC(BIC_Pkgpc3)) @@ -1357,12 +1376,14 @@ void compute_average(struct thread_data *t, struct core_data *c, average.cores.c7 /= topo.num_cores; average.cores.mc6_us /= topo.num_cores; - if (do_skl_residency) { + if (DO_BIC(BIC_Totl_c0)) average.packages.pkg_wtd_core_c0 /= topo.num_packages; + if (DO_BIC(BIC_Any_c0)) average.packages.pkg_any_core_c0 /= topo.num_packages; + if (DO_BIC(BIC_GFX_c0)) average.packages.pkg_any_gfxe_c0 /= topo.num_packages; + if (DO_BIC(BIC_CPUGFX)) average.packages.pkg_both_core_gfxe_c0 /= topo.num_packages; - } average.packages.pc2 /= topo.num_packages; if (DO_BIC(BIC_Pkgpc3)) @@ -1603,13 +1624,19 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) return 0; - if (do_skl_residency) { + if (DO_BIC(BIC_Totl_c0)) { if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0)) return -10; + } + if (DO_BIC(BIC_Any_c0)) { if (get_msr(cpu, MSR_PKG_ANY_CORE_C0_RES, &p->pkg_any_core_c0)) return -11; + } + if (DO_BIC(BIC_GFX_c0)) { if (get_msr(cpu, MSR_PKG_ANY_GFXE_C0_RES, &p->pkg_any_gfxe_c0)) return -12; + } + if (DO_BIC(BIC_CPUGFX)) { if (get_msr(cpu, MSR_PKG_BOTH_CORE_GFXE_C0_RES, &p->pkg_both_core_gfxe_c0)) return -13; } @@ -4198,7 +4225,12 @@ void process_cpuid() BIC_PRESENT(BIC_Pkgpc10); } do_irtl_hsw = has_hsw_msrs(family, model); - do_skl_residency = has_skl_msrs(family, model); + if (has_skl_msrs(family, model)) { + BIC_PRESENT(BIC_Totl_c0); + BIC_PRESENT(BIC_Any_c0); + BIC_PRESENT(BIC_GFX_c0); + BIC_PRESENT(BIC_CPUGFX); + } do_slm_cstates = is_slm(family, model); do_knl_cstates = is_knl(family, model); -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/5] tools/power turbostat: if --debug, print sampling overhead 2017-06-25 3:12 ` [PATCH 1/5] tools/power turbostat: hide SKL counters, when not requested Len Brown @ 2017-06-25 3:12 ` Len Brown 2017-06-25 3:12 ` [PATCH 3/5] tools/power turbostat: stop migrating, unless '-m' Len Brown ` (2 subsequent siblings) 3 siblings, 0 replies; 7+ messages in thread From: Len Brown @ 2017-06-25 3:12 UTC (permalink / raw) To: linux-pm; +Cc: Len Brown From: Len Brown <len.brown@intel.com> The --debug option now pre-pends each row with the number of micro-seconds [usec] to collect the finishing snapshot for that row. Signed-off-by: Len Brown <len.brown@intel.com> --- tools/power/x86/turbostat/turbostat.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 2b25727..6f7c64a 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -150,6 +150,8 @@ size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size; #define MAX_ADDED_COUNTERS 16 struct thread_data { + struct timeval tv_begin; + struct timeval tv_end; unsigned long long tsc; unsigned long long aperf; unsigned long long mperf; @@ -530,6 +532,8 @@ void print_header(char *delim) struct msr_counter *mp; int printed = 0; + if (debug) + outp += sprintf(outp, "usec %s", delim); if (DO_BIC(BIC_Package)) outp += sprintf(outp, "%sPackage", (printed++ ? delim : "")); if (DO_BIC(BIC_Core)) @@ -782,6 +786,14 @@ int format_counters(struct thread_data *t, struct core_data *c, (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset))) return 0; + if (debug) { + /* on each row, print how many usec each timestamp took to gather */ + struct timeval tv; + + timersub(&t->tv_end, &t->tv_begin, &tv); + outp += sprintf(outp, "%5ld\t", tv.tv_sec * 1000000 + tv.tv_usec); + } + interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0; tsc = t->tsc * tsc_tweak; @@ -1503,6 +1515,9 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) struct msr_counter *mp; int i; + + gettimeofday(&t->tv_begin, (struct timezone *)NULL); + if (cpu_migrate(cpu)) { fprintf(outf, "Could not migrate to CPU %d\n", cpu); return -1; @@ -1586,7 +1601,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) /* collect core counters only for 1st thread in core */ if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) - return 0; + goto done; if (DO_BIC(BIC_CPU_c3) && !do_slm_cstates && !do_knl_cstates) { if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) @@ -1622,7 +1637,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) /* collect package counters only for 1st core in package */ if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) - return 0; + goto done; if (DO_BIC(BIC_Totl_c0)) { if (get_msr(cpu, MSR_PKG_WEIGHTED_CORE_C0_RES, &p->pkg_wtd_core_c0)) @@ -1715,6 +1730,8 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) if (get_mp(cpu, mp, &p->counter[i])) return -10; } +done: + gettimeofday(&t->tv_end, (struct timezone *)NULL); return 0; } -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 3/5] tools/power turbostat: stop migrating, unless '-m' 2017-06-25 3:12 ` [PATCH 1/5] tools/power turbostat: hide SKL counters, when not requested Len Brown 2017-06-25 3:12 ` [PATCH 2/5] tools/power turbostat: if --debug, print sampling overhead Len Brown @ 2017-06-25 3:12 ` Len Brown 2017-06-25 3:13 ` [PATCH 4/5] tools/power turbostat: decode MSR_IA32_MISC_ENABLE only on Intel Len Brown 2017-06-25 3:13 ` [PATCH 5/5] tools/power turbostat: update version number Len Brown 3 siblings, 0 replies; 7+ messages in thread From: Len Brown @ 2017-06-25 3:12 UTC (permalink / raw) To: linux-pm; +Cc: Len Brown From: Len Brown <len.brown@intel.com> Turbostat has the capability to set its own affinity to each CPU so that its MSR accesses are on the local CPU. However, using the in-kernel cross-call in the msr driver tends to be less invasive, so do that -- by-default. '-m' remains to get the old behaviour. Signed-off-by: Len Brown <len.brown@intel.com> --- tools/power/x86/turbostat/turbostat.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 6f7c64a..1a3a5b4 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -92,6 +92,7 @@ unsigned int do_ring_perf_limit_reasons; unsigned int crystal_hz; unsigned long long tsc_hz; int base_cpu; +int do_migrate; double discover_bclk(unsigned int family, unsigned int model); unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ /* IA32_HWP_REQUEST, IA32_HWP_STATUS */ @@ -302,6 +303,9 @@ int for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg int cpu_migrate(int cpu) { + if (!do_migrate) + return 0; + CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); CPU_SET_S(cpu, cpu_affinity_setsize, cpu_affinity_set); if (sched_setaffinity(0, cpu_affinity_setsize, cpu_affinity_set) == -1) @@ -5000,6 +5004,7 @@ void cmdline(int argc, char **argv) {"hide", required_argument, 0, 'H'}, // meh, -h taken by --help {"Joules", no_argument, 0, 'J'}, {"list", no_argument, 0, 'l'}, + {"migrate", no_argument, 0, 'm'}, {"out", required_argument, 0, 'o'}, {"quiet", no_argument, 0, 'q'}, {"show", required_argument, 0, 's'}, @@ -5011,7 +5016,7 @@ void cmdline(int argc, char **argv) progname = argv[0]; - while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:JM:m:o:qST:v", + while ((opt = getopt_long_only(argc, argv, "+C:c:Ddhi:Jmo:qST:v", long_options, &option_index)) != -1) { switch (opt) { case 'a': @@ -5054,6 +5059,9 @@ void cmdline(int argc, char **argv) list_header_only++; quiet++; break; + case 'm': + do_migrate = 1; + break; case 'o': outf = fopen_or_die(optarg, "w"); break; -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 4/5] tools/power turbostat: decode MSR_IA32_MISC_ENABLE only on Intel 2017-06-25 3:12 ` [PATCH 1/5] tools/power turbostat: hide SKL counters, when not requested Len Brown 2017-06-25 3:12 ` [PATCH 2/5] tools/power turbostat: if --debug, print sampling overhead Len Brown 2017-06-25 3:12 ` [PATCH 3/5] tools/power turbostat: stop migrating, unless '-m' Len Brown @ 2017-06-25 3:13 ` Len Brown 2017-06-25 3:13 ` [PATCH 5/5] tools/power turbostat: update version number Len Brown 3 siblings, 0 replies; 7+ messages in thread From: Len Brown @ 2017-06-25 3:13 UTC (permalink / raw) To: linux-pm; +Cc: Len Brown From: Len Brown <len.brown@intel.com> otherwise, turbostat bails on on AMD Opteron boxes: turbostat: cpu26: msr offset 0x1a0 read failed: Input/output error Reported-by: Kamil Kolakowski <kkolakow@redhat.com> Signed-off-by: Len Brown <len.brown@intel.com> --- tools/power/x86/turbostat/turbostat.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 1a3a5b4..33992a9 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3943,6 +3943,9 @@ void decode_misc_enable_msr(void) { unsigned long long msr; + if (!genuine_intel) + return; + if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr)) fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n", base_cpu, msr, -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 5/5] tools/power turbostat: update version number 2017-06-25 3:12 ` [PATCH 1/5] tools/power turbostat: hide SKL counters, when not requested Len Brown ` (2 preceding siblings ...) 2017-06-25 3:13 ` [PATCH 4/5] tools/power turbostat: decode MSR_IA32_MISC_ENABLE only on Intel Len Brown @ 2017-06-25 3:13 ` Len Brown 3 siblings, 0 replies; 7+ messages in thread From: Len Brown @ 2017-06-25 3:13 UTC (permalink / raw) To: linux-pm; +Cc: Len Brown From: Len Brown <len.brown@intel.com> Signed-off-by: Len Brown <len.brown@intel.com> --- tools/power/x86/turbostat/turbostat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 33992a9..0dafba2 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -4634,7 +4634,7 @@ int get_and_dump_counters(void) } void print_version() { - fprintf(outf, "turbostat version 17.04.12" + fprintf(outf, "turbostat version 17.06.23" " - Len Brown <lenb@kernel.org>\n"); } -- 2.7.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [GIT PULL] turbostat fixes 2017-06-25 3:12 [GIT PULL] turbostat fixes Len Brown 2017-06-25 3:12 ` [PATCH 1/5] tools/power turbostat: hide SKL counters, when not requested Len Brown @ 2017-06-26 23:45 ` Rafael J. Wysocki 1 sibling, 0 replies; 7+ messages in thread From: Rafael J. Wysocki @ 2017-06-26 23:45 UTC (permalink / raw) To: Len Brown; +Cc: Linux PM On Sun, Jun 25, 2017 at 5:12 AM, Len Brown <lenb@kernel.org> wrote: > Hi Rafael, Hi, > Please pull these turbostat patches. > > thanks! > Len Brown, Intel Open Source Technology Center > > The following changes since commit 3c2993b8c6143d8a5793746a54eba8f86f95240f: > > Linux 4.12-rc4 (2017-06-04 16:47:43 -0700) > > are available in the git repository at: > > git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux.git turbostat > > for you to fetch changes up to f7d44a8f3fd7f13770470a306a233acbaad5e96d: > > tools/power turbostat: update version number (2017-06-24 20:03:42 -0700) > > ---------------------------------------------------------------- > Len Brown (5): > tools/power turbostat: hide SKL counters, when not requested > tools/power turbostat: if --debug, print sampling overhead > tools/power turbostat: stop migrating, unless '-m' > tools/power turbostat: decode MSR_IA32_MISC_ENABLE only on Intel > tools/power turbostat: update version number > > tools/power/x86/turbostat/turbostat.c | 94 ++++++++++++++++++++++++++++------- > 1 file changed, 77 insertions(+), 17 deletions(-) Pulled, thanks! ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2017-06-26 23:45 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-06-25 3:12 [GIT PULL] turbostat fixes Len Brown 2017-06-25 3:12 ` [PATCH 1/5] tools/power turbostat: hide SKL counters, when not requested Len Brown 2017-06-25 3:12 ` [PATCH 2/5] tools/power turbostat: if --debug, print sampling overhead Len Brown 2017-06-25 3:12 ` [PATCH 3/5] tools/power turbostat: stop migrating, unless '-m' Len Brown 2017-06-25 3:13 ` [PATCH 4/5] tools/power turbostat: decode MSR_IA32_MISC_ENABLE only on Intel Len Brown 2017-06-25 3:13 ` [PATCH 5/5] tools/power turbostat: update version number Len Brown 2017-06-26 23:45 ` [GIT PULL] turbostat fixes Rafael J. Wysocki
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).