* [PATCH] EDAC/mc: embed channels with csrow_info
@ 2026-07-29 0:46 Rosen Penev
0 siblings, 0 replies; only message in thread
From: Rosen Penev @ 2026-07-29 0:46 UTC (permalink / raw)
To: linux-edac
Cc: Borislav Petkov, Tony Luck, Kees Cook, Gustavo A. R. Silva,
open list,
open list:KERNEL HARDENING (not covered by other areas):Keyword:b__counted_by(_le|_be|_ptr)?b
Use a flexible array member to combine allocations to avoid separate
freeing. Also emded the actual array to avoid separate allocations.
Add __counted_by for extra runtime analysis with UBSAN.
Move tot_channels assignment to after allocations. kzalloc_flex() does
this already for GCC >= 15.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/edac/edac_mc.c | 33 ++++++++++-----------------------
include/linux/edac.h | 2 +-
2 files changed, 11 insertions(+), 24 deletions(-)
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
index fd70caa85574..0fff56ce21b4 100644
--- a/drivers/edac/edac_mc.c
+++ b/drivers/edac/edac_mc.c
@@ -179,7 +179,7 @@ static void mci_release(struct device *dev)
{
struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);
struct csrow_info *csr;
- int i, chn, row;
+ int i, row;
if (mci->dimms) {
for (i = 0; i < mci->tot_dimms; i++)
@@ -193,11 +193,6 @@ static void mci_release(struct device *dev)
if (!csr)
continue;
- if (csr->channels) {
- for (chn = 0; chn < mci->num_cschannel; chn++)
- kfree(csr->channels[chn]);
- kfree(csr->channels);
- }
kfree(csr);
}
kfree(mci->csrows);
@@ -222,26 +217,18 @@ static int edac_mc_alloc_csrows(struct mem_ctl_info *mci)
for (row = 0; row < tot_csrows; row++) {
struct csrow_info *csr;
- csr = kzalloc_obj(**mci->csrows);
+ csr = kzalloc_flex(*csr, channels, tot_channels);
if (!csr)
return -ENOMEM;
+ csr->nr_channels = tot_channels;
mci->csrows[row] = csr;
csr->csrow_idx = row;
csr->mci = mci;
- csr->nr_channels = tot_channels;
- csr->channels = kzalloc_objs(*csr->channels, tot_channels);
- if (!csr->channels)
- return -ENOMEM;
for (chn = 0; chn < tot_channels; chn++) {
- struct rank_info *chan;
-
- chan = kzalloc_obj(**csr->channels);
- if (!chan)
- return -ENOMEM;
+ struct rank_info *chan = &csr->channels[chn];
- csr->channels[chn] = chan;
chan->chan_idx = chn;
chan->csrow = csr;
}
@@ -272,7 +259,7 @@ static int edac_mc_alloc_dimms(struct mem_ctl_info *mci)
struct rank_info *chan;
int n, len;
- chan = mci->csrows[row]->channels[chn];
+ chan = &mci->csrows[row]->channels[chn];
dimm = kzalloc_obj(**mci->dimms);
if (!dimm)
@@ -613,13 +600,13 @@ int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
int j;
for (j = 0; j < csrow->nr_channels; j++)
- nr_pages += csrow->channels[j]->dimm->nr_pages;
+ nr_pages += csrow->channels[j].dimm->nr_pages;
if (!nr_pages)
continue;
edac_mc_dump_csrow(csrow);
for (j = 0; j < csrow->nr_channels; j++)
- if (csrow->channels[j]->dimm->nr_pages)
- edac_mc_dump_channel(csrow->channels[j]);
+ if (csrow->channels[j].dimm->nr_pages)
+ edac_mc_dump_channel(&csrow->channels[j]);
}
mci_for_each_dimm(mci, dimm)
@@ -758,7 +745,7 @@ int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page)
struct csrow_info *csrow = csrows[i];
n = 0;
for (j = 0; j < csrow->nr_channels; j++) {
- struct dimm_info *dimm = csrow->channels[j]->dimm;
+ struct dimm_info *dimm = csrow->channels[j].dimm;
n += dimm->nr_pages;
}
if (n == 0)
@@ -904,7 +891,7 @@ static void edac_inc_csrow(struct edac_raw_error_desc *e, int row, int chan)
if (type == HW_EVENT_ERR_CORRECTED) {
mci->csrows[row]->ce_count += count;
if (chan >= 0)
- mci->csrows[row]->channels[chan]->ce_count += count;
+ mci->csrows[row]->channels[chan].ce_count += count;
} else {
mci->csrows[row]->ue_count += count;
}
diff --git a/include/linux/edac.h b/include/linux/edac.h
index 3902c3789510..3d8ee12c11be 100644
--- a/include/linux/edac.h
+++ b/include/linux/edac.h
@@ -448,7 +448,7 @@ struct csrow_info {
/* channel information for this csrow */
u32 nr_channels;
- struct rank_info **channels;
+ struct rank_info channels[] __counted_by(nr_channels);
};
/*
--
2.55.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-29 0:46 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-29 0:46 [PATCH] EDAC/mc: embed channels with csrow_info Rosen Penev
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.