Skip to content

Commit be80a1c

Browse files
committed
Merge branches 'edac-misc' and 'edac-alloc-cleanup' into edac-updates-for-v5.19
Combine all collected EDAC changes for submission into v5.19: * edac-misc: EDAC/xgene: Fix typo processsors -> processors EDAC/i5100: Remove unused inline function i5100_nrecmema_dm_buf_id() EDAC/ghes: Change ghes_hw from global to static EDAC/armada_xp: Use devm_platform_ioremap_resource() EDAC/synopsys: Add a SPDX identifier EDAC/synopsys: Add driver support for i.MX platforms EDAC/dmc520: Don't print an error for each unconfigured interrupt line efi/cper: Reformat CPER memory error location to more readable EDAC/ghes: Unify CPER memory error location reporting efi/cper: Add a cper_mem_err_status_str() to decode error description powerpc/85xx: Remove fsl,85... bindings * edac-alloc-cleanup: EDAC: Use kcalloc() EDAC/mc: Get rid of edac_align_ptr() EDAC/device: Sanitize edac_device_alloc_ctl_info() definition EDAC/device: Get rid of the silly one-shot memory allocation in edac_device_alloc_ctl_info() EDAC/pci: Get rid of the silly one-shot memory allocation in edac_pci_alloc_ctl_info() EDAC/mc: Get rid of silly one-shot struct allocation in edac_mc_alloc() Signed-off-by: Borislav Petkov <bp@suse.de>
2 parents 2aeb1f5 + 13088b6 commit be80a1c

6 files changed

Lines changed: 90 additions & 182 deletions

File tree

drivers/edac/edac_device.c

Lines changed: 50 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -47,99 +47,67 @@ static void edac_device_dump_device(struct edac_device_ctl_info *edac_dev)
4747
}
4848
#endif /* CONFIG_EDAC_DEBUG */
4949

