Skip to content

Commit

Permalink
Merge tag 'please-pull-pstore' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…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"
  • Loading branch information
Linus Torvalds committed Jul 3, 2013
2 parents e39dfe5 + 0d83834 commit 04bbc8e
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 18 deletions.
20 changes: 14 additions & 6 deletions drivers/acpi/apei/erst.c
Original file line number Diff line number Diff line change
Expand Up @@ -1180,20 +1180,28 @@ static int __init erst_init(void)
if (!erst_erange.vaddr)
goto err_release_erange;

pr_info(ERST_PFX
"Error Record Serialization Table (ERST) support is initialized.\n");

buf = kmalloc(erst_erange.size, GFP_KERNEL);
spin_lock_init(&erst_info.buf_lock);
if (buf) {
erst_info.buf = buf + sizeof(struct cper_pstore_record);
erst_info.bufsize = erst_erange.size -
sizeof(struct cper_pstore_record);
if (pstore_register(&erst_info)) {
pr_info(ERST_PFX "Could not register with persistent store\n");
rc = pstore_register(&erst_info);
if (rc) {
if (rc != -EPERM)
pr_info(ERST_PFX
"Could not register with persistent store\n");
erst_info.buf = NULL;
erst_info.bufsize = 0;
kfree(buf);
}
}

pr_info(ERST_PFX
"Error Record Serialization Table (ERST) support is initialized.\n");
} else
pr_err(ERST_PFX
"Failed to allocate %lld bytes for persistent store error log\n",
erst_erange.size);

return 0;

Expand Down
9 changes: 6 additions & 3 deletions drivers/firmware/efi/efi-pstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,9 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
&entry->var.DataSize, entry->var.Data);
size = entry->var.DataSize;

*cb_data->buf = kmalloc(size, GFP_KERNEL);
*cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL);
if (*cb_data->buf == NULL)
return -ENOMEM;
memcpy(*cb_data->buf, entry->var.Data, size);
return size;
}

Expand Down Expand Up @@ -236,7 +235,11 @@ static __init int efivars_pstore_init(void)
efi_pstore_info.bufsize = 1024;
spin_lock_init(&efi_pstore_info.buf_lock);

pstore_register(&efi_pstore_info);
if (pstore_register(&efi_pstore_info)) {
kfree(efi_pstore_info.buf);
efi_pstore_info.buf = NULL;
efi_pstore_info.bufsize = 0;
}

return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions fs/pstore/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry)
if (p->psi->erase)
p->psi->erase(p->type, p->id, p->count,
dentry->d_inode->i_ctime, p->psi);
else
return -EPERM;

return simple_unlink(dir, dentry);
}
Expand Down
11 changes: 6 additions & 5 deletions fs/pstore/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,17 +239,15 @@ int pstore_register(struct pstore_info *psi)
{
struct module *owner = psi->owner;

if (backend && strcmp(backend, psi->name))
return -EPERM;

spin_lock(&pstore_lock);
if (psinfo) {
spin_unlock(&pstore_lock);
return -EBUSY;
}

if (backend && strcmp(backend, psi->name)) {
spin_unlock(&pstore_lock);
return -EINVAL;
}

if (!psi->write)
psi->write = pstore_write_compat;
psinfo = psi;
Expand All @@ -274,6 +272,9 @@ int pstore_register(struct pstore_info *psi)
add_timer(&pstore_timer);
}

pr_info("pstore: Registered %s as persistent store backend\n",
psi->name);

return 0;
}
EXPORT_SYMBOL_GPL(pstore_register);
Expand Down
2 changes: 0 additions & 2 deletions fs/pstore/ram.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,6 @@ static int ramoops_probe(struct platform_device *pdev)
goto fail_out;
}

if (!is_power_of_2(pdata->mem_size))
pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
if (!is_power_of_2(pdata->record_size))
pdata->record_size = rounddown_pow_of_two(pdata->record_size);
if (!is_power_of_2(pdata->console_size))
Expand Down
54 changes: 52 additions & 2 deletions fs/pstore/ram_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz)
}

/* increase and wrap the start pointer, returning the old value */
static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a)
{
int old;
int new;
Expand All @@ -62,7 +62,7 @@ static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
}

/* increase the size counter until it hits the max size */
static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a)
{
size_t old;
size_t new;
Expand All @@ -78,6 +78,53 @@ static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
} while (atomic_cmpxchg(&prz->buffer->size, old, new) != old);
}

static DEFINE_RAW_SPINLOCK(buffer_lock);

/* increase and wrap the start pointer, returning the old value */
static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
{
int old;
int new;
unsigned long flags;

raw_spin_lock_irqsave(&buffer_lock, flags);

old = atomic_read(&prz->buffer->start);
new = old + a;
while (unlikely(new > prz->buffer_size))
new -= prz->buffer_size;
atomic_set(&prz->buffer->start, new);

raw_spin_unlock_irqrestore(&buffer_lock, flags);

return old;
}

/* increase the size counter until it hits the max size */
static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a)
{
size_t old;
size_t new;
unsigned long flags;

raw_spin_lock_irqsave(&buffer_lock, flags);

old = atomic_read(&prz->buffer->size);
if (old == prz->buffer_size)
goto exit;

new = old + a;
if (new > prz->buffer_size)
new = prz->buffer_size;
atomic_set(&prz->buffer->size, new);

exit:
raw_spin_unlock_irqrestore(&buffer_lock, flags);
}

static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic;
static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic;

static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
uint8_t *data, size_t len, uint8_t *ecc)
{
Expand Down Expand Up @@ -372,6 +419,9 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size)
return NULL;
}

buffer_start_add = buffer_start_add_locked;
buffer_size_add = buffer_size_add_locked;

return ioremap(start, size);
}

Expand Down

0 comments on commit 04bbc8e

Please sign in to comment.