diff options
author | Arnd Bergmann <arnd.bergmann@de.ibm.com> | 2007-04-23 15:08:25 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@klappe.arndb.de> | 2007-04-23 15:18:58 -0400 |
commit | 6cf2179202cf706471777ad6ee5d0377d5990ab7 (patch) | |
tree | abe3c27de753d66f23f9a297864ec57af245eee9 /arch/powerpc | |
parent | d3764397d07b1e03943edfdcc3fb77af7bdac02b (diff) |
[POWERPC] spufs: fix memory leak on coredump
Dynamically allocated read/write buffer in spufs_arch_write_note() will
not be freed. Convert it to get_free_page at the same time.
Cc: Akinobu Mita <mita@fixstars.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/coredump.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c index 725e19561159..5d9ad5a0307b 100644 --- a/arch/powerpc/platforms/cell/spufs/coredump.c +++ b/arch/powerpc/platforms/cell/spufs/coredump.c | |||
@@ -169,12 +169,12 @@ static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i, | |||
169 | struct spu_context *ctx; | 169 | struct spu_context *ctx; |
170 | loff_t pos = 0; | 170 | loff_t pos = 0; |
171 | int sz, dfd, rc, total = 0; | 171 | int sz, dfd, rc, total = 0; |
172 | const int bufsz = 4096; | 172 | const int bufsz = PAGE_SIZE; |
173 | char *name; | 173 | char *name; |
174 | char fullname[80], *buf; | 174 | char fullname[80], *buf; |
175 | struct elf_note en; | 175 | struct elf_note en; |
176 | 176 | ||
177 | buf = kmalloc(bufsz, GFP_KERNEL); | 177 | buf = (void *)get_zeroed_page(GFP_KERNEL); |
178 | if (!buf) | 178 | if (!buf) |
179 | return; | 179 | return; |
180 | 180 | ||
@@ -187,9 +187,8 @@ static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i, | |||
187 | sz = spufs_coredump_read[i].size; | 187 | sz = spufs_coredump_read[i].size; |
188 | 188 | ||
189 | ctx = ctx_info->ctx; | 189 | ctx = ctx_info->ctx; |
190 | if (!ctx) { | 190 | if (!ctx) |
191 | return; | 191 | goto out; |
192 | } | ||
193 | 192 | ||
194 | sprintf(fullname, "SPU/%d/%s", dfd, name); | 193 | sprintf(fullname, "SPU/%d/%s", dfd, name); |
195 | en.n_namesz = strlen(fullname) + 1; | 194 | en.n_namesz = strlen(fullname) + 1; |
@@ -197,23 +196,25 @@ static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i, | |||
197 | en.n_type = NT_SPU; | 196 | en.n_type = NT_SPU; |
198 | 197 | ||
199 | if (!spufs_dump_write(file, &en, sizeof(en))) | 198 | if (!spufs_dump_write(file, &en, sizeof(en))) |
200 | return; | 199 | goto out; |
201 | if (!spufs_dump_write(file, fullname, en.n_namesz)) | 200 | if (!spufs_dump_write(file, fullname, en.n_namesz)) |
202 | return; | 201 | goto out; |
203 | if (!spufs_dump_seek(file, roundup((unsigned long)file->f_pos, 4))) | 202 | if (!spufs_dump_seek(file, roundup((unsigned long)file->f_pos, 4))) |
204 | return; | 203 | goto out; |
205 | 204 | ||
206 | do { | 205 | do { |
207 | rc = do_coredump_read(i, ctx, buf, bufsz, &pos); | 206 | rc = do_coredump_read(i, ctx, buf, bufsz, &pos); |
208 | if (rc > 0) { | 207 | if (rc > 0) { |
209 | if (!spufs_dump_write(file, buf, rc)) | 208 | if (!spufs_dump_write(file, buf, rc)) |
210 | return; | 209 | goto out; |
211 | total += rc; | 210 | total += rc; |
212 | } | 211 | } |
213 | } while (rc == bufsz && total < sz); | 212 | } while (rc == bufsz && total < sz); |
214 | 213 | ||
215 | spufs_dump_seek(file, roundup((unsigned long)file->f_pos | 214 | spufs_dump_seek(file, roundup((unsigned long)file->f_pos |
216 | - total + sz, 4)); | 215 | - total + sz, 4)); |
216 | out: | ||
217 | free_page((unsigned long)buf); | ||
217 | } | 218 | } |
218 | 219 | ||
219 | static void spufs_arch_write_notes(struct file *file) | 220 | static void spufs_arch_write_notes(struct file *file) |