50-
struct edac_device_ctl_info *edac_device_alloc_ctl_info(
51-
unsigned sz_private,
52-
char *edac_device_name, unsigned nr_instances,
53-
char *edac_block_name, unsigned nr_blocks,
54-
unsigned offset_value, /* zero, 1, or other based offset */
55-
struct edac_dev_sysfs_block_attribute *attrib_spec, unsigned nr_attrib,
56-
int device_index)
50+
/*
51+
* @off_val: zero, 1, or other based offset
52+
*/
53+
struct edac_device_ctl_info *
54+
edac_device_alloc_ctl_info(unsigned pvt_sz, char *dev_name, unsigned nr_instances,
55+
char *blk_name, unsigned nr_blocks, unsigned off_val,
56+
struct edac_dev_sysfs_block_attribute *attrib_spec,
57+
unsigned nr_attrib, int device_index)
5758
{
58-
struct edac_device_ctl_info *dev_ctl;
59-
struct edac_device_instance *dev_inst, *inst;
60-
struct edac_device_block *dev_blk, *blk_p, *blk;
6159
struct edac_dev_sysfs_block_attribute *dev_attrib, *attrib_p, *attrib;
62-
unsigned total_size;
63-
unsigned count;
60+
struct edac_device_block *dev_blk, *blk_p, *blk;
61+
struct edac_device_instance *dev_inst, *inst;
62+
struct edac_device_ctl_info *dev_ctl;
6463
unsigned instance, block, attr;
65-
void *pvt, *p;
64+
void *pvt;
6665
int err;
6766

6867
edac_dbg(4, "instances=%d blocks=%d\n", nr_instances, nr_blocks);
6968

70-
/* Calculate the size of memory we need to allocate AND
71-
* determine the offsets of the various item arrays
72-
* (instance,block,attrib) from the start of an allocated structure.
73-
* We want the alignment of each item (instance,block,attrib)
74-
* to be at least as stringent as what the compiler would
75-
* provide if we could simply hardcode everything into a single struct.
76-
*/
77-
p = NULL;
78-
dev_ctl = edac_align_ptr(&p, sizeof(*dev_ctl), 1);
69+
dev_ctl = kzalloc(sizeof(struct edac_device_ctl_info), GFP_KERNEL);
70+
if (!dev_ctl)
71+
return NULL;
7972

80-
/* Calc the 'end' offset past end of ONE ctl_info structure
81-
* which will become the start of the 'instance' array
82-
*/
83-
dev_inst = edac_align_ptr(&p, sizeof(*dev_inst), nr_instances);
73+
dev_inst = kcalloc(nr_instances, sizeof(struct edac_device_instance), GFP_KERNEL);
74+
if (!dev_inst)
75+
goto free;
8476

85-
/* Calc the 'end' offset past the instance array within the ctl_info
86-
* which will become the start of the block array
87-
*/
88-
count = nr_instances * nr_blocks;
89-
dev_blk = edac_align_ptr(&p, sizeof(*dev_blk), count);
77+
dev_ctl->instances = dev_inst;
9078

91-
/* Calc the 'end' offset past the dev_blk array
92-
* which will become the start of the attrib array, if any.
93-
*/
94-
/* calc how many nr_attrib we need */
95-
if (nr_attrib > 0)
96-
count *= nr_attrib;
97-
dev_attrib = edac_align_ptr(&p, sizeof(*dev_attrib), count);
79+
dev_blk = kcalloc(nr_instances * nr_blocks, sizeof(struct edac_device_block), GFP_KERNEL);
80+
if (!dev_blk)
81+
goto free;
9882

99-
/* Calc the 'end' offset past the attributes array */
100-
pvt = edac_align_ptr(&p, sz_private, 1);
83+
dev_ctl->blocks = dev_blk;
10184

102-
/* 'pvt' now points to where the private data area is.
103-
* At this point 'pvt' (like dev_inst,dev_blk and dev_attrib)
104-
* is baselined at ZERO
105-
*/
106-
total_size = ((unsigned long)pvt) + sz_private;
85+
if (nr_attrib) {
86+
dev_attrib = kcalloc(nr_attrib, sizeof(struct edac_dev_sysfs_block_attribute),
87+
GFP_KERNEL);
88+
if (!dev_attrib)
89+
goto free;
10790

108-
/* Allocate the amount of memory for the set of control structures */
109-
dev_ctl = kzalloc(total_size, GFP_KERNEL);
110-
if (dev_ctl == NULL)
111-
return NULL;
91+
dev_ctl->attribs = dev_attrib;
92+
}
11293

113-
/* Adjust pointers so they point within the actual memory we
114-
* just allocated rather than an imaginary chunk of memory
115-
* located at address 0.
116-
* 'dev_ctl' points to REAL memory, while the others are
117-
* ZERO based and thus need to be adjusted to point within
118-
* the allocated memory.
119-
*/
120-
dev_inst = (struct edac_device_instance *)
121-
(((char *)dev_ctl) + ((unsigned long)dev_inst));
122-
dev_blk = (struct edac_device_block *)
123-
(((char *)dev_ctl) + ((unsigned long)dev_blk));
124-
dev_attrib = (struct edac_dev_sysfs_block_attribute *)
125-
(((char *)dev_ctl) + ((unsigned long)dev_attrib));
126-
pvt = sz_private ? (((char *)dev_ctl) + ((unsigned long)pvt)) : NULL;
127-
128-
/* Begin storing the information into the control info structure */
129-
dev_ctl->dev_idx = device_index;
130-
dev_ctl->nr_instances = nr_instances;
131-
dev_ctl->instances = dev_inst;
132-
dev_ctl->pvt_info = pvt;
94+
if (pvt_sz) {
95+
pvt = kzalloc(pvt_sz, GFP_KERNEL);
96+
if (!pvt)
97+
goto free;
98+
99+
dev_ctl->pvt_info = pvt;
100+
}
101+
102+
dev_ctl->dev_idx = device_index;
103+
dev_ctl->nr_instances = nr_instances;
133104

134105
/* Default logging of CEs and UEs */
135106
dev_ctl->log_ce = 1;
136107
dev_ctl->log_ue = 1;
137108

138109
/* Name of this edac device */
139-
snprintf(dev_ctl->name,sizeof(dev_ctl->name),"%s",edac_device_name);
140-
141-
edac_dbg(4, "edac_dev=%p next after end=%p\n",
142-
dev_ctl, pvt + sz_private);
110+
snprintf(dev_ctl->name, sizeof(dev_ctl->name),"%s", dev_name);
143111

144112
/* Initialize every Instance */
145113
for (instance = 0; instance < nr_instances; instance++) {
@@ -150,15 +118,14 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
150118
inst->blocks = blk_p;
151119

152120
/* name of this instance */
153-
snprintf(inst->name, sizeof(inst->name),
154-
"%s%u", edac_device_name, instance);
121+
snprintf(inst->name, sizeof(inst->name), "%s%u", dev_name, instance);
155122

156123
/* Initialize every block in each instance */
157124
for (block = 0; block < nr_blocks; block++) {
158125
blk = &blk_p[block];
159126
blk->instance = inst;
160127
snprintf(blk->name, sizeof(blk->name),
161-
"%s%d", edac_block_name, block+offset_value);
128+
"%s%d", blk_name, block + off_val);
162129

163130
edac_dbg(4, "instance=%d inst_p=%p block=#%d block_p=%p name='%s'\n",
164131
instance, inst, block, blk, blk->name);
@@ -210,10 +177,8 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
210177
* Initialize the 'root' kobj for the edac_device controller
211178
*/
212179
err = edac_device_register_sysfs_main_kobj(dev_ctl);
213-
if (err) {
214-
kfree(dev_ctl);
215-
return NULL;
216-
}
180+
if (err)
181+
goto free;
217182

218183
/* at this point, the root kobj is valid, and in order to
219184
* 'free' the object, then the function:
@@ -223,6 +188,11 @@ struct edac_device_ctl_info *edac_device_alloc_ctl_info(
223188
*/
224189

225190
return dev_ctl;
191+
192+
free:
193+
__edac_device_free_ctl_info(dev_ctl);
194+
195+
return NULL;
226196
}
227197
EXPORT_SYMBOL_GPL(edac_device_alloc_ctl_info);
228198

drivers/edac/edac_device.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ struct edac_device_ctl_info {
216216
*/
217217
u32 nr_instances;
218218
struct edac_device_instance *instances;
219+
struct edac_device_block *blocks;
220+
struct edac_dev_sysfs_block_attribute *attribs;
219221

220222
/* Event counters for the this whole EDAC Device */
221223
struct edac_device_counter counters;
@@ -348,4 +350,16 @@ edac_device_handle_ue(struct edac_device_ctl_info *edac_dev, int inst_nr,
348350
*/
349351
extern int edac_device_alloc_index(void);
350352
extern const char *edac_layer_name[];
353+
354+
/* Free the actual struct */
355+
static inline void __edac_device_free_ctl_info(struct edac_device_ctl_info *ci)
356+
{
357+
if (ci) {
358+
kfree(ci->pvt_info);
359+
kfree(ci->attribs);
360+
kfree(ci->blocks);
361+
kfree(ci->instances);
362+
kfree(ci);
363+
}
364+
}
351365
#endif

drivers/edac/edac_device_sysfs.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,7 @@ static void edac_device_ctrl_master_release(struct kobject *kobj)
208208
/* decrement the EDAC CORE module ref count */
209209
module_put(edac_dev->owner);
210210

211-
/* free the control struct containing the 'main' kobj
212-
* passed in to this routine
213-
*/
214-
kfree(edac_dev);
211+
__edac_device_free_ctl_info(edac_dev);
215212
}
216213

217214
/* ktype for the main (master) kobject */

drivers/edac/edac_mc.c

Lines changed: 13 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -170,61 +170,6 @@ const char * const edac_mem_types[] = {
170170
};
171171
EXPORT_SYMBOL_GPL(edac_mem_types);
172172

173-
/**
174-
* edac_align_ptr - Prepares the pointer offsets for a single-shot allocation
175-
* @p: pointer to a pointer with the memory offset to be used. At
176-
* return, this will be incremented to point to the next offset
177-
* @size: Size of the data structure to be reserved
178-
* @n_elems: Number of elements that should be reserved
179-
*
180-
* If 'size' is a constant, the compiler will optimize this whole function
181-
* down to either a no-op or the addition of a constant to the value of '*p'.
182-
*
183-
* The 'p' pointer is absolutely needed to keep the proper advancing
184-
* further in memory to the proper offsets when allocating the struct along
185-
* with its embedded structs, as edac_device_alloc_ctl_info() does it
186-
* above, for example.
187-
*
188-
* At return, the pointer 'p' will be incremented to be used on a next call
189-
* to this function.
190-
*/
191-
void *edac_align_ptr(void **p, unsigned int size, int n_elems)
192-
{
193-
unsigned int align, r;
194-
void *ptr = *p;
195-
196-
*p += size * n_elems;
197-
198-
/*
199-
* 'p' can possibly be an unaligned item X such that sizeof(X) is
200-
* 'size'. Adjust 'p' so that its alignment is at least as
201-
* stringent as what the compiler would provide for X and return
202-
* the aligned result.
203-
* Here we assume that the alignment of a "long long" is the most
204-
* stringent alignment that the compiler will ever provide by default.
205-
* As far as I know, this is a reasonable assumption.
206-
*/
207-
if (size > sizeof(long))
208-
align = sizeof(long long);
209-
else if (size > sizeof(int))
210-
align = sizeof(long);
211-
else if (size > sizeof(short))
212-
align = sizeof(int);
213-
else if (size > sizeof(char))
214-
align = sizeof(short);
215-
else
216-
return ptr;
217-
218-
r = (unsigned long)ptr % align;
219-
220-
if (r == 0)
221-
return ptr;
222-
223-
*p += align - r;
224-
225-
return (void *)(((unsigned long)ptr) + align - r);
226-
}
227-
228173
static void _edac_mc_free(struct mem_ctl_info *mci)
229174
{
230175
put_device(&mci->dev);
@@ -257,6 +202,8 @@ static void mci_release(struct device *dev)
257202
}
258203
kfree(mci->csrows);
259204
}
205+
kfree(mci->pvt_info);
206+
kfree(mci->layers);
260207
kfree(mci);
261208
}
262209

