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

Commit 563447d7 authored by Jack Steiner's avatar Jack Steiner Committed by Linus Torvalds
Browse files

gru: add additional GRU statistics



Add additional GRU statistics & debug messages.

Signed-off-by: default avatarJack Steiner <steiner@sgi.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 4107e1d3
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -303,7 +303,7 @@ static int gru_try_dropin(struct gru_thread_state *gts,
			  struct gru_tlb_fault_handle *tfh,
			  struct gru_instruction_bits *cbk)
{
	int pageshift = 0, asid, write, ret, atomic = !cbk;
	int pageshift = 0, asid, write, ret, atomic = !cbk, indexway;
	unsigned long gpa = 0, vaddr = 0;

	/*
@@ -333,6 +333,7 @@ static int gru_try_dropin(struct gru_thread_state *gts,
	write = (tfh->cause & TFHCAUSE_TLB_MOD) != 0;
	vaddr = tfh->missvaddr;
	asid = tfh->missasid;
	indexway = tfh->indexway;
	if (asid == 0)
		goto failnoasid;

@@ -361,11 +362,12 @@ static int gru_try_dropin(struct gru_thread_state *gts,
	gru_cb_set_istatus_active(cbk);
	tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write,
			  GRU_PAGESIZE(pageshift));
	STAT(tlb_dropin);
	gru_dbg(grudev,
		"%s: tfh 0x%p, vaddr 0x%lx, asid 0x%x, ps %d, gpa 0x%lx\n",
		ret ? "non-atomic" : "atomic", tfh, vaddr, asid,
		pageshift, gpa);
		"%s: gid %d, gts 0x%p, tfh 0x%p, vaddr 0x%lx, asid 0x%x, indexway 0x%x,"
		" rw %d, ps %d, gpa 0x%lx\n",
		atomic ? "atomic" : "non-atomic", gts->ts_gru->gs_gid, gts, tfh, vaddr, asid,
		indexway, write, pageshift, gpa);
	STAT(tlb_dropin);
	return 0;

failnoasid:
@@ -460,12 +462,14 @@ static irqreturn_t gru_intr(int chiplet, int blade)
		dmap.fault_bits[0], dmap.fault_bits[1]);

	for_each_cbr_in_tfm(cbrnum, dmap.fault_bits) {
		STAT(intr_cbr);
		complete(gru->gs_blade->bs_async_wq);
		gru_dbg(grudev, "gid %d, cbr_done %d, done %d\n",
			gru->gs_gid, cbrnum, gru->gs_blade->bs_async_wq->done);
	}

	for_each_cbr_in_tfm(cbrnum, imap.fault_bits) {
		STAT(intr_tfh);
		tfh = get_tfh_by_index(gru, cbrnum);
		prefetchw(tfh);	/* Helps on hdw, required for emulator */

@@ -551,7 +555,6 @@ int gru_handle_user_call_os(unsigned long cb)
	int ucbnum, cbrnum, ret = -EINVAL;

	STAT(call_os);
	gru_dbg(grudev, "address 0x%lx\n", cb);

	/* sanity check the cb pointer */
	ucbnum = get_cb_number((void *)cb);
@@ -561,6 +564,7 @@ int gru_handle_user_call_os(unsigned long cb)
	gts = gru_find_lock_gts(cb);
	if (!gts)
		return -EINVAL;
	gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);

	if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
		goto exit;
@@ -603,11 +607,11 @@ int gru_get_exception_detail(unsigned long arg)
	if (copy_from_user(&excdet, (void __user *)arg, sizeof(excdet)))
		return -EFAULT;

	gru_dbg(grudev, "address 0x%lx\n", excdet.cb);
	gts = gru_find_lock_gts(excdet.cb);
	if (!gts)
		return -EINVAL;

	gru_dbg(grudev, "address 0x%lx, gid %d, gts 0x%p\n", excdet.cb, gts->ts_gru ? gts->ts_gru->gs_gid : -1, gts);
	ucbnum = get_cb_number((void *)excdet.cb);
	if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
		ret = -EINVAL;
