From: Kenny Ho <Kenny.Ho@amd.com>
To: y2kenny@gmail.com, cgroups@vger.kernel.org,
dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org,
tj@kernel.org, alexander.deucher@amd.com,
christian.koenig@amd.com, felix.kuehling@amd.com,
joseph.greathouse@amd.com, jsparks@cray.com, lkaplan@cray.com,
daniel@ffwll.ch
Cc: Kenny Ho <Kenny.Ho@amd.com>
Subject: [PATCH RFC v4 03/16] drm, cgroup: Initialize drmcg properties
Date: Thu, 29 Aug 2019 02:05:20 -0400 [thread overview]
Message-ID: <20190829060533.32315-4-Kenny.Ho@amd.com> (raw)
In-Reply-To: <20190829060533.32315-1-Kenny.Ho@amd.com>
drmcg initialization involves allocating a per cgroup, per device data
structure and setting the defaults. There are two entry points for
drmcg init:
1) When struct drmcg is created via css_alloc, initialization is done
for each device
2) When DRM devices are created after drmcgs are created
a) Per device drmcg data structure is allocated at the beginning of
DRM device creation such that drmcg can begin tracking usage
statistics
b) At the end of DRM device creation, drmcg_device_update is called in
case device specific defaults need to be applied.
Entry point #2 usually applies to the root cgroup since it can be
created before DRM devices are available. The drmcg controller will go
through all existing drm cgroups and initialize them with the new device
accordingly.
Change-Id: I908ee6975ea0585e4c30eafde4599f87094d8c65
Signed-off-by: Kenny Ho <Kenny.Ho@amd.com>
---
drivers/gpu/drm/drm_drv.c | 7 +++
include/drm/drm_cgroup.h | 27 ++++++++
include/drm/drm_device.h | 7 +++
include/drm/drm_drv.h | 9 +++
include/linux/cgroup_drm.h | 13 ++++
kernel/cgroup/drm.c | 123 +++++++++++++++++++++++++++++++++++++
6 files changed, 186 insertions(+)
create mode 100644 include/drm/drm_cgroup.h
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 000cddabd970..94265eba68ca 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -37,6 +37,7 @@
#include <drm/drm_client.h>
#include <drm/drm_drv.h>
#include <drm/drmP.h>
+#include <drm/drm_cgroup.h>
#include "drm_crtc_internal.h"
#include "drm_legacy.h"
@@ -672,6 +673,7 @@ int drm_dev_init(struct drm_device *dev,
mutex_init(&dev->filelist_mutex);
mutex_init(&dev->clientlist_mutex);
mutex_init(&dev->master_mutex);
+ mutex_init(&dev->drmcg_mutex);
dev->anon_inode = drm_fs_inode_new();
if (IS_ERR(dev->anon_inode)) {
@@ -708,6 +710,7 @@ int drm_dev_init(struct drm_device *dev,
if (ret)
goto err_setunique;
+ drmcg_device_early_init(dev);
return 0;
err_setunique:
@@ -722,6 +725,7 @@ int drm_dev_init(struct drm_device *dev,
drm_fs_inode_free(dev->anon_inode);
err_free:
put_device(dev->dev);
+ mutex_destroy(&dev->drmcg_mutex);
mutex_destroy(&dev->master_mutex);
mutex_destroy(&dev->clientlist_mutex);
mutex_destroy(&dev->filelist_mutex);
@@ -798,6 +802,7 @@ void drm_dev_fini(struct drm_device *dev)
put_device(dev->dev);
+ mutex_destroy(&dev->drmcg_mutex);
mutex_destroy(&dev->master_mutex);
mutex_destroy(&dev->clientlist_mutex);
mutex_destroy(&dev->filelist_mutex);
@@ -1008,6 +1013,8 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
dev->dev ? dev_name(dev->dev) : "virtual device",
dev->primary->index);
+ drmcg_device_update(dev);
+
goto out_unlock;
err_minors:
diff --git a/include/drm/drm_cgroup.h b/include/drm/drm_cgroup.h
new file mode 100644
index 000000000000..bef9f9245924
--- /dev/null
+++ b/include/drm/drm_cgroup.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: MIT
+ * Copyright 2019 Advanced Micro Devices, Inc.
+ */
+#ifndef __DRM_CGROUP_H__
+#define __DRM_CGROUP_H__
+
+/**
+ * Per DRM device properties for DRM cgroup controller for the purpose
+ * of storing per device defaults
+ */
+struct drmcg_props {
+};
+
+#ifdef CONFIG_CGROUP_DRM
+
+void drmcg_device_update(struct drm_device *device);
+void drmcg_device_early_init(struct drm_device *device);
+#else
+static inline void drmcg_device_update(struct drm_device *device)
+{
+}
+
+static inline void drmcg_device_early_init(struct drm_device *device)
+{
+}
+#endif /* CONFIG_CGROUP_DRM */
+#endif /* __DRM_CGROUP_H__ */
diff --git a/include/drm/drm_device.h b/include/drm/drm_device.h
index 7f9ef709b2b6..5d7d779a5083 100644
--- a/include/drm/drm_device.h
+++ b/include/drm/drm_device.h
@@ -8,6 +8,7 @@
#include <drm/drm_hashtab.h>
#include <drm/drm_mode_config.h>
+#include <drm/drm_cgroup.h>
struct drm_driver;
struct drm_minor;
@@ -304,6 +305,12 @@ struct drm_device {
*/
struct drm_fb_helper *fb_helper;
+ /** \name DRM Cgroup */
+ /*@{ */
+ struct mutex drmcg_mutex;
+ struct drmcg_props drmcg_props;
+ /*@} */
+
/* Everything below here is for legacy driver, never use! */
/* private: */
#if IS_ENABLED(CONFIG_DRM_LEGACY)
diff --git a/include/drm/drm_drv.h b/include/drm/drm_drv.h
index 24f8d054c570..c8a37a08d98d 100644
--- a/include/drm/drm_drv.h
+++ b/include/drm/drm_drv.h
@@ -660,6 +660,15 @@ struct drm_driver {
struct drm_device *dev,
uint32_t handle);
+ /**
+ * @drmcg_custom_init
+ *
+ * Optional callback used to initialize drm cgroup per device properties
+ * such as resource limit defaults.
+ */
+ void (*drmcg_custom_init)(struct drm_device *dev,
+ struct drmcg_props *props);
+
/**
* @gem_vm_ops: Driver private ops for this object
*/
diff --git a/include/linux/cgroup_drm.h b/include/linux/cgroup_drm.h
index 971166f9dd78..4ecd44f2ac27 100644
--- a/include/linux/cgroup_drm.h
+++ b/include/linux/cgroup_drm.h
@@ -6,13 +6,26 @@
#ifdef CONFIG_CGROUP_DRM
+#include <linux/mutex.h>
#include <linux/cgroup.h>
+#include <drm/drm_file.h>
+
+/* limit defined per the way drm_minor_alloc operates */
+#define MAX_DRM_DEV (64 * DRM_MINOR_RENDER)
+
+/**
+ * Per DRM cgroup, per device resources (such as statistics and limits)
+ */
+struct drmcg_device_resource {
+ /* for per device stats */
+};
/**
* The DRM cgroup controller data structure.
*/
struct drmcg {
struct cgroup_subsys_state css;
+ struct drmcg_device_resource *dev_resources[MAX_DRM_DEV];
};
/**
diff --git a/kernel/cgroup/drm.c b/kernel/cgroup/drm.c
index e97861b3cb30..135fdcdc4b51 100644
--- a/kernel/cgroup/drm.c
+++ b/kernel/cgroup/drm.c
@@ -1,28 +1,103 @@
// SPDX-License-Identifier: MIT
// Copyright 2019 Advanced Micro Devices, Inc.
+#include <linux/export.h>
#include <linux/slab.h>
#include <linux/cgroup.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/mutex.h>
#include <linux/cgroup_drm.h>
+#include <linux/kernel.h>
+#include <drm/drm_file.h>
+#include <drm/drm_drv.h>
+#include <drm/drm_device.h>
+#include <drm/drm_cgroup.h>
+
+/* global mutex for drmcg across all devices */
+static DEFINE_MUTEX(drmcg_mutex);
static struct drmcg *root_drmcg __read_mostly;
+static int drmcg_css_free_fn(int id, void *ptr, void *data)
+{
+ struct drm_minor *minor = ptr;
+ struct drmcg *drmcg = data;
+
+ if (minor->type != DRM_MINOR_PRIMARY)
+ return 0;
+
+ kfree(drmcg->dev_resources[minor->index]);
+
+ return 0;
+}
+
static void drmcg_css_free(struct cgroup_subsys_state *css)
{
struct drmcg *drmcg = css_to_drmcg(css);
+ drm_minor_for_each(&drmcg_css_free_fn, drmcg);
+
kfree(drmcg);
}
+static inline int init_drmcg_single(struct drmcg *drmcg, struct drm_device *dev)
+{
+ int minor = dev->primary->index;
+ struct drmcg_device_resource *ddr = drmcg->dev_resources[minor];
+
+ if (ddr == NULL) {
+ ddr = kzalloc(sizeof(struct drmcg_device_resource),
+ GFP_KERNEL);
+
+ if (!ddr)
+ return -ENOMEM;
+ }
+
+ mutex_lock(&dev->drmcg_mutex);
+ drmcg->dev_resources[minor] = ddr;
+
+ /* set defaults here */
+
+ mutex_unlock(&dev->drmcg_mutex);
+ return 0;
+}
+
+static int init_drmcg_fn(int id, void *ptr, void *data)
+{
+ struct drm_minor *minor = ptr;
+ struct drmcg *drmcg = data;
+
+ if (minor->type != DRM_MINOR_PRIMARY)
+ return 0;
+
+ return init_drmcg_single(drmcg, minor->dev);
+}
+
+static inline int init_drmcg(struct drmcg *drmcg, struct drm_device *dev)
+{
+ if (dev != NULL)
+ return init_drmcg_single(drmcg, dev);
+
+ return drm_minor_for_each(&init_drmcg_fn, drmcg);
+}
+
static struct cgroup_subsys_state *
drmcg_css_alloc(struct cgroup_subsys_state *parent_css)
{
struct drmcg *parent = css_to_drmcg(parent_css);
struct drmcg *drmcg;
+ int rc;
drmcg = kzalloc(sizeof(struct drmcg), GFP_KERNEL);
if (!drmcg)
return ERR_PTR(-ENOMEM);
+ rc = init_drmcg(drmcg, NULL);
+ if (rc) {
+ drmcg_css_free(&drmcg->css);
+ return ERR_PTR(rc);
+ }
+
if (!parent)
root_drmcg = drmcg;
@@ -40,3 +115,51 @@ struct cgroup_subsys drm_cgrp_subsys = {
.legacy_cftypes = files,
.dfl_cftypes = files,
};
+
+static inline void drmcg_update_cg_tree(struct drm_device *dev)
+{
+ /* init cgroups created before registration (i.e. root cgroup) */
+ if (root_drmcg != NULL) {
+ struct cgroup_subsys_state *pos;
+ struct drmcg *child;
+
+ rcu_read_lock();
+ css_for_each_descendant_pre(pos, &root_drmcg->css) {
+ child = css_to_drmcg(pos);
+ init_drmcg(child, dev);
+ }
+ rcu_read_unlock();
+ }
+}
+
+/**
+ * drmcg_device_update - update DRM cgroups defaults
+ * @dev: the target DRM device
+ *
+ * If @dev has a drmcg_custom_init for the DRM cgroup controller, it will be called
+ * to set device specific defaults and set the initial values for all existing
+ * cgroups created prior to @dev become available.
+ */
+void drmcg_device_update(struct drm_device *dev)
+{
+ if (dev->driver->drmcg_custom_init)
+ {
+ dev->driver->drmcg_custom_init(dev, &dev->drmcg_props);
+
+ drmcg_update_cg_tree(dev);
+ }
+}
+EXPORT_SYMBOL(drmcg_device_update);
+
+/**
+ * drmcg_device_early_init - initialize device specific resources for DRM cgroups
+ * @dev: the target DRM device
+ *
+ * Allocate and initialize device specific resources for existing DRM cgroups.
+ * Typically only the root cgroup exists before the initialization of @dev.
+ */
+void drmcg_device_early_init(struct drm_device *dev)
+{
+ drmcg_update_cg_tree(dev);
+}
+EXPORT_SYMBOL(drmcg_device_early_init);
--
2.22.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2019-08-29 6:05 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-29 6:05 [PATCH RFC v4 00/16] new cgroup controller for gpu/drm subsystem Kenny Ho
2019-08-29 6:05 ` [PATCH RFC v4 02/16] cgroup: Introduce cgroup for drm subsystem Kenny Ho
[not found] ` <20190829060533.32315-3-Kenny.Ho-5C7GfCeVMHo@public.gmane.org>
2019-10-01 14:31 ` Michal Koutný
[not found] ` <20191001143106.GA4749-9OudH3eul5jcvrawFnH+a6VXKuFTiq87@public.gmane.org>
2019-11-29 6:00 ` Kenny Ho
2019-11-29 6:00 ` Kenny Ho
2019-12-02 19:14 ` Tejun Heo
2019-08-29 6:05 ` Kenny Ho [this message]
2019-08-29 6:05 ` [PATCH RFC v4 07/16] drm, cgroup: Add total GEM buffer allocation limit Kenny Ho
[not found] ` <20190829060533.32315-8-Kenny.Ho-5C7GfCeVMHo@public.gmane.org>
2019-10-01 14:30 ` Michal Koutný
2019-11-29 7:18 ` Kenny Ho
2019-11-29 7:18 ` Kenny Ho
2019-08-29 6:05 ` [PATCH RFC v4 12/16] drm, cgroup: Add soft VRAM limit Kenny Ho
2019-08-29 6:05 ` [PATCH RFC v4 14/16] drm, cgroup: Introduce lgpu as DRM cgroup resource Kenny Ho
[not found] ` <20190829060533.32315-15-Kenny.Ho-5C7GfCeVMHo@public.gmane.org>
2019-10-08 18:53 ` Kuehling, Felix
[not found] ` <b3d2b3c1-8854-10ca-3e39-b3bef35bdfa9-5C7GfCeVMHo@public.gmane.org>
2019-10-09 10:31 ` Daniel Vetter
[not found] ` <20191009103153.GU16989-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2019-10-09 15:08 ` Kenny Ho
[not found] ` <CAOWid-fLurBT6-h5WjQsEPA+dq1fgfWztbyZuLV4ypmWH8SC9w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-10-09 15:23 ` Daniel Vetter
2019-10-09 15:25 ` Kuehling, Felix
[not found] ` <ee873e89-48fd-c4c9-1ce0-73965f4ad2ba-5C7GfCeVMHo@public.gmane.org>
2019-10-09 15:34 ` Daniel Vetter
[not found] ` <20191009153429.GI16989-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2019-10-09 15:53 ` Kuehling, Felix
[not found] ` <c7812af4-7ec4-02bb-ff4c-21dd114cf38e-5C7GfCeVMHo@public.gmane.org>
2019-10-09 16:06 ` Daniel Vetter
2019-10-09 18:52 ` Greathouse, Joseph
[not found] ` <CY4PR12MB17670EE9EE4A22663EB584E8F9950-rpdhrqHFk07NeWpHaHeGuQdYzm3356FpvxpqHgZTriW3zl9H0oFU5g@public.gmane.org>
2019-10-09 19:07 ` Daniel Vetter
2019-10-11 17:12 ` tj
2019-11-29 20:10 ` Felix Kuehling
[not found] ` <20190829060533.32315-1-Kenny.Ho-5C7GfCeVMHo@public.gmane.org>
2019-08-29 6:05 ` [PATCH RFC v4 05/16] drm, cgroup: Add peak GEM buffer allocation stats Kenny Ho
2019-08-29 6:05 ` [PATCH RFC v4 08/16] drm, cgroup: Add peak GEM buffer allocation limit Kenny Ho
2019-08-29 6:05 ` [PATCH RFC v4 09/16] drm, cgroup: Add TTM buffer allocation stats Kenny Ho
2019-08-29 6:05 ` [PATCH RFC v4 10/16] drm, cgroup: Add TTM buffer peak usage stats Kenny Ho
2019-08-29 6:05 ` [PATCH RFC v4 11/16] drm, cgroup: Add per cgroup bw measure and control Kenny Ho
[not found] ` <20190829060533.32315-12-Kenny.Ho-5C7GfCeVMHo@public.gmane.org>
2019-10-01 14:30 ` Michal Koutný
2019-08-29 6:05 ` [PATCH RFC v4 13/16] drm, cgroup: Allow more aggressive memory reclaim Kenny Ho
2019-08-29 7:08 ` Koenig, Christian
2019-08-29 14:07 ` Kenny Ho
[not found] ` <CAOWid-dzJiqjH9+=36fFYh87OKOzToMDcJZpepOWdjoXpBSF8A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-08-29 14:12 ` Koenig, Christian
[not found] ` <f6963293-bebe-0dca-b509-799f9096ca91-5C7GfCeVMHo@public.gmane.org>
2019-08-29 14:39 ` Kenny Ho
2019-08-29 6:05 ` [PATCH RFC v4 15/16] drm, cgroup: add update trigger after limit change Kenny Ho
2019-08-31 4:28 ` [PATCH RFC v4 00/16] new cgroup controller for gpu/drm subsystem Tejun Heo
[not found] ` <20190831042857.GD2263813-LpCCV3molIbIZ9tKgghJQw2O0Ztt9esIQQ4Iyu8u01E@public.gmane.org>
2019-09-03 7:55 ` Daniel Vetter
[not found] ` <20190903075550.GJ2112-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2019-09-03 18:50 ` Tejun Heo
2019-09-03 19:23 ` Kenny Ho
2019-09-03 19:48 ` Daniel Vetter
[not found] ` <CAKMK7uE5Bj-3cJH895iqnLpwUV+GBDM1Y=n4Z4A3xervMdJKXg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-06 15:23 ` Tejun Heo
[not found] ` <20190906152320.GM2263813-LpCCV3molIbIZ9tKgghJQw2O0Ztt9esIQQ4Iyu8u01E@public.gmane.org>
2019-09-06 15:34 ` Daniel Vetter
[not found] ` <CAKMK7uEXP7XLFB2aFU6+E0TH_DepFRkfCoKoHwkXtjZRDyhHig-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-06 15:45 ` Tejun Heo
[not found] ` <20190906154539.GP2263813-LpCCV3molIbIZ9tKgghJQw2O0Ztt9esIQQ4Iyu8u01E@public.gmane.org>
2019-09-10 11:54 ` Michal Hocko
[not found] ` <20190910115448.GT2063-2MMpYkNvuYDjFM9bn6wA6Q@public.gmane.org>
2019-09-10 16:03 ` Tejun Heo
2019-09-10 17:25 ` Michal Hocko
2019-09-17 12:21 ` Daniel Vetter
2019-08-29 6:05 ` [PATCH RFC v4 16/16] drm/amdgpu: Integrate with DRM cgroup Kenny Ho
[not found] ` <20190829060533.32315-17-Kenny.Ho-5C7GfCeVMHo@public.gmane.org>
2019-10-08 19:11 ` Kuehling, Felix
[not found] ` <04abdc58-ae30-a13d-e7dc-f1020a1400b9-5C7GfCeVMHo@public.gmane.org>
2019-11-29 5:59 ` Kenny Ho
2019-11-29 5:59 ` Kenny Ho
2019-12-02 22:05 ` Greathouse, Joseph
2019-12-03 16:02 ` Kenny Ho
2019-09-03 8:02 ` [PATCH RFC v4 00/16] new cgroup controller for gpu/drm subsystem Daniel Vetter
[not found] ` <20190903080217.GL2112-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2019-09-03 8:24 ` Koenig, Christian
2019-09-03 9:19 ` Daniel Vetter
2019-09-03 19:30 ` Kenny Ho
[not found] ` <20190829060533.32315-2-Kenny.Ho@amd.com>
[not found] ` <20190903075719.GK2112@phenom.ffwll.local>
2019-09-03 19:45 ` [PATCH RFC v4 01/16] drm: Add drm_minor_for_each Kenny Ho
[not found] ` <CAOWid-dxxDhyxP2+0R0oKAk29rR-1TbMyhshR1+gbcpGJCAW6g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-03 20:12 ` Daniel Vetter
[not found] ` <CAKMK7uEofjdVURu+meonh_YdV5eX8vfNALkW3A_+kLapCV8j+w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-03 20:43 ` Kenny Ho
[not found] ` <CAOWid-eUVztW4hNVpznnJRcwHcjCirGL2aS75p4OY8XoGuJqUg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-04 8:54 ` Daniel Vetter
[not found] ` <20190904085434.GF2112-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2019-09-05 18:27 ` Kenny Ho
2019-09-05 18:28 ` Kenny Ho
2019-09-05 20:06 ` Daniel Vetter
[not found] ` <CAKMK7uGSrscs-WAv0pYfcxaUGXvx7M6JYbiPHTY=1hxRbFK1sg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-05 20:20 ` Kenny Ho
2019-09-05 20:32 ` Daniel Vetter
[not found] ` <CAKMK7uHy+GRAcpLDuz6STCBW+GNfNWr-i=ZERF3uqkO7jfynnQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-05 21:26 ` Kenny Ho
[not found] ` <CAOWid-cRP1T2gr2U_ZN+QhS7jFM0kFTWiYy8JPPXXmGW7xBPzA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-06 9:12 ` Daniel Vetter
2019-09-06 15:29 ` Tejun Heo
2019-09-06 15:36 ` Daniel Vetter
[not found] ` <CAKMK7uFQqAMB1DbiEy-o2bzr_F25My93imNcg1Qh9DHe=uWQug-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2019-09-06 15:38 ` Tejun Heo
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=20190829060533.32315-4-Kenny.Ho@amd.com \
--to=kenny.ho@amd.com \
--cc=alexander.deucher@amd.com \
--cc=amd-gfx@lists.freedesktop.org \
--cc=cgroups@vger.kernel.org \
--cc=christian.koenig@amd.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=felix.kuehling@amd.com \
--cc=joseph.greathouse@amd.com \
--cc=jsparks@cray.com \
--cc=lkaplan@cray.com \
--cc=tj@kernel.org \
--cc=y2kenny@gmail.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