summaryrefslogtreecommitdiff
path: root/kernel/cgroup
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-08-21 11:48:54 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-08-21 11:48:54 -0700
commit21bd0802cd3f58b656065f1be236694c40588c3a (patch)
tree08f3479623310d779023b5a8cd4290e53d1e37d7 /kernel/cgroup
parent35748ddd3b2c91555bd86b8cf88edc90e7317e57 (diff)
parent8049741ac93acd3a590dac070e12571fddf0e294 (diff)
downloadlwn-21bd0802cd3f58b656065f1be236694c40588c3a.tar.gz
lwn-21bd0802cd3f58b656065f1be236694c40588c3a.zip
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
Pull RDMA updates from Jason Gunthorpe: "About the normal size, still a lot of AI bug fixes and so on, but some interesting new functionality too: - Assorted locking, bounds-checking, cleanup, and error-path fixes across UCMA/CMA, bng_re, bnxt_re, cxgb4, EFA, ERDMA, HFI1, HNS, ionic, iRDMA, mlx4/mlx5, RXE, SIW, SRP/SRPT, and iSER target. - netlink report for max # of supported resources - get_zeroed_page()/etc removal - Robust udata for ionic - Allow unique RDMA device names per network namespace - Completion counters and v2 admit queue support for EFA - UC QP support for MANA - Completion timestamps for ionic - Harden uverbs data validation and resource lifetime handling, fixing several core use-after-free conditions. - bnxt_re toggle-page ownership and lifetime bug fixes - dmabuf SRQ support for mlx5" * tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma: (160 commits) RDMA/ucma: Allow path records to exactly fit the output buffer RDMA/uverbs: Guard legacy bundles without method_elm RDMA/efa: Add support for 128B admin v2 SQ entry RDMA/efa: Generalize the admin SQ RDMA/efa: Decouple admin command payload from admin header RDMA/rxe: Fix OOB in free_rd_atomic_resources() RDMA/cma: Fix WARNING in res_to_rt RDMA/cxgb4: Free debugfs on registration failure RDMA/cxgb4: Cancel reg_work before freeing device on remove RDMA/ucma: Lock the handler in ucma_set_ib_path() RDMA/ucma: Lock the handler in ucma_write_cm_event() RDMA/erdma: restrict the driver to little-endian systems RDMA/ionic: Embed counter driver data in rdma_counter allocation RDMA/ionic: Cap eq_count to the eth driver's interrupt vector budget RDMA/siw: Fix use-after-free in siw_accept() IB/isert: post the full-feature receive buffers after session registration IB/isert: delay the final Login Response until the session is registered RDMA/srp: fix heap information leak on a truncated SRP_CRED_REQ RDMA/erdma: Hold QP references for AE and CM processing RDMA/erdma: Hold CQ references when processing EQ events ...
Diffstat (limited to 'kernel/cgroup')
-rw-r--r--kernel/cgroup/rdma.c71
1 files changed, 59 insertions, 12 deletions
diff --git a/kernel/cgroup/rdma.c b/kernel/cgroup/rdma.c
index 5e82a03b3270..9489f3df0bf3 100644
--- a/kernel/cgroup/rdma.c
+++ b/kernel/cgroup/rdma.c
@@ -19,6 +19,7 @@
#define RDMACG_MAX_STR "max"
enum rdmacg_limit_tokens {
+ RDMACG_DEVICE_INDEX,
RDMACG_HCA_HANDLE_VAL,
RDMACG_HCA_HANDLE_MAX,
RDMACG_HCA_OBJECT_VAL,
@@ -27,6 +28,7 @@ enum rdmacg_limit_tokens {
};
static const match_table_t rdmacg_limit_tokens = {
+ { RDMACG_DEVICE_INDEX, "index=%u" },
{ RDMACG_HCA_HANDLE_VAL, "hca_handle=%d" },
{ RDMACG_HCA_HANDLE_MAX, "hca_handle=max" },
{ RDMACG_HCA_OBJECT_VAL, "hca_object=%d" },
@@ -464,17 +466,53 @@ void rdmacg_unregister_device(struct rdmacg_device *device)
}
EXPORT_SYMBOL(rdmacg_unregister_device);
-static struct rdmacg_device *rdmacg_get_device_locked(const char *name)
+static struct rdmacg_device *
+rdmacg_get_device_locked(const char *name, bool has_index, u32 index)
{
+ struct rdmacg_device *match = NULL;
struct rdmacg_device *device;
lockdep_assert_held(&rdmacg_mutex);
- list_for_each_entry(device, &rdmacg_devices, dev_node)
- if (!strcmp(name, device->name))
- return device;
+ list_for_each_entry(device, &rdmacg_devices, dev_node) {
+ if (strcmp(name, device->name))
+ continue;
- return NULL;
+ if (has_index) {
+ if (device->index == index)
+ return device;
+ continue;
+ }
+
+ if (match)
+ return ERR_PTR(-ENOTUNIQ);
+ match = device;
+ }
+
+ return match ?: ERR_PTR(-ENODEV);
+}
+
+static bool
+rdmacg_device_name_unique_locked(const struct rdmacg_device *device)
+{
+ struct rdmacg_device *other;
+
+ lockdep_assert_held(&rdmacg_mutex);
+
+ list_for_each_entry(other, &rdmacg_devices, dev_node)
+ if (other != device && !strcmp(other->name, device->name))
+ return false;
+
+ return true;
+}
+
+static void rdmacg_print_device_key(struct seq_file *sf,
+ const struct rdmacg_device *device)
+{
+ seq_puts(sf, device->name);
+ if (!rdmacg_device_name_unique_locked(device))
+ seq_printf(sf, " index=%u", device->index);
+ seq_putc(sf, ' ');
}
static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
@@ -488,6 +526,8 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
char *p;
int *new_limits;
unsigned long enables = 0;
+ u32 dev_index = 0;
+ bool has_index = false;
int i = 0, ret = 0;
/* extract the device name first */
@@ -503,7 +543,7 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
goto err;
}
- /* parse resource limit tokens */
+ /* parse the optional device index and resource limit tokens */
while ((p = strsep(&options, " \t\n"))) {
substring_t args[MAX_OPT_ARGS];
int tok, intval;
@@ -513,6 +553,13 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
tok = match_token(p, rdmacg_limit_tokens, args);
switch (tok) {
+ case RDMACG_DEVICE_INDEX:
+ if (has_index || match_uint(&args[0], &dev_index)) {
+ ret = -EINVAL;
+ goto parse_err;
+ }
+ has_index = true;
+ break;
case RDMACG_HCA_HANDLE_VAL:
if (match_int(&args[0], &intval) || intval < 0) {
ret = -EINVAL;
@@ -546,9 +593,9 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of,
/* acquire lock to synchronize with hot plug devices */
mutex_lock(&rdmacg_mutex);
- device = rdmacg_get_device_locked(dev_name);
- if (!device) {
- ret = -ENODEV;
+ device = rdmacg_get_device_locked(dev_name, has_index, dev_index);
+ if (IS_ERR(device)) {
+ ret = PTR_ERR(device);
goto dev_err;
}
@@ -626,7 +673,7 @@ static int rdmacg_resource_read(struct seq_file *sf, void *v)
mutex_lock(&rdmacg_mutex);
list_for_each_entry(device, &rdmacg_devices, dev_node) {
- seq_printf(sf, "%s ", device->name);
+ rdmacg_print_device_key(sf, device);
rpool = find_cg_rpool_locked(cg, device);
print_rpool_values(sf, rpool);
@@ -650,7 +697,7 @@ static int rdmacg_events_show(struct seq_file *sf, void *v)
list_for_each_entry(device, &rdmacg_devices, dev_node) {
rpool = find_cg_rpool_locked(cg, device);
- seq_printf(sf, "%s ", device->name);
+ rdmacg_print_device_key(sf, device);
for (i = 0; i < RDMACG_RESOURCE_MAX; i++) {
seq_printf(sf, "%s.max=%llu %s.alloc_fail=%llu",
rdmacg_resource_names[i],
@@ -679,7 +726,7 @@ static int rdmacg_events_local_show(struct seq_file *sf, void *v)
list_for_each_entry(device, &rdmacg_devices, dev_node) {
rpool = find_cg_rpool_locked(cg, device);
- seq_printf(sf, "%s ", device->name);
+ rdmacg_print_device_key(sf, device);
for (i = 0; i < RDMACG_RESOURCE_MAX; i++) {
seq_printf(sf, "%s.max=%llu %s.alloc_fail=%llu",
rdmacg_resource_names[i],