Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 432ac5e0 authored by Jan Glauber's avatar Jan Glauber Committed by Martin Schwidefsky
Browse files

[S390] qdio: optimize cache line usage of struct qdio_irq



Remove a memset hack that relied on the internal layout of the
qdio_irq struct and move the per device statistics data into an own
cache line to avoid cache line bashing between the inbound and the
outbound queue tasklets. Also reduce the number of allocated queues
from 32 to 4 which is the current maximum. That saves a cache line
in struct qdio_irq.

Signed-off-by: default avatarJan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent d307297f
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -13,7 +13,8 @@
#include <asm/cio.h>
#include <asm/cio.h>
#include <asm/ccwdev.h>
#include <asm/ccwdev.h>


#define QDIO_MAX_QUEUES_PER_IRQ		32
/* only use 4 queues to save some cachelines */
#define QDIO_MAX_QUEUES_PER_IRQ		4
#define QDIO_MAX_BUFFERS_PER_Q		128
#define QDIO_MAX_BUFFERS_PER_Q		128
#define QDIO_MAX_BUFFERS_MASK		(QDIO_MAX_BUFFERS_PER_Q - 1)
#define QDIO_MAX_BUFFERS_MASK		(QDIO_MAX_BUFFERS_PER_Q - 1)
#define QDIO_MAX_ELEMENTS_PER_BUFFER	16
#define QDIO_MAX_ELEMENTS_PER_BUFFER	16
+3 −6
Original line number Original line Diff line number Diff line
@@ -208,7 +208,7 @@ struct qdio_dev_perf_stat {
	unsigned int eqbs_partial;
	unsigned int eqbs_partial;
	unsigned int sqbs;
	unsigned int sqbs;
	unsigned int sqbs_partial;
	unsigned int sqbs_partial;
};
} ____cacheline_aligned;


struct qdio_queue_perf_stat {
struct qdio_queue_perf_stat {
	/*
	/*
@@ -329,12 +329,8 @@ struct qdio_irq {
	struct qdio_ssqd_desc ssqd_desc;
	struct qdio_ssqd_desc ssqd_desc;
	void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *);
	void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *);


	struct qdio_dev_perf_stat perf_stat;
	int perf_stat_enabled;
	int perf_stat_enabled;
	/*

	 * Warning: Leave these members together at the end so they won't be
	 * cleared in qdio_setup_irq.
	 */
	struct qdr *qdr;
	struct qdr *qdr;
	unsigned long chsc_page;
	unsigned long chsc_page;


@@ -343,6 +339,7 @@ struct qdio_irq {


	debug_info_t *debug_area;
	debug_info_t *debug_area;
	struct mutex setup_mutex;
	struct mutex setup_mutex;
	struct qdio_dev_perf_stat perf_stat;
};
};


/* helper functions */
/* helper functions */
+9 −1
Original line number Original line Diff line number Diff line
@@ -382,7 +382,15 @@ int qdio_setup_irq(struct qdio_initialize *init_data)
	struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data;
	struct qdio_irq *irq_ptr = init_data->cdev->private->qdio_data;
	int rc;
	int rc;


	memset(irq_ptr, 0, ((char *)&irq_ptr->qdr) - ((char *)irq_ptr));
	memset(&irq_ptr->qib, 0, sizeof(irq_ptr->qib));
	memset(&irq_ptr->siga_flag, 0, sizeof(irq_ptr->siga_flag));
	memset(&irq_ptr->ccw, 0, sizeof(irq_ptr->ccw));
	memset(&irq_ptr->ssqd_desc, 0, sizeof(irq_ptr->ssqd_desc));
	memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat));

	irq_ptr->debugfs_dev = irq_ptr->debugfs_perf = NULL;
	irq_ptr->sch_token = irq_ptr->state = irq_ptr->perf_stat_enabled = 0;

	/* wipes qib.ac, required by ar7063 */
	/* wipes qib.ac, required by ar7063 */
	memset(irq_ptr->qdr, 0, sizeof(struct qdr));
	memset(irq_ptr->qdr, 0, sizeof(struct qdr));