anolis: pstore: add ttyprobe frontend

ANBZ: #4183

Provide a pstore frontend which can log all messages that are send
to tty drivers when there are some problems with drivers or there
is no access to serial ports.

Using pmsg requires us to redirect the output of the user state.
When we need to globally view the serial output of various processes,
it is tedious to redirect the output of each process. We think pmsg is
more suitable for targeted viewing of certain processes' output, and
we also need a tool that can quickly do a global view so that we can
get user-state printed data if the tty driver is working abnormally or
if we don't have serial access.

Signed-off-by: Yuanhe Shu <xiangzao@linux.alibaba.com>
Signed-off-by: Xingrui Yi <yixingrui@linux.alibaba.com>
Reviewed-by: Xunlei Pang <xlpang@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/1231
This commit is contained in:
Yuanhe Shu 2023-02-24 18:09:19 +08:00 committed by 小龙
parent 51dba0bbc5
commit 74aedbfb46
14 changed files with 210 additions and 3 deletions

View File

@ -587,6 +587,7 @@ static ssize_t process_output_block(struct tty_struct *tty,
}
}
break_out:
pstore_start_ttyprobe(buf, i);
i = tty->ops->write(tty, buf, i);
mutex_unlock(&ldata->output_lock);

View File

@ -138,6 +138,17 @@ config PSTORE_FTRACE
If unsure, say N.
config PSTORE_TTYPROBE
bool "Log tty messages"
depends on PSTORE
help
When the option is enabled, pstore will log all messages send
to tty drivers, even if no oops or panic happened. It can be
useful to log serial information when there is no access to
serial ports or the tty drivers work abnormally.
If unsure, say N.
config PSTORE_RAM
tristate "Log panic/oops to a RAM buffer"
depends on PSTORE
@ -263,3 +274,15 @@ config PSTORE_BLK_FTRACE_SIZE
NOTE that, both Kconfig and module parameters can configure
pstore/blk, but module parameters have priority over Kconfig.
config PSTORE_BLK_TTYPROBE_SIZE
int "Size in Kbytes of ttyprobe log to store"
depends on PSTORE_BLK
depends on PSTORE_TTYPROBE
default 64
help
This just sets size of ttyprobe log (ttyprobe_size) for pstore/blk. The
size is in KB and must be a multiple of 4.
NOTE that, both Kconfig and module parameters can configure
pstore/blk, but module parameters have priority over Kconfig.

View File

@ -10,6 +10,8 @@ pstore-$(CONFIG_PSTORE_FTRACE) += ftrace.o
pstore-$(CONFIG_PSTORE_PMSG) += pmsg.o
pstore-$(CONFIG_PSTORE_TTYPROBE) += ttyprobe.o
ramoops-objs += ram.o ram_core.o
obj-$(CONFIG_PSTORE_RAM) += ramoops.o

View File

@ -51,6 +51,14 @@ static long ftrace_size = -1;
module_param(ftrace_size, long, 0400);
MODULE_PARM_DESC(ftrace_size, "ftrace size in kbytes");
#if IS_ENABLED(CONFIG_PSTORE_TTYPROBE)
static long ttyprobe_size = CONFIG_PSTORE_BLK_TTYPROBE_SIZE;
#else
static long ttyprobe_size = -1;
#endif
module_param(ttyprobe_size, long, 0400);
MODULE_PARM_DESC(ttyprobe_size, "ttyprobe_size size in kbytes");
static bool best_effort;
module_param(best_effort, bool, 0400);
MODULE_PARM_DESC(best_effort, "use best effort to write (i.e. do not require storage driver pstore support, default: off)");
@ -144,6 +152,7 @@ static int __register_pstore_device(struct pstore_device_info *dev)
verify_size(pmsg_size, 4096, dev->flags & PSTORE_FLAGS_PMSG);
verify_size(console_size, 4096, dev->flags & PSTORE_FLAGS_CONSOLE);
verify_size(ftrace_size, 4096, dev->flags & PSTORE_FLAGS_FTRACE);
verify_size(ttyprobe_size, 4096, dev->flags & PSTORE_FLAGS_TTYPROBE);
#undef verify_size
pstore_zone_info->total_size = dev->total_size;
@ -476,6 +485,7 @@ int pstore_blk_get_config(struct pstore_blk_config *info)
info->pmsg_size = check_size(pmsg_size, 4096);
info->ftrace_size = check_size(ftrace_size, 4096);
info->console_size = check_size(console_size, 4096);
info->ttyprobe_size = check_size(ttyprobe_size, 4096);
return 0;
}

