[Issue] Currently, a variable name, which identifies each entry, consists of type, id and ctime. But if multiple events happens in a short time, a second/third event may fail to log because efi_pstore can't distinguish each event with current variable name. [Solution] A reasonable way to identify all events precisely is introducing a sequence counter to the variable name. The sequence counter has already supported in a pstore layer with "oopscount". So, this patch adds it to a variable name. Also, it is passed to read/erase callbacks of platform drivers in accordance with the modification of the variable name. <before applying this patch> a variable name of first event: dump-type0-1-12345678 a variable name of second event: dump-type0-1-12345678 type:0 id:1 ctime:12345678 If multiple events happen in a short time, efi_pstore can't distinguish them because variable names are same among them. <after applying this patch> it can be distinguishable by adding a sequence counter as follows. a variable name of first event: dump-type0-1-1-12345678 a variable name of Second event: dump-type0-1-2-12345678 type:0 id:1 sequence counter: 1(first event), 2(second event) ctime:12345678 In case of a write callback executed in pstore_console_write(), "0" is added to an argument of the write callback because it just logs all kernel messages and doesn't need to care about multiple events. Signed-off-by: Seiji Aguchi <seiji.aguchi@hds.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Mike Waychison <mikew@google.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
		
			
				
	
	
		
			57 lines
		
	
	
	
		
			1.2 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			57 lines
		
	
	
	
		
			1.2 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
#ifndef __PSTORE_INTERNAL_H__
 | 
						|
#define __PSTORE_INTERNAL_H__
 | 
						|
 | 
						|
#include <linux/types.h>
 | 
						|
#include <linux/time.h>
 | 
						|
#include <linux/pstore.h>
 | 
						|
 | 
						|
#if NR_CPUS <= 2 && defined(CONFIG_ARM_THUMB)
 | 
						|
#define PSTORE_CPU_IN_IP 0x1
 | 
						|
#elif NR_CPUS <= 4 && defined(CONFIG_ARM)
 | 
						|
#define PSTORE_CPU_IN_IP 0x3
 | 
						|
#endif
 | 
						|
 | 
						|
struct pstore_ftrace_record {
 | 
						|
	unsigned long ip;
 | 
						|
	unsigned long parent_ip;
 | 
						|
#ifndef PSTORE_CPU_IN_IP
 | 
						|
	unsigned int cpu;
 | 
						|
#endif
 | 
						|
};
 | 
						|
 | 
						|
static inline void
 | 
						|
pstore_ftrace_encode_cpu(struct pstore_ftrace_record *rec, unsigned int cpu)
 | 
						|
{
 | 
						|
#ifndef PSTORE_CPU_IN_IP
 | 
						|
	rec->cpu = cpu;
 | 
						|
#else
 | 
						|
	rec->ip |= cpu;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
static inline unsigned int
 | 
						|
pstore_ftrace_decode_cpu(struct pstore_ftrace_record *rec)
 | 
						|
{
 | 
						|
#ifndef PSTORE_CPU_IN_IP
 | 
						|
	return rec->cpu;
 | 
						|
#else
 | 
						|
	return rec->ip & PSTORE_CPU_IN_IP;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
#ifdef CONFIG_PSTORE_FTRACE
 | 
						|
extern void pstore_register_ftrace(void);
 | 
						|
#else
 | 
						|
static inline void pstore_register_ftrace(void) {}
 | 
						|
#endif
 | 
						|
 | 
						|
extern struct pstore_info *psinfo;
 | 
						|
 | 
						|
extern void	pstore_set_kmsg_bytes(int);
 | 
						|
extern void	pstore_get_records(int);
 | 
						|
extern int	pstore_mkfile(enum pstore_type_id, char *psname, u64 id,
 | 
						|
			      int count, char *data, size_t size,
 | 
						|
			      struct timespec time, struct pstore_info *psi);
 | 
						|
extern int	pstore_is_mounted(void);
 | 
						|
 | 
						|
#endif
 |