arch/s390/kernel/perf_cpum_sf.c

Source file repositories/reference/linux-study-clean/arch/s390/kernel/perf_cpum_sf.c

File Facts

System
Linux kernel
Corpus path
arch/s390/kernel/perf_cpum_sf.c
Extension
.c
Size
59832 bytes
Lines
2108
Domain
Architecture Layer
Bucket
arch/s390
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct sf_buffer {
	unsigned long	 *sdbt;	    /* Sample-data-block-table origin */
	/* buffer characteristics (required for buffer increments) */
	unsigned long  num_sdb;	    /* Number of sample-data-blocks */
	unsigned long num_sdbt;	    /* Number of sample-data-block-tables */
	unsigned long	 *tail;	    /* last sample-data-block-table */
};

struct aux_buffer {
	struct sf_buffer sfb;
	unsigned long head;	   /* index of SDB of buffer head */
	unsigned long alert_mark;  /* index of SDB of alert request position */
	unsigned long empty_mark;  /* mark of SDB not marked full */
	unsigned long *sdb_index;  /* SDB address for fast lookup */
	unsigned long *sdbt_index; /* SDBT address for fast lookup */
};

struct cpu_hw_sf {
	/* CPU-measurement sampling information block */
	struct hws_qsi_info_block qsi;
	/* CPU-measurement sampling control block */
	struct hws_lsctl_request_block lsctl;
	struct sf_buffer sfb;	    /* Sampling buffer */
	unsigned int flags;	    /* Status flags */
	struct perf_event *event;   /* Scheduled perf event */
	struct perf_output_handle handle; /* AUX buffer output handle */
};
static DEFINE_PER_CPU(struct cpu_hw_sf, cpu_hw_sf);

/* Debug feature */
static debug_info_t *sfdbg;

/* Sampling control helper functions */
static inline unsigned long freq_to_sample_rate(struct hws_qsi_info_block *qsi,
						unsigned long freq)
{
	return (USEC_PER_SEC / freq) * qsi->cpu_speed;
}

static inline unsigned long sample_rate_to_freq(struct hws_qsi_info_block *qsi,
						unsigned long rate)
{
	return USEC_PER_SEC * qsi->cpu_speed / rate;
}

/* Return pointer to trailer entry of an sample data block */
static inline struct hws_trailer_entry *trailer_entry_ptr(unsigned long v)
{
	void *ret;

	ret = (void *)v;
	ret += PAGE_SIZE;
	ret -= sizeof(struct hws_trailer_entry);

	return ret;
}

/*
 * Return true if the entry in the sample data block table (sdbt)
 * is a link to the next sdbt
 */
static inline int is_link_entry(unsigned long *s)
{
	return *s & 0x1UL ? 1 : 0;
}

/* Return pointer to the linked sdbt */
static inline unsigned long *get_next_sdbt(unsigned long *s)
{
	return phys_to_virt(*s & ~0x1UL);
}

/*
 * sf_disable() - Switch off sampling facility
 */
static void sf_disable(void)
{
	struct hws_lsctl_request_block sreq;

	memset(&sreq, 0, sizeof(sreq));
	lsctl(&sreq);
}

/*
 * sf_buffer_available() - Check for an allocated sampling buffer
 */
static int sf_buffer_available(struct cpu_hw_sf *cpuhw)
{
	return !!cpuhw->sfb.sdbt;
}

Annotation

Implementation Notes