@@ -392,9 +339,8 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
392339
{
393340
struct mem_ctl_info *mci;
394341
struct edac_mc_layer *layer;
395-
unsigned int idx, size, tot_dimms = 1;
342+
unsigned int idx, tot_dimms = 1;
396343
unsigned int tot_csrows = 1, tot_channels = 1;
397-
void *pvt, *ptr = NULL;
398344
bool per_rank = false;
399345

400346
if (WARN_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0))
@@ -416,41 +362,25 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
416362
per_rank = true;
417363
}
418364

419-
/* Figure out the offsets of the various items from the start of an mc
420-
* structure. We want the alignment of each item to be at least as
421-
* stringent as what the compiler would provide if we could simply
422-
* hardcode everything into a single struct.
423-
*/
424-
mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
425-
layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers);
426-
pvt = edac_align_ptr(&ptr, sz_pvt, 1);
427-
size = ((unsigned long)pvt) + sz_pvt;
428-
429-
edac_dbg(1, "allocating %u bytes for mci data (%d %s, %d csrows/channels)\n",
430-
size,
431-
tot_dimms,
432-
per_rank ? "ranks" : "dimms",
433-
tot_csrows * tot_channels);
434-
435-
mci = kzalloc(size, GFP_KERNEL);
436-
if (mci == NULL)
365+
mci = kzalloc(sizeof(struct mem_ctl_info), GFP_KERNEL);
366+
if (!mci)
437367
return NULL;
438368

