mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
hwpmc: Add ATF regression tests for hwpmc EXTERROR diagnostics
Root-only ATF program hitting negative allocate/attach/read-write paths
and asserting the exterr(3) text. AMD/IBS cases skip without the PMC
class; program skips without hwpmc.
Additional changes by mhorne@:
- Move and rename to the established test directory tests/sys/pmc
- Remove broken test amd_missing_pmu_flag; fixed by recent change
6c4d9b9af1
- Add ATF_REQUIRE_FEATURE("exterr_strings") to skip the tests on kernels
compiled without the strings
- Remove arch-conditional compilation; tests are properly gated by PMC
class check
- Fix copyright formatting
Reviewed by: Ali Mashtizadeh <[email protected]>
Signed-off-by: Andre Silva <[email protected]>
Co-authored-by: mhorne
Sponsored by: AMD
Pull Request: https://github.com/freebsd/freebsd-src/pull/2180
This commit is contained in:
1 parent
f19f44634a
commit
e555692d1b
2 files changed
+454
No files matched your search
@@ -4,11 +4,16 @@ ATF_TESTS_C+= pmc_api_test
|
||||
ATF_TESTS_C+= pmc_credexec_test
|
||||
ATF_TESTS_C+= pmc_detach_test
|
||||
ATF_TESTS_C+= pmc_exec_test
|
||||
ATF_TESTS_C+= pmc_exterr_test
|
||||
ATF_TESTS_C+= pmc_lifecycle_test
|
||||
ATF_TESTS_C+= pmc_log_test
|
||||
ATF_TESTS_C+= pmc_wrap_test
|
||||
|
||||
TEST_METADATA.pmc_exterr_test+= required_user="root"
|
||||
|
||||
LIBADD+= pmc
|
||||
LIBADD.pmc_detach_test+= pthread
|
||||
|
||||
CFLAGS.pmc_exterr_test.c+= -I${SRCTOP}/tests
|
||||
|
||||
.include <bsd.test.mk>
|
||||
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/exterrvar.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/pmc.h>
|
||||
|
||||
#include <dev/hwpmc/hwpmc_amd.h>
|
||||
#include <dev/hwpmc/hwpmc_ibs.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
#include <errno.h>
|
||||
#include <exterr.h>
|
||||
#include <pmc.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "freebsd_test_suite/macros.h"
|
||||
|
||||
static int
|
||||
hwpmc_syscall_num(void)
|
||||
{
|
||||
struct module_stat ms;
|
||||
int modid;
|
||||
|
||||
modid = modfind(PMC_MODULE_NAME);
|
||||
if (modid < 0)
|
||||
return (-1);
|
||||
|
||||
ms.version = sizeof(ms);
|
||||
if (modstat(modid, &ms) < 0)
|
||||
return (-1);
|
||||
|
||||
return (ms.data.intval);
|
||||
}
|
||||
|
||||
static int
|
||||
hwpmc_call(int op, void *arg)
|
||||
{
|
||||
int sc;
|
||||
|
||||
sc = hwpmc_syscall_num();
|
||||
if (sc < 0)
|
||||
return (-1);
|
||||
|
||||
return (syscall(sc, op, arg));
|
||||
}
|
||||
|
||||
static void
|
||||
clear_exterr(void)
|
||||
{
|
||||
char exterr[UEXTERROR_MAXLEN];
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, exterrctl(EXTERRCTL_UD, 0, NULL) == -1);
|
||||
ATF_REQUIRE_EQ(0, uexterr_gettext(exterr, sizeof(exterr)));
|
||||
ATF_REQUIRE_STREQ("", exterr);
|
||||
}
|
||||
|
||||
static void
|
||||
require_exterr(const char *needle)
|
||||
{
|
||||
char exterr[UEXTERROR_MAXLEN];
|
||||
|
||||
ATF_REQUIRE_EQ(0, uexterr_gettext(exterr, sizeof(exterr)));
|
||||
ATF_REQUIRE_MSG(strstr(exterr, needle) != NULL,
|
||||
"extended error \"%s\" does not contain \"%s\"", exterr, needle);
|
||||
}
|
||||
|
||||
static void
|
||||
require_hwpmc(void)
|
||||
{
|
||||
|
||||
if (pmc_init() == 0)
|
||||
return;
|
||||
|
||||
atf_tc_skip("hwpmc is unavailable: %s", strerror(errno));
|
||||
}
|
||||
|
||||
static void
|
||||
require_class(enum pmc_class class, const char *name)
|
||||
{
|
||||
const struct pmc_cpuinfo *pci;
|
||||
uint32_t i;
|
||||
|
||||
ATF_REQUIRE_EQ(0, pmc_cpuinfo(&pci));
|
||||
for (i = 0; i < pci->pm_nclass; i++) {
|
||||
if (pci->pm_classes[i].pm_class == class)
|
||||
return;
|
||||
}
|
||||
atf_tc_skip("%s PMCs are unavailable on this system", name);
|
||||
}
|
||||
|
||||
static void
|
||||
allocate_soft_pmc(enum pmc_mode mode, int cpu, pmc_id_t *pmcid)
|
||||
{
|
||||
|
||||
ATF_REQUIRE_EQ(0, pmc_allocate("SOFT-CLOCK.HARD", mode, 0, cpu, pmcid,
|
||||
1));
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(pmcallocate_invalid_mode);
|
||||
ATF_TC_BODY(pmcallocate_invalid_mode, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_class = PMC_CLASS_SOFT;
|
||||
pa.pm_mode = (enum pmc_mode)0xff;
|
||||
pa.pm_cpu = PMC_CPU_ANY;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
require_exterr("Invalid PMC mode");
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(pmcallocate_invalid_cpu);
|
||||
ATF_TC_BODY(pmcallocate_invalid_cpu, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_class = PMC_CLASS_SOFT;
|
||||
pa.pm_mode = PMC_MODE_TC;
|
||||
pa.pm_cpu = (uint32_t)pmc_ncpu();
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
require_exterr("Invalid PMC CPU");
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(pmcallocate_invalid_flags);
|
||||
ATF_TC_BODY(pmcallocate_invalid_flags, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_class = PMC_CLASS_SOFT;
|
||||
pa.pm_mode = PMC_MODE_TC;
|
||||
pa.pm_cpu = PMC_CPU_ANY;
|
||||
pa.pm_flags = 1U << 31;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
require_exterr("Invalid PMC flags");
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(pmcattach_system_mode);
|
||||
ATF_TC_BODY(pmcattach_system_mode, tc)
|
||||
{
|
||||
struct pmc_op_pmcattach pa;
|
||||
pmc_id_t pmcid;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
clear_exterr();
|
||||
allocate_soft_pmc(PMC_MODE_SC, 0, &pmcid);
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_pmc = pmcid;
|
||||
pa.pm_pid = getpid();
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCATTACH, &pa) == -1);
|
||||
require_exterr("Cannot attach a system-mode PMC");
|
||||
|
||||
ATF_REQUIRE_EQ(0, pmc_release(pmcid));
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(pmcattach_running_pmc);
|
||||
ATF_TC_BODY(pmcattach_running_pmc, tc)
|
||||
{
|
||||
struct pmc_op_pmcattach pa;
|
||||
pmc_id_t pmcid;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
clear_exterr();
|
||||
allocate_soft_pmc(PMC_MODE_TC, PMC_CPU_ANY, &pmcid);
|
||||
ATF_REQUIRE_EQ(0, pmc_start(pmcid));
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_pmc = pmcid;
|
||||
pa.pm_pid = getpid();
|
||||
|
||||
ATF_REQUIRE_ERRNO(EBUSY, hwpmc_call(PMC_OP_PMCATTACH, &pa) == -1);
|
||||
require_exterr("PMC must be stopped before attach");
|
||||
|
||||
ATF_REQUIRE_EQ(0, pmc_stop(pmcid));
|
||||
ATF_REQUIRE_EQ(0, pmc_release(pmcid));
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(pmcrw_no_flags);
|
||||
ATF_TC_BODY(pmcrw_no_flags, tc)
|
||||
{
|
||||
struct pmc_op_pmcrw prw;
|
||||
pmc_id_t pmcid;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
clear_exterr();
|
||||
allocate_soft_pmc(PMC_MODE_TC, PMC_CPU_ANY, &pmcid);
|
||||
|
||||
memset(&prw, 0, sizeof(prw));
|
||||
prw.pm_pmcid = pmcid;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCRW, &prw) == -1);
|
||||
require_exterr("PMCRW requires PMC_F_OLDVALUE");
|
||||
|
||||
ATF_REQUIRE_EQ(0, pmc_release(pmcid));
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(pmcrw_write_running);
|
||||
ATF_TC_BODY(pmcrw_write_running, tc)
|
||||
{
|
||||
struct pmc_op_pmcrw prw;
|
||||
pmc_id_t pmcid;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
clear_exterr();
|
||||
allocate_soft_pmc(PMC_MODE_TC, PMC_CPU_ANY, &pmcid);
|
||||
ATF_REQUIRE_EQ(0, pmc_start(pmcid));
|
||||
|
||||
memset(&prw, 0, sizeof(prw));
|
||||
prw.pm_flags = PMC_F_NEWVALUE;
|
||||
prw.pm_pmcid = pmcid;
|
||||
prw.pm_value = 1;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EBUSY, hwpmc_call(PMC_OP_PMCRW, &prw) == -1);
|
||||
require_exterr("Cannot write a PMC while it is running");
|
||||
|
||||
ATF_REQUIRE_EQ(0, pmc_stop(pmcid));
|
||||
ATF_REQUIRE_EQ(0, pmc_release(pmcid));
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(amd_invalid_subclass);
|
||||
ATF_TC_BODY(amd_invalid_subclass, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
require_class(PMC_CLASS_K8, "AMD");
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_class = PMC_CLASS_K8;
|
||||
pa.pm_mode = PMC_MODE_TC;
|
||||
pa.pm_cpu = PMC_CPU_ANY;
|
||||
pa.pm_flags = PMC_F_EV_PMU;
|
||||
pa.pm_md.pm_amd.pm_amd_sub_class = UINT32_MAX;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
require_exterr("No PMC row accepted");
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(amd_invalid_config_bits);
|
||||
ATF_TC_BODY(amd_invalid_config_bits, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
char exterr[UEXTERROR_MAXLEN];
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
require_class(PMC_CLASS_K8, "AMD");
|
||||
if (!pmc_pmu_enabled())
|
||||
atf_tc_skip("AMD PMU raw allocation path is unavailable");
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_class = PMC_CLASS_K8;
|
||||
pa.pm_mode = PMC_MODE_TC;
|
||||
pa.pm_cpu = PMC_CPU_ANY;
|
||||
pa.pm_flags = PMC_F_EV_PMU;
|
||||
pa.pm_md.pm_amd.pm_amd_sub_class = PMC_AMD_SUB_CLASS_CORE;
|
||||
pa.pm_md.pm_amd.pm_amd_config = ~0ULL;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
ATF_REQUIRE_EQ(0, uexterr_gettext(exterr, sizeof(exterr)));
|
||||
if (strstr(exterr, "No PMC row accepted") != NULL)
|
||||
atf_tc_skip("AMD core reserved-bit diagnostic was not returned");
|
||||
ATF_REQUIRE_MSG(strstr(exterr,
|
||||
"AMD PMU config has unsupported bits") != NULL,
|
||||
"extended error \"%s\" does not report core reserved-bit failure",
|
||||
exterr);
|
||||
}
|
||||
|
||||
/*
|
||||
* DF subclass with reserved config bits. On a system with Data Fabric
|
||||
* PMC support, the DF row matches class+subclass and the config-mask
|
||||
* check fires with the "AMD PMU config has unsupported bits" diagnostic.
|
||||
* On a system without DF support every row mismatches subclass and we
|
||||
* surface "No PMC row accepted"; the test skips in that case rather
|
||||
* than fail.
|
||||
*/
|
||||
ATF_TC_WITHOUT_HEAD(amd_invalid_df_config_bits);
|
||||
ATF_TC_BODY(amd_invalid_df_config_bits, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
char exterr[UEXTERROR_MAXLEN];
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
require_class(PMC_CLASS_K8, "AMD");
|
||||
if (!pmc_pmu_enabled())
|
||||
atf_tc_skip("AMD PMU raw allocation path is unavailable");
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_class = PMC_CLASS_K8;
|
||||
pa.pm_mode = PMC_MODE_SC;
|
||||
pa.pm_cpu = 0;
|
||||
pa.pm_flags = PMC_F_EV_PMU;
|
||||
pa.pm_md.pm_amd.pm_amd_sub_class = PMC_AMD_SUB_CLASS_DATA_FABRIC;
|
||||
pa.pm_md.pm_amd.pm_amd_config = ~0ULL;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
ATF_REQUIRE_EQ(0, uexterr_gettext(exterr, sizeof(exterr)));
|
||||
if (strstr(exterr, "No PMC row accepted") != NULL)
|
||||
atf_tc_skip("Data Fabric PMCs are unavailable on this system");
|
||||
ATF_REQUIRE_MSG(strstr(exterr,
|
||||
"AMD PMU config has unsupported bits") != NULL,
|
||||
"extended error \"%s\" does not report DF reserved-bit failure",
|
||||
exterr);
|
||||
fprintf(stderr, "DF reserved-bit allocation: errno=EINVAL exterr=%s\n",
|
||||
exterr);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(ibs_missing_system_capability);
|
||||
ATF_TC_BODY(ibs_missing_system_capability, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
require_class(PMC_CLASS_IBS, "IBS");
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_class = PMC_CLASS_IBS;
|
||||
pa.pm_mode = PMC_MODE_SS;
|
||||
pa.pm_cpu = 0;
|
||||
pa.pm_md.pm_ibs.ibs_type = IBS_PMC_OP;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
require_exterr("IBS requires SYSTEM capability");
|
||||
}
|
||||
|
||||
/*
|
||||
* An out-of-range ibs_type is a row discriminator mismatch on every IBS
|
||||
* row (bare EINVAL), so the generic loop-exhaustion message is surfaced.
|
||||
*/
|
||||
ATF_TC_WITHOUT_HEAD(ibs_invalid_type);
|
||||
ATF_TC_BODY(ibs_invalid_type, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
require_class(PMC_CLASS_IBS, "IBS");
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_caps = PMC_CAP_SYSTEM;
|
||||
pa.pm_class = PMC_CLASS_IBS;
|
||||
pa.pm_mode = PMC_MODE_SS;
|
||||
pa.pm_cpu = 0;
|
||||
pa.pm_md.pm_ibs.ibs_type = UINT32_MAX;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
require_exterr("No PMC row accepted");
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(ibs_invalid_config_bits);
|
||||
ATF_TC_BODY(ibs_invalid_config_bits, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
require_class(PMC_CLASS_IBS, "IBS");
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_caps = PMC_CAP_SYSTEM;
|
||||
pa.pm_class = PMC_CLASS_IBS;
|
||||
pa.pm_mode = PMC_MODE_SS;
|
||||
pa.pm_cpu = 0;
|
||||
pa.pm_md.pm_ibs.ibs_type = IBS_PMC_OP;
|
||||
pa.pm_md.pm_ibs.ibs_ctl = 1ULL << 58;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
require_exterr("IBS op ctl config");
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(ibs_nonsampling_mode);
|
||||
ATF_TC_BODY(ibs_nonsampling_mode, tc)
|
||||
{
|
||||
struct pmc_op_pmcallocate pa;
|
||||
|
||||
ATF_REQUIRE_FEATURE("exterr_strings");
|
||||
require_hwpmc();
|
||||
require_class(PMC_CLASS_IBS, "IBS");
|
||||
clear_exterr();
|
||||
|
||||
memset(&pa, 0, sizeof(pa));
|
||||
pa.pm_caps = PMC_CAP_SYSTEM;
|
||||
pa.pm_class = PMC_CLASS_IBS;
|
||||
pa.pm_mode = PMC_MODE_SC;
|
||||
pa.pm_cpu = 0;
|
||||
pa.pm_md.pm_ibs.ibs_type = IBS_PMC_OP;
|
||||
|
||||
ATF_REQUIRE_ERRNO(EINVAL, hwpmc_call(PMC_OP_PMCALLOCATE, &pa) == -1);
|
||||
require_exterr("IBS only supports sampling mode");
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, pmcallocate_invalid_mode);
|
||||
ATF_TP_ADD_TC(tp, pmcallocate_invalid_cpu);
|
||||
ATF_TP_ADD_TC(tp, pmcallocate_invalid_flags);
|
||||
ATF_TP_ADD_TC(tp, pmcattach_system_mode);
|
||||
ATF_TP_ADD_TC(tp, pmcattach_running_pmc);
|
||||
ATF_TP_ADD_TC(tp, pmcrw_no_flags);
|
||||
ATF_TP_ADD_TC(tp, pmcrw_write_running);
|
||||
ATF_TP_ADD_TC(tp, amd_invalid_subclass);
|
||||
ATF_TP_ADD_TC(tp, amd_invalid_config_bits);
|
||||
ATF_TP_ADD_TC(tp, amd_invalid_df_config_bits);
|
||||
ATF_TP_ADD_TC(tp, ibs_missing_system_capability);
|
||||
ATF_TP_ADD_TC(tp, ibs_invalid_type);
|
||||
ATF_TP_ADD_TC(tp, ibs_invalid_config_bits);
|
||||
ATF_TP_ADD_TC(tp, ibs_nonsampling_mode);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
Reference in new issue
Block a user