blob: 1a41d4c63ea38b0d0589a2088b5654e3391556fa [file] [log] [blame]
/*
* Copyright (c) 2014-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __SEEMP_LOGK_H__
#define __SEEMP_LOGK_H__
#define OBSERVER_VERSION 0x01
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/wait.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/mutex.h>
#include <linux/vmalloc.h>
#include <asm/ioctls.h>
#define seemp_LOGK_NUM_DEVS 1
#define seemp_LOGK_DEV_NAME "seemplog"
/*
* The logcat driver on Android uses four 256k ring buffers
* here, we use two ring buffers of the same size.
* we think this is reasonable
*/
#define FULL_BUF_SIZE (64 * 1024 * 1024)
#define HALF_BUF_SIZE (32 * 1024 * 1024)
#define FULL_BLOCKS (8 * 1024)
#define HALF_BLOCKS (4 * 1024)
#define READER_NOT_READY 0
#define READER_READY 1
#define MAGIC 'z'
#define SEEMP_CMD_RESERVE_RDBLKS _IOR(MAGIC, 1, int)
#define SEEMP_CMD_RELEASE_RDBLKS _IO(MAGIC, 2)
#define SEEMP_CMD_GET_RINGSZ _IOR(MAGIC, 3, int)
#define SEEMP_CMD_GET_BLKSZ _IOR(MAGIC, 4, int)
#define SEEMP_CMD_SET_MASK _IO(MAGIC, 5)
#define SEEMP_CMD_SET_MAPPING _IO(MAGIC, 6)
#define SEEMP_CMD_CHECK_FILTER _IOR(MAGIC, 7, int)
struct read_range {
int start_idx;
int num;
};
struct seemp_logk_dev {
unsigned int major;
unsigned int minor;
struct cdev cdev;
struct class *cls;
/*the full buffer*/
struct seemp_logk_blk *ring;
/*an array of blks*/
unsigned int ring_sz;
unsigned int blk_sz;
int num_tot_blks;
int num_write_avail_blks;
int num_write_in_prog_blks;
int num_read_avail_blks;
int num_read_in_prog_blks;
int num_writers;
/*
* there is always one reader
* which is the observer daemon
* therefore there is no necessity
* for num_readers variable
*/
/*
* read_idx and write_idx loop through from zero to ring_sz,
* and then back to zero in a circle, as they advance
* based on the reader's and writers' accesses
*/
int read_idx;
int write_idx;
/*
* wait queues
* readers_wq: implement wait for readers
* writers_wq: implement wait for writers
*
* whether writers are blocked or not is driven by the policy:
* case 1: (best_effort_logging == 1)
* writers are not blocked, and
* when there is no mem in the ring to store logs,
* the logs are simply dropped.
* case 2: (best_effort_logging == 0)
* when there is no mem in the ring to store logs,
* the process gets blocked until there is space.
*/
wait_queue_head_t readers_wq;
wait_queue_head_t writers_wq;
/*
* protects everything in the device
* including ring buffer and all the num_ variables
* spinlock_t lock;
*/
struct mutex lock;
};
#define BLK_SIZE 256
#define BLK_HDR_SIZE 64
#define TS_SIZE 20
#define BLK_MAX_MSG_SZ (BLK_SIZE - BLK_HDR_SIZE)
struct blk_payload {
__u32 api_id; /* event API id */
char msg[BLK_MAX_MSG_SZ]; /* event parameters */
} __packed;
struct seemp_logk_blk {
__u8 status; /* bits: 0->valid/invalid; 1-7: unused as of now! */
__u16 len; /* length of the payload */
__u8 version; /* version number */
__s32 pid; /* generating process's pid */
__s32 uid; /* generating process's uid - app specific */
__s32 tid; /* generating process's tid */
__s32 sec; /* seconds since Epoch */
__s32 nsec; /* nanoseconds */
char ts[TS_SIZE]; /* Time Stamp */
char appname[TASK_COMM_LEN];
struct blk_payload payload;
} __packed;
extern unsigned int kmalloc_flag;
struct seemp_source_mask {
__u32 hash;
bool isOn;
};
#endif