369+
mci->layers = kcalloc(n_layers, sizeof(struct edac_mc_layer), GFP_KERNEL);
370+
if (!mci->layers)
371+
goto error;
372+
373+
mci->pvt_info = kzalloc(sz_pvt, GFP_KERNEL);
374+
if (!mci->pvt_info)
375+
goto error;
376+
439377
mci->dev.release = mci_release;
440378
device_initialize(&mci->dev);
441379

442-
/* Adjust pointers so they point within the memory we just allocated
443-
* rather than an imaginary chunk of memory located at address 0.
444-
*/
445-
layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer));
446-
pvt = sz_pvt ? (((char *)mci) + ((unsigned long)pvt)) : NULL;
447-
448380
/* setup index and various internal pointers */
449381
mci->mc_idx = mc_num;
450382
mci->tot_dimms = tot_dimms;
451-
mci->pvt_info = pvt;
452383
mci->n_layers = n_layers;
453-
mci->layers = layer;
454384
memcpy(mci->layers, layers, sizeof(*layer) * n_layers);
455385
mci->nr_csrows = tot_csrows;
456386
mci->num_cschannel = tot_channels;

drivers/edac/edac_module.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ extern void edac_device_reset_delay_period(struct edac_device_ctl_info
5959
*edac_dev, unsigned long value);
6060
extern void edac_mc_reset_delay_period(unsigned long value);
6161

62-
extern void *edac_align_ptr(void **p, unsigned size, int n_elems);
63-
6462
/*
6563
* EDAC debugfs functions
6664
*/

0 commit comments

Comments
 (0)