summaryrefslogtreecommitdiffstats
path: root/drivers/edac
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-08-27 11:36:23 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-30 14:56:59 -0300
commit85580ea4f72ce08e4d9140a3bb22806185a0bba9 (patch)
tree47bda43b1f4c3f60afa17114df8f4f8081e2f2a2 /drivers/edac
parent28c2ce7c8b275a8e6950bacb2dbad70b36a2996b (diff)
i7300_edac: pre-allocate a buffer used to prepare err messages
Instead of dynamically allocating a buffer for it where needed, just allocate it once. As we'll use the same buffer also during fatal and non-fatal errors, is is very risky to dynamically allocate it during an error. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r--drivers/edac/i7300_edac.c41
1 files changed, 24 insertions, 17 deletions
diff --git a/drivers/edac/i7300_edac.c b/drivers/edac/i7300_edac.c
index a4f47fda078..4c239ce6986 100644
--- a/drivers/edac/i7300_edac.c
+++ b/drivers/edac/i7300_edac.c
@@ -306,6 +306,9 @@ struct i7300_pvt {
/* DIMM information matrix, allocating architecture maximums */
struct i7300_dimm_info dimm_info[MAX_SLOTS][MAX_CHANNELS];
+
+ /* Temporary buffer for use when preparing error messages */
+ char *tmp_prt_buffer;
};
/* FIXME: Why do we need to have this static? */
@@ -611,17 +614,12 @@ static int decode_mtr(struct i7300_pvt *pvt,
static void print_dimm_size(struct i7300_pvt *pvt)
{
struct i7300_dimm_info *dinfo;
- char *p, *mem_buffer;
+ char *p;
int space, n;
int channel, slot;
space = PAGE_SIZE;
- mem_buffer = p = kmalloc(space, GFP_KERNEL);
- if (p == NULL) {
- i7300_printk(KERN_ERR, "MC: %s:%s() kmalloc() failed\n",
- __FILE__, __func__);
- return;
- }
+ p = pvt->tmp_prt_buffer;
n = snprintf(p, space, " ");
p += n;
@@ -631,15 +629,15 @@ static void print_dimm_size(struct i7300_pvt *pvt)
p += n;
space -= n;
}
- debugf2("%s\n", mem_buffer);
- p = mem_buffer;
+ debugf2("%s\n", pvt->tmp_prt_buffer);
+ p = pvt->tmp_prt_buffer;
space = PAGE_SIZE;
n = snprintf(p, space, "-------------------------------"
"------------------------------");
p += n;
space -= n;
- debugf2("%s\n", mem_buffer);
- p = mem_buffer;
+ debugf2("%s\n", pvt->tmp_prt_buffer);
+ p = pvt->tmp_prt_buffer;
space = PAGE_SIZE;
for (slot = 0; slot < MAX_SLOTS; slot++) {
@@ -654,8 +652,8 @@ static void print_dimm_size(struct i7300_pvt *pvt)
space -= n;
}
- debugf2("%s\n", mem_buffer);
- p = mem_buffer;
+ debugf2("%s\n", pvt->tmp_prt_buffer);
+ p = pvt->tmp_prt_buffer;
space = PAGE_SIZE;
}
@@ -663,11 +661,9 @@ static void print_dimm_size(struct i7300_pvt *pvt)
"------------------------------");
p += n;
space -= n;
- debugf2("%s\n", mem_buffer);
- p = mem_buffer;
+ debugf2("%s\n", pvt->tmp_prt_buffer);
+ p = pvt->tmp_prt_buffer;
space = PAGE_SIZE;
-
- kfree(mem_buffer);
}
/*
@@ -978,6 +974,12 @@ static int i7300_probe1(struct pci_dev *pdev, int dev_idx)
pvt = mci->pvt_info;
pvt->pci_dev_16_0_fsb_ctlr = pdev; /* Record this device in our private */
+ pvt->tmp_prt_buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!pvt->tmp_prt_buffer) {
+ edac_mc_free(mci);
+ return -ENOMEM;
+ }
+
/* 'get' the pci devices we want to reserve for our use */
if (i7300_get_devices(mci, dev_idx))
goto fail0;
@@ -1038,6 +1040,7 @@ fail1:
i7300_put_devices(mci);
fail0:
+ kfree(pvt->tmp_prt_buffer);
edac_mc_free(mci);
return -ENODEV;
}
@@ -1072,6 +1075,7 @@ static int __devinit i7300_init_one(struct pci_dev *pdev,
static void __devexit i7300_remove_one(struct pci_dev *pdev)
{
struct mem_ctl_info *mci;
+ char *tmp;
debugf0(__FILE__ ": %s()\n", __func__);
@@ -1082,9 +1086,12 @@ static void __devexit i7300_remove_one(struct pci_dev *pdev)
if (!mci)
return;
+ tmp = ((struct i7300_pvt *)mci->pvt_info)->tmp_prt_buffer;
+
/* retrieve references to resources, and free those resources */
i7300_put_devices(mci);
+ kfree(tmp);
edac_mc_free(mci);
}