View File

@ -34,6 +34,14 @@ static inline void pstore_register_pmsg(void) {}
static inline void pstore_unregister_pmsg(void) {}
#endif
#ifdef CONFIG_PSTORE_TTYPROBE
extern void pstore_register_ttyprobe(void);
extern void pstore_unregister_ttyprobe(void);
#else
static inline void pstore_register_ttyprobe(void) {}
static inline void pstore_unregister_ttyprobe(void) {}
#endif
extern struct pstore_backends *psback;
extern void pstore_set_kmsg_bytes(int);

View File

@ -58,6 +58,7 @@ static const char * const pstore_type_names[] = {
"powerpc-common",
"pmsg",
"powerpc-opal",
"ttyprobe",
};
static int pstore_new_entry;
@ -652,6 +653,8 @@ int pstore_register(struct pstore_info *psi)
pstore_register_ftrace();
if (psi->flags & PSTORE_FLAGS_PMSG && !psback->front_cnt[PSTORE_TYPE_PMSG]++)
pstore_register_pmsg();
if (psi->flags & PSTORE_FLAGS_TTYPROBE && !psback->front_cnt[PSTORE_TYPE_TTYPROBE]++)
pstore_register_ttyprobe();
/* Start watching for new records, if desired. */
pstore_timer_kick();
@ -681,6 +684,8 @@ void pstore_unregister(struct pstore_info *psi)
pstore_unregister_console();
if (psi->flags & PSTORE_FLAGS_DMESG && !--psback->front_cnt[PSTORE_TYPE_DMESG])
pstore_unregister_kmsg();
if (psi->flags & PSTORE_FLAGS_TTYPROBE && !--psback->front_cnt[PSTORE_TYPE_TTYPROBE])
pstore_unregister_ttyprobe();
/* Stop timer and make sure all work has finished. */
del_timer_sync(&pstore_timer);

View File