+1 −1
Original line number Diff line number Diff line
@@ -192,7 +192,7 @@ static long gru_file_unlocked_ioctl(struct file *file, unsigned int req,
{
	int err = -EBADRQC;

	gru_dbg(grudev, "file %p\n", file);
	gru_dbg(grudev, "file %p, req 0x%x, 0x%lx\n", file, req, arg);

	switch (req) {
	case GRU_CREATE_CONTEXT:
+8 −3
Original line number Diff line number Diff line
@@ -27,9 +27,11 @@
#ifdef CONFIG_IA64
#include <asm/processor.h>
#define GRU_OPERATION_TIMEOUT	(((cycles_t) local_cpu_data->itc_freq)*10)
#define CLKS2NSEC(c)		((c) *1000000000 / local_cpu_data->itc_freq)
#else
#include <asm/tsc.h>
#define GRU_OPERATION_TIMEOUT	((cycles_t) tsc_khz*10*1000)
#define CLKS2NSEC(c)		((c) * 1000000 / tsc_khz)
#endif

/* Extract the status field from a kernel handle */
@@ -39,10 +41,13 @@ struct mcs_op_statistic mcs_op_statistics[mcsop_last];

static void update_mcs_stats(enum mcs_op op, unsigned long clks)
{
	unsigned long nsec;

	nsec = CLKS2NSEC(clks);
	atomic_long_inc(&mcs_op_statistics[op].count);
	atomic_long_add(clks, &mcs_op_statistics[op].total);
	if (mcs_op_statistics[op].max < clks)
		mcs_op_statistics[op].max = clks;
	atomic_long_add(nsec, &mcs_op_statistics[op].total);
	if (mcs_op_statistics[op].max < nsec)
		mcs_op_statistics[op].max = nsec;
}

static void start_instruction(void *h)
+24 −11
Original line number Diff line number Diff line
@@ -414,8 +414,8 @@ char *gru_get_cb_exception_detail_str(int ret, void *cb,
	if (ret > 0 && gen->istatus == CBS_EXCEPTION) {
		gru_get_cb_exception_detail(cb, &excdet);
		snprintf(buf, size,
			"GRU exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
			"excdet0 0x%lx, excdet1 0x%x",
			"GRU:%d exception: cb %p, opc %d, exopc %d, ecause 0x%x,"
			"excdet0 0x%lx, excdet1 0x%x", smp_processor_id(),
			gen, excdet.opc, excdet.exopc, excdet.ecause,
			excdet.exceptdet0, excdet.exceptdet1);
	} else {
@@ -604,6 +604,8 @@ static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd,
				ret = MQE_UNEXPECTED_CB_ERR;
			break;
		case CBSS_PAGE_OVERFLOW:
			STAT(mesq_noop_page_overflow);
			/* fallthru */
		default:
			BUG();
		}
@@ -745,6 +747,9 @@ static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
		STAT(mesq_send_put_nacked);
		ret = send_message_put_nacked(cb, mqd, mesg, lines);
		break;
	case CBSS_PAGE_OVERFLOW:
		STAT(mesq_page_overflow);
		/* fallthru */
	default:
		BUG();
	}
@@ -837,7 +842,6 @@ void *gru_get_next_message(struct gru_message_queue_desc *mqd)
	int present = mhdr->present;

	/* skip NOOP messages */
	STAT(mesq_receive);
	while (present == MQS_NOOP) {
		gru_free_message(mqd, mhdr);
		mhdr = mq->next;
@@ -857,6 +861,7 @@ void *gru_get_next_message(struct gru_message_queue_desc *mqd)
	if (mhdr->lines == 2)
		restore_present2(mhdr, mhdr->present2);

	STAT(mesq_receive);
	return mhdr;
}
EXPORT_SYMBOL_GPL(gru_get_next_message);
@@ -927,24 +932,24 @@ static int quicktest0(unsigned long arg)

	gru_vload(cb, uv_gpa(&word0), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
	if (gru_wait(cb) != CBS_IDLE) {
		printk(KERN_DEBUG "GRU quicktest0: CBR failure 1\n");
		printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 1\n", smp_processor_id());
		goto done;
	}

	if (*p != MAGIC) {
		printk(KERN_DEBUG "GRU: quicktest0 bad magic 0x%lx\n", *p);
		printk(KERN_DEBUG "GRU:%d quicktest0 bad magic 0x%lx\n", smp_processor_id(), *p);
		goto done;
	}
	gru_vstore(cb, uv_gpa(&word1), gru_get_tri(dsr), XTYPE_DW, 1, 1, IMA);
	if (gru_wait(cb) != CBS_IDLE) {
		printk(KERN_DEBUG "GRU quicktest0: CBR failure 2\n");
		printk(KERN_DEBUG "GRU:%d quicktest0: CBR failure 2\n", smp_processor_id());
		goto done;
	}

	if (word0 != word1 || word1 != MAGIC) {
		printk(KERN_DEBUG
		       "GRU quicktest0 err: found 0x%lx, expected 0x%lx\n",
		     word1, MAGIC);
		       "GRU:%d quicktest0 err: found 0x%lx, expected 0x%lx\n",
		     smp_processor_id(), word1, MAGIC);
		goto done;
	}
	ret = 0;
@@ -981,8 +986,11 @@ static int quicktest1(unsigned long arg)
		if (ret)
			break;
	}
	if (ret != MQE_QUEUE_FULL || i != 4)
	if (ret != MQE_QUEUE_FULL || i != 4) {
		printk(KERN_DEBUG "GRU:%d quicktest1: unexpect status %d, i %d\n",
		       smp_processor_id(), ret, i);
		goto done;
	}

	for (i = 0; i < 6; i++) {
		m = gru_get_next_message(&mqd);
@@ -990,7 +998,12 @@ static int quicktest1(unsigned long arg)
			break;
		gru_free_message(&mqd, m);
	}
	ret = (i == 4) ? 0 : -EIO;
	if (i != 4) {
		printk(KERN_DEBUG "GRU:%d quicktest2: bad message, i %d, m %p, m8 %d\n",
			smp_processor_id(), i, m, m ? m[8] : -1);
		goto done;
	}
	ret = 0;

done:
	kfree(p);
@@ -1069,7 +1082,7 @@ static int quicktest3(unsigned long arg)
	memset(buf1, get_cycles() & 255, sizeof(buf1));
	gru_copy_gpa(uv_gpa(buf2), uv_gpa(buf1), BUFSIZE);
	if (memcmp(buf1, buf2, BUFSIZE)) {
		printk(KERN_DEBUG "GRU quicktest3 error\n");
		printk(KERN_DEBUG "GRU:%d quicktest3 error\n", smp_processor_id());
		ret = -EIO;
	}
	return ret;
+7 −3
Original line number Diff line number Diff line
@@ -370,6 +370,7 @@ struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, int tsid)
	if (!vdata)
		return NULL;

	STAT(vdata_alloc);
	INIT_LIST_HEAD(&vdata->vd_head);
	spin_lock_init(&vdata->vd_lock);
	gru_dbg(grudev, "alloc vdata %p\n", vdata);
@@ -552,7 +553,8 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate)
		zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE);
	cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);

	gru_dbg(grudev, "gts %p\n", gts);
	gru_dbg(grudev, "gts %p, cbrmap 0x%lx, dsrmap 0x%lx\n",
		gts, gts->ts_cbr_map, gts->ts_dsr_map);
	lock_cch_handle(cch);
	if (cch_interrupt_sync(cch))
		BUG();
@@ -583,9 +585,7 @@ void gru_load_context(struct gru_thread_state *gts)
	struct gru_context_configuration_handle *cch;
	int i, err, asid, ctxnum = gts->ts_ctxnum;

	gru_dbg(grudev, "gts %p\n", gts);
	cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);

	lock_cch_handle(cch);
	cch->tfm_fault_bit_enable =
	    (gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
@@ -635,6 +635,10 @@ void gru_load_context(struct gru_thread_state *gts)
	if (cch_start(cch))
		BUG();
	unlock_cch_handle(cch);

	gru_dbg(grudev, "gid %d, gts %p, cbrmap 0x%lx, dsrmap 0x%lx, tie %d, tis %d\n",
		gts->ts_gru->gs_gid, gts, gts->ts_cbr_map, gts->ts_dsr_map,
		(gts->ts_user_options == GRU_OPT_MISS_FMM_INTR), gts->ts_tlb_int_select);
}

/*
Loading