linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@elte.hu>
To: Cliff Wickman <cpw@sgi.com>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] x86, UV: BAU performance and error recovery
Date: Fri, 12 Mar 2010 20:38:14 +0100	[thread overview]
Message-ID: <20100312193814.GA27306@elte.hu> (raw)
In-Reply-To: <E1Nq5yy-0006ot-8E@eag09.americas.sgi.com>


* Cliff Wickman <cpw@sgi.com> wrote:

>  static void uv_bau_process_message(struct bau_payload_queue_entry *msg,
> +			int msg_slot, int sw_ack_slot, struct bau_control *bcp,
> +			struct bau_payload_queue_entry *va_queue_first,
> +			struct bau_payload_queue_entry *va_queue_last)

this function really needs a cleanup - some helper structure that can be 
passed along, instead of these 6 parameters from hell.

Also:

> +	int i;
> +	int sending_cpu;
> +	int msg_ack_count;
> +	int slot2;
> +	int cancel_count = 0;
> +	unsigned char this_sw_ack_vector;
> +	short socket_ack_count = 0;
> +	unsigned long mmr = 0;
> +	unsigned long msg_res;
> +	struct ptc_stats *stat;
> +	struct bau_payload_queue_entry *msg2;
> +	struct bau_control *smaster = bcp->socket_master;
>  
> +	/*
> +	 * This must be a normal message, or retry of a normal message
> +	 */
> +	stat = &per_cpu(ptcstats, bcp->cpu);
>  	if (msg->address == TLB_FLUSH_ALL) {
>  		local_flush_tlb();
> -		__get_cpu_var(ptcstats).alltlb++;
> +		stat->d_alltlb++;
>  	} else {
>  		__flush_tlb_one(msg->address);
> -		__get_cpu_var(ptcstats).onetlb++;
> +		stat->d_onetlb++;
>  	}
> +	stat->d_requestee++;
>  
> -	__get_cpu_var(ptcstats).requestee++;
> +	/*
> +	 * One cpu on each blade has the additional job on a RETRY
> +	 * of releasing the resource held by the message that is
> +	 * being retried.  That message is identified by sending
> +	 * cpu number.
> +	 */
> +	if (msg->msg_type == MSG_RETRY && bcp == bcp->pnode_master) {
> +		sending_cpu = msg->sending_cpu;
> +		this_sw_ack_vector = msg->sw_ack_vector;
> +		stat->d_retries++;
> +		/*
> +		 * cancel any from msg+1 to the retry itself
> +		 */
> +		bcp->retry_message_scans++;
> +		for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) {
> +			if (msg2 > va_queue_last)
> +				msg2 = va_queue_first;
> +			if (msg2 == msg)
> +				break;
> +
> +			/* uv_bau_process_message: same conditions
> +			   for cancellation as uv_do_reset */
> +			if ((msg2->replied_to == 0) &&
> +			    (msg2->canceled == 0) &&
> +			    (msg2->sw_ack_vector) &&
> +			    ((msg2->sw_ack_vector &
> +				this_sw_ack_vector) == 0) &&
> +			    (msg2->sending_cpu == sending_cpu) &&
> +			    (msg2->msg_type != MSG_NOOP)) {
> +				bcp->retry_message_actions++;
> +				slot2 = msg2 - va_queue_first;
> +				mmr = uv_read_local_mmr
> +				(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
> +				msg_res = ((msg2->sw_ack_vector << 8) |
> +					   msg2->sw_ack_vector);
> +				/*
> +				 * If this message timed out elsewhere
> +				 * so that a retry was broadcast, it
> +				 * should have timed out here too.
> +				 * It is not 'replied_to' so some local
> +				 * cpu has not seen it.  When it does
> +				 * get around to processing the
> +				 * interrupt it should skip it, as
> +				 * it's going to be marked 'canceled'.
> +				 */
> +				msg2->canceled = 1;
> +				cancel_count++;
> +				/*
> +				 * this is a message retry; clear
> +				 * the resources held by the previous
> +				 * message or retries even if they did
> +				 * not time out
> +				 */
> +				if (mmr & msg_res) {
> +					stat->d_canceled++;
> +					uv_write_local_mmr(
> +			    UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS,
> +						msg_res);
> +				}
> +			}
> +		}
> +		if (!cancel_count)
> +			stat->d_nocanceled++;
> +	}
>  
> +	/*
> +	 * This is a sw_ack message, so we have to reply to it.
> +	 * Count each responding cpu on the socket. This avoids
> +	 * pinging the count's cache line back and forth between
> +	 * the sockets.
> +	 */
> +	socket_ack_count = atomic_add_short_return(1, (struct atomic_short *)
> +				&smaster->socket_acknowledge_count[msg_slot]);
> +	if (socket_ack_count == bcp->cpus_in_socket) {
> +		/*
> +		 * Both sockets dump their completed count total into
> +		 * the message's count.
> +		 */
> +		smaster->socket_acknowledge_count[msg_slot] = 0;
> +		msg_ack_count = atomic_add_short_return(socket_ack_count,
> +				(struct atomic_short *)&msg->acknowledge_count);
> +
> +		if (msg_ack_count == bcp->cpus_in_blade) {
> +			/*
> +			 * All cpus in blade saw it; reply
> +			 */
> +			uv_reply_to_message(msg_slot, sw_ack_slot, msg, bcp);
> +		}
> +	}
> +

This function is way too large and suffers from various col80 artifacts, the 
pinacle of which is probably this:

> +					uv_write_local_mmr(
> +			    UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS,
> +						msg_res);

Helper inlines and other tricks could reduce its size and reduce the per 
function complexity.

> +	return;
> +}

Totally unnecessary return statement.

Really, this code is pretty ugly and should be restructured to be a lot easier 
to read and easier to maintain.

If this patch works for you we can do this as a smaller series of that patch 
plus a cleanup patch (for easier debuggability), but we really want a cleaner 
thing than this ...

	Ingo

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

      reply	other threads:[~2010-03-12 19:38 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-12 14:36 [PATCH] x86, UV: BAU performance and error recovery Cliff Wickman
2010-03-12 19:38 ` Ingo Molnar [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100312193814.GA27306@elte.hu \
    --to=mingo@elte.hu \
    --cc=cpw@sgi.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).