@ -43,6 +43,10 @@ static ulong ramoops_pmsg_size = MIN_MEM_SIZE;
module_param_named(pmsg_size, ramoops_pmsg_size, ulong, 0400);
MODULE_PARM_DESC(pmsg_size, "size of user space message log");
static ulong ramoops_ttyprobe_size = MIN_MEM_SIZE;
module_param_named(ttyprobe_size, ramoops_ttyprobe_size, ulong, 0400);
MODULE_PARM_DESC(ttyprobe_size, "size of ttyprobe message log");
static unsigned long long mem_address;
module_param_hw(mem_address, ullong, other, 0400);
MODULE_PARM_DESC(mem_address,
@ -80,6 +84,7 @@ struct ramoops_context {
struct persistent_ram_zone *cprz; /* Console zone */
struct persistent_ram_zone **fprzs; /* Ftrace zones */
struct persistent_ram_zone *mprz; /* PMSG zone */
struct persistent_ram_zone *tprz; /* TTYPROBE zone */
phys_addr_t phys_addr;
unsigned long size;
unsigned int memtype;
@ -87,6 +92,7 @@ struct ramoops_context {
size_t console_size;
size_t ftrace_size;
size_t pmsg_size;
size_t ttyprobe_size;
u32 flags;
struct persistent_ram_ecc_info ecc_info;
unsigned int max_dump_cnt;
@ -97,6 +103,7 @@ struct ramoops_context {
unsigned int max_ftrace_cnt;
unsigned int ftrace_read_cnt;
unsigned int pmsg_read_cnt;
unsigned int ttyprobe_read_cnt;
struct pstore_info pstore;
};
@ -110,6 +117,7 @@ static int ramoops_pstore_open(struct pstore_info *psi)
cxt->console_read_cnt = 0;
cxt->ftrace_read_cnt = 0;
cxt->pmsg_read_cnt = 0;
cxt->ttyprobe_read_cnt = 0;
return 0;
}
@ -213,6 +221,9 @@ static ssize_t ramoops_pstore_read(struct pstore_record *record)
if (!prz_ok(prz) && !cxt->pmsg_read_cnt++)
prz = ramoops_get_next_prz(&cxt->mprz, 0 /* single */, record);
if (!prz_ok(prz) && !cxt->ttyprobe_read_cnt++)
prz = ramoops_get_next_prz(&cxt->tprz, 0 /* single */, record);
/* ftrace is last since it may want to dynamically allocate memory. */
if (!prz_ok(prz)) {
if (!(cxt->flags & RAMOOPS_FLAG_FTRACE_PER_CPU) &&
@ -334,6 +345,11 @@ static int notrace ramoops_pstore_write(struct pstore_record *record)
} else if (record->type == PSTORE_TYPE_PMSG) {
pr_warn_ratelimited("PMSG shouldn't call %s\n", __func__);
return -EINVAL;
} else if (record->type == PSTORE_TYPE_TTYPROBE) {
if (!cxt->tprz)
return -ENOMEM;
persistent_ram_write(cxt->tprz, record->buf, record->size);
return 0;
}
if (record->type != PSTORE_TYPE_DMESG)
@ -425,6 +441,9 @@ static int ramoops_pstore_erase(struct pstore_record *record)
case PSTORE_TYPE_PMSG:
prz = cxt->mprz;
break;
case PSTORE_TYPE_TTYPROBE:
prz = cxt->tprz;
break;
default:
return -EINVAL;
}
@ -670,6 +689,7 @@ static int ramoops_parse_dt(struct platform_device *pdev,
parse_u32("console-size", pdata->console_size, 0);
parse_u32("ftrace-size", pdata->ftrace_size, 0);
parse_u32("pmsg-size", pdata->pmsg_size, 0);
parse_u32("ttyprobe-size", pdata->ttyprobe_size, 0);
parse_u32("ecc-size", pdata->ecc_info.ecc_size, 0);
parse_u32("flags", pdata->flags, 0);
parse_u32("max-reason", pdata->max_reason, pdata->max_reason);
@ -690,9 +710,10 @@ static int ramoops_parse_dt(struct platform_device *pdev,
parent_node = of_get_parent(of_node);
if (!of_node_name_eq(parent_node, "reserved-memory") &&
!pdata->console_size && !pdata->ftrace_size &&
!pdata->pmsg_size && !pdata->ecc_info.ecc_size) {
!pdata->pmsg_size && !pdata->ttyprobe_size && !pdata->ecc_info.ecc_size) {
pdata->console_size = pdata->record_size;
pdata->pmsg_size = pdata->record_size;
pdata->ttyprobe_size = pdata->record_size;
}
of_node_put(parent_node);
@ -748,6 +769,8 @@ static int ramoops_probe(struct platform_device *pdev)
pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size);
if (pdata->pmsg_size && !is_power_of_2(pdata->pmsg_size))
pdata->pmsg_size = rounddown_pow_of_two(pdata->pmsg_size);
if (pdata->ttyprobe_size && !is_power_of_2(pdata->ttyprobe_size))
pdata->ttyprobe_size = rounddown_pow_of_two(pdata->ttyprobe_size);
cxt->size = pdata->mem_size;
cxt->phys_addr = pdata->mem_address;
@ -756,13 +779,14 @@ static int ramoops_probe(struct platform_device *pdev)
cxt->console_size = pdata->console_size;
cxt->ftrace_size = pdata->ftrace_size;
cxt->pmsg_size = pdata->pmsg_size;
cxt->ttyprobe_size = pdata->ttyprobe_size;
cxt->flags = pdata->flags;
cxt->ecc_info = pdata->ecc_info;
paddr = cxt->phys_addr;
dump_mem_sz = cxt->size - cxt->console_size - cxt->ftrace_size
- cxt->pmsg_size;
- cxt->pmsg_size - cxt->ttyprobe_size;
err = ramoops_init_przs("dmesg", dev, cxt, &cxt->dprzs, &paddr,
dump_mem_sz, cxt->record_size,
&cxt->max_dump_cnt, 0, 0);
@ -790,6 +814,11 @@ static int ramoops_probe(struct platform_device *pdev)
if (err)
goto fail_init_mprz;
err = ramoops_init_prz("ttyprobe", dev, cxt, &cxt->tprz, &paddr,
cxt->ttyprobe_size, 0);
if (err)
goto fail_init_tprz;
cxt->pstore.data = cxt;
/*
* Prepare frontend flags based on which areas are initialized.
@ -808,6 +837,8 @@ static int ramoops_probe(struct platform_device *pdev)
cxt->pstore.flags |= PSTORE_FLAGS_FTRACE;
if (cxt->pmsg_size)
cxt->pstore.flags |= PSTORE_FLAGS_PMSG;
if (cxt->ttyprobe_size)
cxt->pstore.flags |= PSTORE_FLAGS_TTYPROBE;
/*
* Since bufsize is only used for dmesg crash dumps, it
@ -841,6 +872,7 @@ static int ramoops_probe(struct platform_device *pdev)
ramoops_console_size = pdata->console_size;
ramoops_pmsg_size = pdata->pmsg_size;
ramoops_ftrace_size = pdata->ftrace_size;
ramoops_ttyprobe_size = pdata->ttyprobe_size;
pr_info("using 0x%lx@0x%llx, ecc: %d\n",
cxt->size, (unsigned long long)cxt->phys_addr,
@ -852,6 +884,8 @@ fail_buf:
kfree(cxt->pstore.buf);
fail_clear:
cxt->pstore.bufsize = 0;
persistent_ram_free(cxt->tprz);
fail_init_tprz:
persistent_ram_free(cxt->mprz);
fail_init_mprz:
fail_init_fprz:
@ -872,6 +906,7 @@ static int ramoops_remove(struct platform_device *pdev)
cxt->pstore.bufsize = 0;
persistent_ram_free(cxt->mprz);
persistent_ram_free(cxt->tprz);
persistent_ram_free(cxt->cprz);
ramoops_free_przs(cxt);
@ -920,6 +955,7 @@ static void __init ramoops_register_dummy(void)
pdata.console_size = ramoops_console_size;
pdata.ftrace_size = ramoops_ftrace_size;
pdata.pmsg_size = ramoops_pmsg_size;
pdata.ttyprobe_size = ramoops_ttyprobe_size;
/* If "max_reason" is set, its value has priority over "dump_oops". */
if (ramoops_max_reason >= 0)
pdata.max_reason = ramoops_max_reason;

70
fs/pstore/ttyprobe.c Normal file
View File

@ -0,0 +1,70 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Provide a pstore frontend which can log all messages that are send
* to tty drivers when there are some problems with drivers or there
* is no access to serial ports.
*/
#include <linux/kernel.h>
#include <linux/kprobes.h>
#include <linux/console.h>
#include <linux/slab.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include "internal.h"
static DEFINE_MUTEX(ttymsg_lock);
#define TTYPROBE_NAME "ttyprobe"
#undef pr_fmt
#define pr_fmt(fmt) TTYPROBE_NAME ": " fmt
#define PSTORE_TTYPROBE_REGISTERED 1
#define PSTORE_TTYPROBE_UNREGISTERED 0
bool pstore_ttyprobe_status = PSTORE_TTYPROBE_UNREGISTERED;
static void do_write_ttymsg(const unsigned char *buf, int count,
struct pstore_info *psinfo)
{
struct pstore_record record, newline;
char *lbreak = "\n";
pstore_record_init(&record, psinfo);
record.type = PSTORE_TYPE_TTYPROBE;
record.size = count;
record.buf = (char *)buf;
mutex_lock(&ttymsg_lock);
psinfo->write(&record);
// add newline character for reading
pstore_record_init(&newline, psinfo);
newline.type = PSTORE_TYPE_TTYPROBE;
newline.size = strlen(lbreak);
newline.buf = lbreak;
psinfo->write(&newline);
mutex_unlock(&ttymsg_lock);
}
void pstore_register_ttyprobe(void)
{
pstore_ttyprobe_status = PSTORE_TTYPROBE_REGISTERED;
}
void pstore_start_ttyprobe(const unsigned char *buf, int count)
{
struct pstore_info_list *entry;
if (pstore_ttyprobe_status == PSTORE_TTYPROBE_UNREGISTERED)
return;
rcu_read_lock();
list_for_each_entry_rcu(entry, &psback->list_entry, list)
if (entry->psi->flags & PSTORE_FLAGS_TTYPROBE)
do_write_ttymsg(buf, count, entry->psi);
rcu_read_unlock();
}
void pstore_unregister_ttyprobe(void)
{
pstore_ttyprobe_status = PSTORE_TTYPROBE_UNREGISTERED;
}

View File

@ -93,6 +93,7 @@ struct pstore_zone {
* @ppsz: pmsg storage zone
* @cpsz: console storage zone
* @fpszs: ftrace storage zones
* @tpsz: ttyprobe storage zone
* @kmsg_max_cnt: max count of @kpszs
* @kmsg_read_cnt: counter of total read kmsg dumps
* @kmsg_write_cnt: counter of total kmsg dump writes
@ -100,6 +101,7 @@ struct pstore_zone {
* @console_read_cnt: counter of total read console zone
* @ftrace_max_cnt: max count of @fpszs
* @ftrace_read_cnt: counter of max read ftrace zone
* @ttyprobe_read_cnt: counter of total read ttyprobe zone
* @oops_counter: counter of oops dumps
* @panic_counter: counter of panic dumps
* @recovered: whether finished recovering data from storage
@ -113,6 +115,7 @@ struct psz_context {
struct pstore_zone *ppsz;
struct pstore_zone *cpsz;
struct pstore_zone **fpszs;
struct pstore_zone *tpsz;
unsigned int kmsg_max_cnt;
unsigned int kmsg_read_cnt;
unsigned int kmsg_write_cnt;
@ -120,6 +123,7 @@ struct psz_context {
unsigned int console_read_cnt;
unsigned int ftrace_max_cnt;
unsigned int ftrace_read_cnt;
unsigned int ttyprobe_read_cnt;
/*
* These counters should be calculated during recovery.
* It records the oops/panic times after crashes rather than boots.
@ -325,6 +329,8 @@ static void psz_flush_all_dirty_zones(struct work_struct *work)
ret |= psz_flush_dirty_zones(cxt->kpszs, cxt->kmsg_max_cnt);
if (cxt->fpszs)
ret |= psz_flush_dirty_zones(cxt->fpszs, cxt->ftrace_max_cnt);
if (cxt->tpsz)
ret |= psz_flush_dirty_zone(cxt->tpsz);
if (ret && cxt->pstore_zone_info)
schedule_delayed_work(&psz_cleaner, msecs_to_jiffies(1000));
}
@ -617,6 +623,10 @@ static inline int psz_recovery(struct psz_context *cxt)
if (ret)
goto out;
ret = psz_recover_zone(cxt, cxt->tpsz);
if (ret)
goto out;
ret = psz_recover_zones(cxt, cxt->fpszs, cxt->ftrace_max_cnt);
out:
@ -637,6 +647,7 @@ static int psz_pstore_open(struct pstore_info *psi)
cxt->pmsg_read_cnt = 0;
cxt->console_read_cnt = 0;
cxt->ftrace_read_cnt = 0;
cxt->ttyprobe_read_cnt = 0;
return 0;
}
@ -713,6 +724,8 @@ static int psz_pstore_erase(struct pstore_record *record)
if (record->id >= cxt->ftrace_max_cnt)
return -EINVAL;
return psz_record_erase(cxt, cxt->fpszs[record->id]);
case PSTORE_TYPE_TTYPROBE:
return psz_record_erase(cxt, cxt->tpsz);
default: return -EINVAL;
}
}
@ -891,6 +904,8 @@ static int notrace psz_pstore_write(struct pstore_record *record)
return psz_record_write(cxt->cpsz, record);
case PSTORE_TYPE_PMSG:
return psz_record_write(cxt->ppsz, record);
case PSTORE_TYPE_TTYPROBE:
return psz_record_write(cxt->tpsz, record);
case PSTORE_TYPE_FTRACE: {
int zonenum = smp_processor_id();
@ -935,6 +950,13 @@ static struct pstore_zone *psz_read_next_zone(struct psz_context *cxt)
return zone;
}
if (cxt->ttyprobe_read_cnt == 0) {
cxt->ttyprobe_read_cnt++;
zone = cxt->tpsz;
if (psz_old_ok(zone))
return zone;
}
return NULL;
}
@ -1081,6 +1103,7 @@ next_zone:
readop = psz_ftrace_read;
break;
case PSTORE_TYPE_CONSOLE:
case PSTORE_TYPE_TTYPROBE:
case PSTORE_TYPE_PMSG:
readop = psz_record_read;
break;
@ -1145,6 +1168,8 @@ static void psz_free_all_zones(struct psz_context *cxt)
psz_free_zone(&cxt->cpsz);
if (cxt->fpszs)
psz_free_zones(&cxt->fpszs, &cxt->ftrace_max_cnt);
if (cxt->tpsz)
psz_free_zone(&cxt->tpsz);
}
static struct pstore_zone *psz_init_zone(enum pstore_type_id type,
@ -1255,6 +1280,15 @@ static int psz_alloc_zones(struct psz_context *cxt)
goto free_out;
}
off_size += info->ttyprobe_size;
cxt->tpsz = psz_init_zone(PSTORE_TYPE_TTYPROBE, &off,
info->ttyprobe_size);
if (IS_ERR(cxt->tpsz)) {
err = PTR_ERR(cxt->tpsz);
cxt->tpsz = NULL;
goto free_out;
}
off_size += info->ftrace_size;
cxt->fpszs = psz_init_zones(PSTORE_TYPE_FTRACE, &off,
info->ftrace_size,
@ -1301,7 +1335,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
}
if (!info->kmsg_size && !info->pmsg_size && !info->console_size &&
!info->ftrace_size) {
!info->ftrace_size && !info->ttyprobe_size) {
pr_warn("at least one record size must be non-zero\n");
return -EINVAL;
}
@ -1326,6 +1360,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
check_size(pmsg_size, SECTOR_SIZE);
check_size(console_size, SECTOR_SIZE);
check_size(ftrace_size, SECTOR_SIZE);
check_size(ttyprobe_size, SECTOR_SIZE);
#undef check_size
@ -1354,6 +1389,7 @@ int register_pstore_zone(struct pstore_zone_info *info)
pr_debug("\tpmsg size : %ld Bytes\n", info->pmsg_size);
pr_debug("\tconsole size : %ld Bytes\n", info->console_size);
pr_debug("\tftrace size : %ld Bytes\n", info->ftrace_size);
pr_debug("\tttyprobe size : %ld Bytes\n", info->ttyprobe_size);
err = psz_alloc_zones(cxt);
if (err) {
@ -1395,6 +1431,10 @@ int register_pstore_zone(struct pstore_zone_info *info)
cxt->pstore.flags |= PSTORE_FLAGS_FTRACE;
pr_cont(" ftrace");
}
if (info->ttyprobe_size) {
cxt->pstore.flags |= PSTORE_FLAGS_TTYPROBE;
pr_cont(" ttyprobe");
}
pr_cont("\n");
err = pstore_register(&cxt->pstore);

View File

@ -38,6 +38,7 @@ enum pstore_type_id {
PSTORE_TYPE_PPC_COMMON = 6,
PSTORE_TYPE_PMSG = 7,
PSTORE_TYPE_PPC_OPAL = 8,
PSTORE_TYPE_TTYPROBE = 9,
/* End of the list */
PSTORE_TYPE_MAX
@ -231,6 +232,7 @@ struct pstore_backends {
#define PSTORE_FLAGS_CONSOLE BIT(1)
#define PSTORE_FLAGS_FTRACE BIT(2)
#define PSTORE_FLAGS_PMSG BIT(3)
#define PSTORE_FLAGS_TTYPROBE BIT(4)
extern int pstore_register(struct pstore_info *);
extern void pstore_unregister(struct pstore_info *);

View File

@ -96,6 +96,7 @@ void unregister_pstore_device(struct pstore_device_info *dev);
* @pmsg_size: Total size of the pmsg storage area
* @console_size: Total size of the console storage area
* @ftrace_size: Total size for ftrace logging data (for all CPUs)
* @ttyprobe_size: Total size of the ttyprobe storage area
*/
struct pstore_blk_config {
char device[80];
@ -104,6 +105,7 @@ struct pstore_blk_config {
unsigned long pmsg_size;
unsigned long console_size;
unsigned long ftrace_size;
unsigned long ttyprobe_size;
};
/**

View File

@ -133,6 +133,7 @@ struct ramoops_platform_data {
unsigned long console_size;
unsigned long ftrace_size;
unsigned long pmsg_size;
unsigned long ttyprobe_size;
int max_reason;
u32 flags;
struct persistent_ram_ecc_info ecc_info;

View File

@ -21,6 +21,7 @@ typedef ssize_t (*pstore_zone_erase_op)(size_t, loff_t);
* @pmsg_size: The size of pmsg zone which is the same as @kmsg_size.
* @console_size:The size of console zone which is the same as @kmsg_size.
* @ftrace_size:The size of ftrace zone which is the same as @kmsg_size.
* @ttyprobe_size:The size of ttyprobe zone which is the same as @kmsg_size.
* @read: The general read operation. Both of the function parameters
* @size and @offset are relative value to storage.
* On success, the number of bytes should be returned, others
@ -48,6 +49,7 @@ struct pstore_zone_info {
unsigned long pmsg_size;
unsigned long console_size;
unsigned long ftrace_size;
unsigned long ttyprobe_size;
pstore_zone_read_op read;
pstore_zone_write_op write;
pstore_zone_erase_op erase;

View File

@ -531,6 +531,11 @@ extern void tty_termios_encode_baud_rate(struct ktermios *termios,
speed_t ibaud, speed_t obaud);
extern void tty_encode_baud_rate(struct tty_struct *tty,
speed_t ibaud, speed_t obaud);
#ifdef CONFIG_PSTORE_TTYPROBE
extern void pstore_start_ttyprobe(const unsigned char *buf, int count);
#else
static inline void pstore_start_ttyprobe(const unsigned char *buf, int count) {}
#endif
/**
* tty_get_baud_rate - get tty bit rates