Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux

Pull pstore update from Tony Luck:
"Fixes for pstore for 3.11 merge window"

* tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux:
efivars: If pstore_register fails, free unneeded pstore buffer
acpi: Eliminate console msg if pstore.backend excludes ERST
pstore: Return unique error if backend registration excluded by kernel param
pstore: Fail to unlink if a driver has not defined pstore_erase
pstore/ram: remove the power of buffer size limitation
pstore/ram: avoid atomic accesses for ioremapped regions
efi, pstore: Cocci spatch "memdup.spatch"

+80 -18
+14 -6
drivers/acpi/apei/erst.c
··· 1180 1180 if (!erst_erange.vaddr) 1181 1181 goto err_release_erange; 1182 1182 1183 + pr_info(ERST_PFX 1184 + "Error Record Serialization Table (ERST) support is initialized.\n"); 1185 + 1183 1186 buf = kmalloc(erst_erange.size, GFP_KERNEL); 1184 1187 spin_lock_init(&erst_info.buf_lock); 1185 1188 if (buf) { 1186 1189 erst_info.buf = buf + sizeof(struct cper_pstore_record); 1187 1190 erst_info.bufsize = erst_erange.size - 1188 1191 sizeof(struct cper_pstore_record); 1189 - if (pstore_register(&erst_info)) { 1190 - pr_info(ERST_PFX "Could not register with persistent store\n"); 1192 + rc = pstore_register(&erst_info); 1193 + if (rc) { 1194 + if (rc != -EPERM) 1195 + pr_info(ERST_PFX 1196 + "Could not register with persistent store\n"); 1197 + erst_info.buf = NULL; 1198 + erst_info.bufsize = 0; 1191 1199 kfree(buf); 1192 1200 } 1193 - } 1194 - 1195 - pr_info(ERST_PFX 1196 - "Error Record Serialization Table (ERST) support is initialized.\n"); 1201 + } else 1202 + pr_err(ERST_PFX 1203 + "Failed to allocate %lld bytes for persistent store error log\n", 1204 + erst_erange.size); 1197 1205 1198 1206 return 0; 1199 1207
+6 -3
drivers/firmware/efi/efi-pstore.c
··· 79 79 &entry->var.DataSize, entry->var.Data); 80 80 size = entry->var.DataSize; 81 81 82 - *cb_data->buf = kmalloc(size, GFP_KERNEL); 82 + *cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL); 83 83 if (*cb_data->buf == NULL) 84 84 return -ENOMEM; 85 - memcpy(*cb_data->buf, entry->var.Data, size); 86 85 return size; 87 86 } 88 87 ··· 235 236 efi_pstore_info.bufsize = 1024; 236 237 spin_lock_init(&efi_pstore_info.buf_lock); 237 238 238 - pstore_register(&efi_pstore_info); 239 + if (pstore_register(&efi_pstore_info)) { 240 + kfree(efi_pstore_info.buf); 241 + efi_pstore_info.buf = NULL; 242 + efi_pstore_info.bufsize = 0; 243 + } 239 244 240 245 return 0; 241 246 }
+2
fs/pstore/inode.c
··· 178 178 if (p->psi->erase) 179 179 p->psi->erase(p->type, p->id, p->count, 180 180 dentry->d_inode->i_ctime, p->psi); 181 + else 182 + return -EPERM; 181 183 182 184 return simple_unlink(dir, dentry); 183 185 }
+6 -5
fs/pstore/platform.c
··· 239 239 { 240 240 struct module *owner = psi->owner; 241 241 242 + if (backend && strcmp(backend, psi->name)) 243 + return -EPERM; 244 + 242 245 spin_lock(&pstore_lock); 243 246 if (psinfo) { 244 247 spin_unlock(&pstore_lock); 245 248 return -EBUSY; 246 - } 247 - 248 - if (backend && strcmp(backend, psi->name)) { 249 - spin_unlock(&pstore_lock); 250 - return -EINVAL; 251 249 } 252 250 253 251 if (!psi->write) ··· 271 273 msecs_to_jiffies(pstore_update_ms); 272 274 add_timer(&pstore_timer); 273 275 } 276 + 277 + pr_info("pstore: Registered %s as persistent store backend\n", 278 + psi->name); 274 279 275 280 return 0; 276 281 }
-2
fs/pstore/ram.c
··· 399 399 goto fail_out; 400 400 } 401 401 402 - if (!is_power_of_2(pdata->mem_size)) 403 - pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); 404 402 if (!is_power_of_2(pdata->record_size)) 405 403 pdata->record_size = rounddown_pow_of_two(pdata->record_size); 406 404 if (!is_power_of_2(pdata->console_size))
+52 -2
fs/pstore/ram_core.c
··· 46 46 } 47 47 48 48 /* increase and wrap the start pointer, returning the old value */ 49 - static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) 49 + static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a) 50 50 { 51 51 int old; 52 52 int new; ··· 62 62 } 63 63 64 64 /* increase the size counter until it hits the max size */ 65 - static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a) 65 + static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a) 66 66 { 67 67 size_t old; 68 68 size_t new; ··· 77 77 new = prz->buffer_size; 78 78 } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); 79 79 } 80 + 81 + static DEFINE_RAW_SPINLOCK(buffer_lock); 82 + 83 + /* increase and wrap the start pointer, returning the old value */ 84 + static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) 85 + { 86 + int old; 87 + int new; 88 + unsigned long flags; 89 + 90 + raw_spin_lock_irqsave(&buffer_lock, flags); 91 + 92 + old = atomic_read(&prz->buffer->start); 93 + new = old + a; 94 + while (unlikely(new > prz->buffer_size)) 95 + new -= prz->buffer_size; 96 + atomic_set(&prz->buffer->start, new); 97 + 98 + raw_spin_unlock_irqrestore(&buffer_lock, flags); 99 + 100 + return old; 101 + } 102 + 103 + /* increase the size counter until it hits the max size */ 104 + static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a) 105 + { 106 + size_t old; 107 + size_t new; 108 + unsigned long flags; 109 + 110 + raw_spin_lock_irqsave(&buffer_lock, flags); 111 + 112 + old = atomic_read(&prz->buffer->size); 113 + if (old == prz->buffer_size) 114 + goto exit; 115 + 116 + new = old + a; 117 + if (new > prz->buffer_size) 118 + new = prz->buffer_size; 119 + atomic_set(&prz->buffer->size, new); 120 + 121 + exit: 122 + raw_spin_unlock_irqrestore(&buffer_lock, flags); 123 + } 124 + 125 + static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic; 126 + static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic; 80 127 81 128 static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, 82 129 uint8_t *data, size_t len, uint8_t *ecc) ··· 418 371 (unsigned long long)size, (unsigned long long)start); 419 372 return NULL; 420 373 } 374 + 375 + buffer_start_add = buffer_start_add_locked; 376 + buffer_size_add = buffer_size_add_locked; 421 377 422 378 return ioremap(start, size); 423 379 }