Merge tag 'drm-misc-next-2019-12-16' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v5.6: UAPI Changes: - Add support for DMA-BUF HEAPS. Cross-subsystem Changes: - mipi dsi definition updates, pulled into drm-intel as well. - Add lockdep annotations for dma_resv vs mmap_sem and fs_reclaim. - Remove support for dma-buf kmap/kunmap. - Constify fb_ops in all fbdev drivers, including drm drivers and drm-core, and media as well. Core Changes: - Small cleanups to ttm. - Fix SCDC definition. - Assorted cleanups to core. - Add todo to remove load/unload hooks, and use generic fbdev emulation. - Assorted documentation updates. - Use blocking ww lock in ttm fault handler. - Remove drm_fb_helper_fbdev_setup/teardown. - Warning fixes with W=1 for atomic. - Use drm_debug_enabled() instead of drm_debug flag testing in various drivers. - Fallback to nontiled mode in fbdev emulation when not all tiles are present. (Later on reverted) - Various kconfig indentation fixes in core and drivers. - Fix freeing transactions in dp-mst correctly. - Sean Paul is steping down as core maintainer. :-( - Add lockdep annotations for atomic locks vs dma-resv. - Prevent use-after-free for a bad job in drm_scheduler. - Fill out all block sizes in the P01x and P210 definitions. - Avoid division by zero in drm/rect, and fix bounds. - Add drm/rect selftests. - Add aspect ratio and alternate clocks for HDMI 4k modes. - Add todo for drm_framebuffer_funcs and fb_create cleanup. - Drop DRM_AUTH for prime import/export ioctls. - Clear DP-MST payload id tables downstream when initializating. - Fix for DSC throughput definition. - Add extra FEC definitions. - Fix fake offset in drm_gem_object_funs.mmap. - Stop using encoder->bridge in core directly - Handle bridge chaining slightly better. - Add backlight support to drm/panel, and use it in many panel drivers. - Increase max number of y420 modes from 128 to 256, as preparation to add the new modes. Driver Changes: - Small fixes all over. - Fix documentation in vkms. - Fix mmap_sem vs dma_resv in nouveau. - Small cleanup in komeda. - Add page flip support in gma500 for psb/cdv. - Add ddc symlink in the connector sysfs directory for many drivers. - Add support for analogic an6345, and fix small bugs in it. - Add atomic modesetting support to ast. - Fix radeon fault handler VMA race. - Switch udl to use generic shmem helpers. - Unconditional vblank handling for mcde. - Miscellaneous fixes to mcde. - Tweak debug output from komeda using debugfs. - Add gamma and color transform support to komeda for DOU-IPS. - Add support for sony acx424AKP panel. - Various small cleanups to gma500. - Use generic fbdev emulation in udl, and replace udl_framebuffer with generic implementation. - Add support for Logic PD Type 28 panel. - Use drm_panel_* wrapper functions in exynos/tegra/msm. - Add devicetree bindings for generic DSI panels. - Don't include drm_pci.h directly in many drivers. - Add support for begin/end_cpu_access in udmabuf. - Stop using drm_get_pci_dev in gma500 and mga200. - Fixes to UDL damage handling, and use dma_buf_begin/end_cpu_access. - Add devfreq thermal support to panfrost. - Fix hotplug with daisy chained monitors by removing VCPI when disabling topology manager. - meson: Add support for OSD1 plane AFBC commit. - Stop displaying garbage when toggling ast primary plane on/off. - More cleanups and fixes to UDL. - Add D32 suport to komeda. - Remove globle copy of drm_dev in gma500. - Add support for Boe Himax8279d MIPI-DSI LCD panel. - Add support for ingenic JZ4770 panel. - Small null pointer deference fix in ingenic. - Remove support for the special tfp420 driver, as there is a generic way to do it. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/ba73535a-9334-5302-2e1f-5208bd7390bd@linux.intel.com
This commit is contained in:
@@ -24,9 +24,9 @@ Driver Initialization
|
||||
At the core of every DRM driver is a :c:type:`struct drm_driver
|
||||
<drm_driver>` structure. Drivers typically statically initialize
|
||||
a drm_driver structure, and then pass it to
|
||||
:c:func:`drm_dev_alloc()` to allocate a device instance. After the
|
||||
drm_dev_alloc() to allocate a device instance. After the
|
||||
device instance is fully initialized it can be registered (which makes
|
||||
it accessible from userspace) using :c:func:`drm_dev_register()`.
|
||||
it accessible from userspace) using drm_dev_register().
|
||||
|
||||
The :c:type:`struct drm_driver <drm_driver>` structure
|
||||
contains static information that describes the driver and features it
|
||||
|
@@ -3,7 +3,7 @@ Kernel Mode Setting (KMS)
|
||||
=========================
|
||||
|
||||
Drivers must initialize the mode setting core by calling
|
||||
:c:func:`drm_mode_config_init()` on the DRM device. The function
|
||||
drm_mode_config_init() on the DRM device. The function
|
||||
initializes the :c:type:`struct drm_device <drm_device>`
|
||||
mode_config field and never fails. Once done, mode configuration must
|
||||
be setup by initializing the following fields.
|
||||
@@ -181,8 +181,7 @@ Setting`_). The somewhat surprising part here is that properties are not
|
||||
directly instantiated on each object, but free-standing mode objects themselves,
|
||||
represented by :c:type:`struct drm_property <drm_property>`, which only specify
|
||||
the type and value range of a property. Any given property can be attached
|
||||
multiple times to different objects using :c:func:`drm_object_attach_property()
|
||||
<drm_object_attach_property>`.
|
||||
multiple times to different objects using drm_object_attach_property().
|
||||
|
||||
.. kernel-doc:: include/drm/drm_mode_object.h
|
||||
:internal:
|
||||
@@ -260,7 +259,8 @@ Taken all together there's two consequences for the atomic design:
|
||||
drm_connector_state <drm_connector_state>` for connectors. These are the only
|
||||
objects with userspace-visible and settable state. For internal state drivers
|
||||
can subclass these structures through embeddeding, or add entirely new state
|
||||
structures for their globally shared hardware functions.
|
||||
structures for their globally shared hardware functions, see :c:type:`struct
|
||||
drm_private_state<drm_private_state>`.
|
||||
|
||||
- An atomic update is assembled and validated as an entirely free-standing pile
|
||||
of structures within the :c:type:`drm_atomic_state <drm_atomic_state>`
|
||||
@@ -269,6 +269,14 @@ Taken all together there's two consequences for the atomic design:
|
||||
to the driver and modeset objects. This way rolling back an update boils down
|
||||
to releasing memory and unreferencing objects like framebuffers.
|
||||
|
||||
Locking of atomic state structures is internally using :c:type:`struct
|
||||
drm_modeset_lock <drm_modeset_lock>`. As a general rule the locking shouldn't be
|
||||
exposed to drivers, instead the right locks should be automatically acquired by
|
||||
any function that duplicates or peeks into a state, like e.g.
|
||||
drm_atomic_get_crtc_state(). Locking only protects the software data
|
||||
structure, ordering of committing state changes to hardware is sequenced using
|
||||
:c:type:`struct drm_crtc_commit <drm_crtc_commit>`.
|
||||
|
||||
Read on in this chapter, and also in :ref:`drm_atomic_helper` for more detailed
|
||||
coverage of specific topics.
|
||||
|
||||
@@ -479,6 +487,9 @@ Color Management Properties
|
||||
.. kernel-doc:: drivers/gpu/drm/drm_color_mgmt.c
|
||||
:export:
|
||||
|
||||
.. kernel-doc:: include/drm/drm_color_mgmt.h
|
||||
:internal:
|
||||
|
||||
Tile Group Property
|
||||
-------------------
|
||||
|
||||
|
@@ -149,19 +149,19 @@ struct :c:type:`struct drm_gem_object <drm_gem_object>`.
|
||||
To create a GEM object, a driver allocates memory for an instance of its
|
||||
specific GEM object type and initializes the embedded struct
|
||||
:c:type:`struct drm_gem_object <drm_gem_object>` with a call
|
||||
to :c:func:`drm_gem_object_init()`. The function takes a pointer
|
||||
to drm_gem_object_init(). The function takes a pointer
|
||||
to the DRM device, a pointer to the GEM object and the buffer object
|
||||
size in bytes.
|
||||
|
||||
GEM uses shmem to allocate anonymous pageable memory.
|
||||
:c:func:`drm_gem_object_init()` will create an shmfs file of the
|
||||
drm_gem_object_init() will create an shmfs file of the
|
||||
requested size and store it into the struct :c:type:`struct
|
||||
drm_gem_object <drm_gem_object>` filp field. The memory is
|
||||
used as either main storage for the object when the graphics hardware
|
||||
uses system memory directly or as a backing store otherwise.
|
||||
|
||||
Drivers are responsible for the actual physical pages allocation by
|
||||
calling :c:func:`shmem_read_mapping_page_gfp()` for each page.
|
||||
calling shmem_read_mapping_page_gfp() for each page.
|
||||
Note that they can decide to allocate pages when initializing the GEM
|
||||
object, or to delay allocation until the memory is needed (for instance
|
||||
when a page fault occurs as a result of a userspace memory access or
|
||||
@@ -170,20 +170,18 @@ when the driver needs to start a DMA transfer involving the memory).
|
||||
Anonymous pageable memory allocation is not always desired, for instance
|
||||
when the hardware requires physically contiguous system memory as is
|
||||
often the case in embedded devices. Drivers can create GEM objects with
|
||||
no shmfs backing (called private GEM objects) by initializing them with
|
||||
a call to :c:func:`drm_gem_private_object_init()` instead of
|
||||
:c:func:`drm_gem_object_init()`. Storage for private GEM objects
|
||||
must be managed by drivers.
|
||||
no shmfs backing (called private GEM objects) by initializing them with a call
|
||||
to drm_gem_private_object_init() instead of drm_gem_object_init(). Storage for
|
||||
private GEM objects must be managed by drivers.
|
||||
|
||||
GEM Objects Lifetime
|
||||
--------------------
|
||||
|
||||
All GEM objects are reference-counted by the GEM core. References can be
|
||||
acquired and release by :c:func:`calling drm_gem_object_get()` and
|
||||
:c:func:`drm_gem_object_put()` respectively. The caller must hold the
|
||||
:c:type:`struct drm_device <drm_device>` struct_mutex lock when calling
|
||||
:c:func:`drm_gem_object_get()`. As a convenience, GEM provides
|
||||
:c:func:`drm_gem_object_put_unlocked()` functions that can be called without
|
||||
acquired and release by calling drm_gem_object_get() and drm_gem_object_put()
|
||||
respectively. The caller must hold the :c:type:`struct drm_device <drm_device>`
|
||||
struct_mutex lock when calling drm_gem_object_get(). As a convenience, GEM
|
||||
provides drm_gem_object_put_unlocked() functions that can be called without
|
||||
holding the lock.
|
||||
|
||||
When the last reference to a GEM object is released the GEM core calls
|
||||
@@ -194,7 +192,7 @@ free the GEM object and all associated resources.
|
||||
void (\*gem_free_object) (struct drm_gem_object \*obj); Drivers are
|
||||
responsible for freeing all GEM object resources. This includes the
|
||||
resources created by the GEM core, which need to be released with
|
||||
:c:func:`drm_gem_object_release()`.
|
||||
drm_gem_object_release().
|
||||
|
||||
GEM Objects Naming
|
||||
------------------
|
||||
@@ -210,13 +208,11 @@ to the GEM object in other standard or driver-specific ioctls. Closing a
|
||||
DRM file handle frees all its GEM handles and dereferences the
|
||||
associated GEM objects.
|
||||
|
||||
To create a handle for a GEM object drivers call
|
||||
:c:func:`drm_gem_handle_create()`. The function takes a pointer
|
||||
to the DRM file and the GEM object and returns a locally unique handle.
|
||||
When the handle is no longer needed drivers delete it with a call to
|
||||
:c:func:`drm_gem_handle_delete()`. Finally the GEM object
|
||||
associated with a handle can be retrieved by a call to
|
||||
:c:func:`drm_gem_object_lookup()`.
|
||||
To create a handle for a GEM object drivers call drm_gem_handle_create(). The
|
||||
function takes a pointer to the DRM file and the GEM object and returns a
|
||||
locally unique handle. When the handle is no longer needed drivers delete it
|
||||
with a call to drm_gem_handle_delete(). Finally the GEM object associated with a
|
||||
handle can be retrieved by a call to drm_gem_object_lookup().
|
||||
|
||||
Handles don't take ownership of GEM objects, they only take a reference
|
||||
to the object that will be dropped when the handle is destroyed. To
|
||||
@@ -258,7 +254,7 @@ The mmap system call can't be used directly to map GEM objects, as they
|
||||
don't have their own file handle. Two alternative methods currently
|
||||
co-exist to map GEM objects to userspace. The first method uses a
|
||||
driver-specific ioctl to perform the mapping operation, calling
|
||||
:c:func:`do_mmap()` under the hood. This is often considered
|
||||
do_mmap() under the hood. This is often considered
|
||||
dubious, seems to be discouraged for new GEM-enabled drivers, and will
|
||||
thus not be described here.
|
||||
|
||||
@@ -267,23 +263,22 @@ The second method uses the mmap system call on the DRM file handle. void
|
||||
offset); DRM identifies the GEM object to be mapped by a fake offset
|
||||
passed through the mmap offset argument. Prior to being mapped, a GEM
|
||||
object must thus be associated with a fake offset. To do so, drivers
|
||||
must call :c:func:`drm_gem_create_mmap_offset()` on the object.
|
||||
must call drm_gem_create_mmap_offset() on the object.
|
||||
|
||||
Once allocated, the fake offset value must be passed to the application
|
||||
in a driver-specific way and can then be used as the mmap offset
|
||||
argument.
|
||||
|
||||
The GEM core provides a helper method :c:func:`drm_gem_mmap()` to
|
||||
The GEM core provides a helper method drm_gem_mmap() to
|
||||
handle object mapping. The method can be set directly as the mmap file
|
||||
operation handler. It will look up the GEM object based on the offset
|
||||
value and set the VMA operations to the :c:type:`struct drm_driver
|
||||
<drm_driver>` gem_vm_ops field. Note that
|
||||
:c:func:`drm_gem_mmap()` doesn't map memory to userspace, but
|
||||
relies on the driver-provided fault handler to map pages individually.
|
||||
<drm_driver>` gem_vm_ops field. Note that drm_gem_mmap() doesn't map memory to
|
||||
userspace, but relies on the driver-provided fault handler to map pages
|
||||
individually.
|
||||
|
||||
To use :c:func:`drm_gem_mmap()`, drivers must fill the struct
|
||||
:c:type:`struct drm_driver <drm_driver>` gem_vm_ops field
|
||||
with a pointer to VM operations.
|
||||
To use drm_gem_mmap(), drivers must fill the struct :c:type:`struct drm_driver
|
||||
<drm_driver>` gem_vm_ops field with a pointer to VM operations.
|
||||
|
||||
The VM operations is a :c:type:`struct vm_operations_struct <vm_operations_struct>`
|
||||
made up of several fields, the more interesting ones being:
|
||||
@@ -298,9 +293,8 @@ made up of several fields, the more interesting ones being:
|
||||
|
||||
|
||||
The open and close operations must update the GEM object reference
|
||||
count. Drivers can use the :c:func:`drm_gem_vm_open()` and
|
||||
:c:func:`drm_gem_vm_close()` helper functions directly as open
|
||||
and close handlers.
|
||||
count. Drivers can use the drm_gem_vm_open() and drm_gem_vm_close() helper
|
||||
functions directly as open and close handlers.
|
||||
|
||||
The fault operation handler is responsible for mapping individual pages
|
||||
to userspace when a page fault occurs. Depending on the memory
|
||||
@@ -312,12 +306,12 @@ Drivers that want to map the GEM object upfront instead of handling page
|
||||
faults can implement their own mmap file operation handler.
|
||||
|
||||
For platforms without MMU the GEM core provides a helper method
|
||||
:c:func:`drm_gem_cma_get_unmapped_area`. The mmap() routines will call
|
||||
this to get a proposed address for the mapping.
|
||||
drm_gem_cma_get_unmapped_area(). The mmap() routines will call this to get a
|
||||
proposed address for the mapping.
|
||||
|
||||
To use :c:func:`drm_gem_cma_get_unmapped_area`, drivers must fill the
|
||||
struct :c:type:`struct file_operations <file_operations>` get_unmapped_area
|
||||
field with a pointer on :c:func:`drm_gem_cma_get_unmapped_area`.
|
||||
To use drm_gem_cma_get_unmapped_area(), drivers must fill the struct
|
||||
:c:type:`struct file_operations <file_operations>` get_unmapped_area field with
|
||||
a pointer on drm_gem_cma_get_unmapped_area().
|
||||
|
||||
More detailed information about get_unmapped_area can be found in
|
||||
Documentation/nommu-mmap.txt
|
||||
|
@@ -254,36 +254,45 @@ Validating changes with IGT
|
||||
There's a collection of tests that aims to cover the whole functionality of
|
||||
DRM drivers and that can be used to check that changes to DRM drivers or the
|
||||
core don't regress existing functionality. This test suite is called IGT and
|
||||
its code can be found in https://cgit.freedesktop.org/drm/igt-gpu-tools/.
|
||||
its code and instructions to build and run can be found in
|
||||
https://gitlab.freedesktop.org/drm/igt-gpu-tools/.
|
||||
|
||||
To build IGT, start by installing its build dependencies. In Debian-based
|
||||
systems::
|
||||
Using VKMS to test DRM API
|
||||
--------------------------
|
||||
|
||||
# apt-get build-dep intel-gpu-tools
|
||||
VKMS is a software-only model of a KMS driver that is useful for testing
|
||||
and for running compositors. VKMS aims to enable a virtual display without
|
||||
the need for a hardware display capability. These characteristics made VKMS
|
||||
a perfect tool for validating the DRM core behavior and also support the
|
||||
compositor developer. VKMS makes it possible to test DRM functions in a
|
||||
virtual machine without display, simplifying the validation of some of the
|
||||
core changes.
|
||||
|
||||
And in Fedora-based systems::
|
||||
To Validate changes in DRM API with VKMS, start setting the kernel: make
|
||||
sure to enable VKMS module; compile the kernel with the VKMS enabled and
|
||||
install it in the target machine. VKMS can be run in a Virtual Machine
|
||||
(QEMU, virtme or similar). It's recommended the use of KVM with the minimum
|
||||
of 1GB of RAM and four cores.
|
||||
|
||||
# dnf builddep intel-gpu-tools
|
||||
It's possible to run the IGT-tests in a VM in two ways:
|
||||
|
||||
Then clone the repository::
|
||||
1. Use IGT inside a VM
|
||||
2. Use IGT from the host machine and write the results in a shared directory.
|
||||
|
||||
$ git clone git://anongit.freedesktop.org/drm/igt-gpu-tools
|
||||
As follow, there is an example of using a VM with a shared directory with
|
||||
the host machine to run igt-tests. As an example it's used virtme::
|
||||
|
||||
Configure the build system and start the build::
|
||||
$ virtme-run --rwdir /path/for/shared_dir --kdir=path/for/kernel/directory --mods=auto
|
||||
|
||||
$ cd igt-gpu-tools && ./autogen.sh && make -j6
|
||||
Run the igt-tests in the guest machine, as example it's ran the 'kms_flip'
|
||||
tests::
|
||||
|
||||
Download the piglit dependency::
|
||||
$ /path/for/igt-gpu-tools/scripts/run-tests.sh -p -s -t "kms_flip.*" -v
|
||||
|
||||
$ ./scripts/run-tests.sh -d
|
||||
|
||||
And run the tests::
|
||||
|
||||
$ ./scripts/run-tests.sh -t kms -t core -s
|
||||
|
||||
run-tests.sh is a wrapper around piglit that will execute the tests matching
|
||||
the -t options. A report in HTML format will be available in
|
||||
./results/html/index.html. Results can be compared with piglit.
|
||||
In this example, instead of build the igt_runner, Piglit is used
|
||||
(-p option); it's created html summary of the tests results and it's saved
|
||||
in the folder "igt-gpu-tools/results"; it's executed only the igt-tests
|
||||
matching the -t option.
|
||||
|
||||
Display CRC Support
|
||||
-------------------
|
||||
|
@@ -171,26 +171,43 @@ Contact: Maintainer of the driver you plan to convert
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Convert drivers to use drm_fb_helper_fbdev_setup/teardown()
|
||||
-----------------------------------------------------------
|
||||
Convert drivers to use drm_fbdev_generic_setup()
|
||||
------------------------------------------------
|
||||
|
||||
Most drivers can use drm_fb_helper_fbdev_setup() except maybe:
|
||||
|
||||
- amdgpu which has special logic to decide whether to call
|
||||
drm_helper_disable_unused_functions()
|
||||
|
||||
- armada which isn't atomic and doesn't call
|
||||
drm_helper_disable_unused_functions()
|
||||
|
||||
- i915 which calls drm_fb_helper_initial_config() in a worker
|
||||
|
||||
Drivers that use drm_framebuffer_remove() to clean up the fbdev framebuffer can
|
||||
probably use drm_fb_helper_fbdev_teardown().
|
||||
Most drivers can use drm_fbdev_generic_setup(). Driver have to implement
|
||||
atomic modesetting and GEM vmap support. Current generic fbdev emulation
|
||||
expects the framebuffer in system memory (or system-like memory).
|
||||
|
||||
Contact: Maintainer of the driver you plan to convert
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
drm_framebuffer_funcs and drm_mode_config_funcs.fb_create cleanup
|
||||
-----------------------------------------------------------------
|
||||
|
||||
A lot more drivers could be switched over to the drm_gem_framebuffer helpers.
|
||||
Various hold-ups:
|
||||
|
||||
- Need to switch over to the generic dirty tracking code using
|
||||
drm_atomic_helper_dirtyfb first (e.g. qxl).
|
||||
|
||||
- Need to switch to drm_fbdev_generic_setup(), otherwise a lot of the custom fb
|
||||
setup code can't be deleted.
|
||||
|
||||
- Many drivers wrap drm_gem_fb_create() only to check for valid formats. For
|
||||
atomic drivers we could check for valid formats by calling
|
||||
drm_plane_check_pixel_format() against all planes, and pass if any plane
|
||||
supports the format. For non-atomic that's not possible since like the format
|
||||
list for the primary plane is fake and we'd therefor reject valid formats.
|
||||
|
||||
- Many drivers subclass drm_framebuffer, we'd need a embedding compatible
|
||||
version of the varios drm_gem_fb_create functions. Maybe called
|
||||
drm_gem_fb_create/_with_dirty/_with_funcs as needed.
|
||||
|
||||
Contact: Daniel Vetter
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Clean up mmap forwarding
|
||||
------------------------
|
||||
|
||||
@@ -328,8 +345,8 @@ drm_fb_helper tasks
|
||||
these igt tests need to be fixed: kms_fbcon_fbt@psr and
|
||||
kms_fbcon_fbt@psr-suspend.
|
||||
|
||||
- The max connector argument for drm_fb_helper_init() and
|
||||
drm_fb_helper_fbdev_setup() isn't used anymore and can be removed.
|
||||
- The max connector argument for drm_fb_helper_init() isn't used anymore and
|
||||
can be removed.
|
||||
|
||||
- The helper doesn't keep an array of connectors anymore so these can be
|
||||
removed: drm_fb_helper_single_add_all_connectors(),
|
||||
@@ -351,6 +368,23 @@ connector register/unregister fixes
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Remove load/unload callbacks from all non-DRIVER_LEGACY drivers
|
||||
---------------------------------------------------------------
|
||||
|
||||
The load/unload callbacks in struct &drm_driver are very much midlayers, plus
|
||||
for historical reasons they get the ordering wrong (and we can't fix that)
|
||||
between setting up the &drm_driver structure and calling drm_dev_register().
|
||||
|
||||
- Rework drivers to no longer use the load/unload callbacks, directly coding the
|
||||
load/unload sequence into the driver's probe function.
|
||||
|
||||
- Once all non-DRIVER_LEGACY drivers are converted, disallow the load/unload
|
||||
callbacks for all modern drivers.
|
||||
|
||||
Contact: Daniel Vetter
|
||||
|
||||
Level: Intermediate
|
||||
|
||||
Core refactorings
|
||||
=================
|
||||
|
||||
|
Reference in New Issue
Block a user