lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 29 Apr 2008 17:26:05 +0800
From:	"Li Yang" <LeoLi@...escale.com>
To:	"Joakim Tjernlund" <Joakim.Tjernlund@...nsmode.se>,
	"Netdev" <netdev@...r.kernel.org>
Subject: RE: [PATCH] ucc_geth: Ack IRQ events as late as possible.

> -----Original Message-----
> From: Joakim Tjernlund [mailto:Joakim.Tjernlund@...nsmode.se] 
> Sent: Friday, April 25, 2008 11:43 PM
> To: Li Yang; Netdev
> Cc: Joakim Tjernlund
> Subject: [PATCH] ucc_geth: Ack IRQ events as late as possible.
> 
> Late acking of IRQ events will reduce number of interrupts 
> that needs to be served.
> 
> Makes the system somewhat responsive during a ping -f -l 10
> 
> Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@...nsmode.se>
> ---
>  drivers/net/ucc_geth.c |   36 ++++++++++++++++++++++--------------
>  drivers/net/ucc_geth.h |    4 ++--
>  2 files changed, 24 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c 
> index 28431aa..c6bf4d3 100644
> --- a/drivers/net/ucc_geth.c
> +++ b/drivers/net/ucc_geth.c
> @@ -3449,6 +3449,7 @@ static int ucc_geth_rx(struct 
> ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
>  	u32 bd_status;
>  	u8 *bdBuffer;
>  	struct net_device *dev;
> +	struct ucc_fast_private *uccf = ugeth->uccf;
>  
>  	ugeth_vdbg("%s: IN", __FUNCTION__);
>  
> @@ -3457,10 +3458,21 @@ static int ucc_geth_rx(struct 
> ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
>  	/* collect received buffers */
>  	bd = ugeth->rxBd[rxQ];
>  
> -	bd_status = in_be32((u32 *)bd);
> -
>  	/* while there are received buffers and BD is full (~R_E) */
> -	while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) {
> +	while (1) {
> +		if (in_be32(uccf->p_ucce) & UCCE_BSY) {
> +			dev->stats.rx_missed_errors++;
> +			dev->stats.rx_errors++;
> +		}
> +		out_be32(uccf->p_ucce, UCCE_RX_EVENTS);
> +
> +		if (--rx_work_limit < 0)
> +			break;
> +
> +		bd_status = in_be32((u32 *)bd);
> +		if (bd_status & R_E)
> +			break; /* No more RX buffers */
> +
>  		bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf);
>  		length = (u16) ((bd_status & BD_LENGTH_MASK) - 4);
>  		skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]];
> @@ -3530,6 +3542,7 @@ static int ucc_geth_tx(struct 
> net_device *dev, u8 txQ)  {
>  	/* Start from the next BD that should be filled */
>  	struct ucc_geth_private *ugeth = netdev_priv(dev);
> +	struct ucc_fast_private *uccf = ugeth->uccf;
>  	u8 *bd;			/* BD pointer */
>  	u32 bd_status;
>  
> @@ -3541,6 +3554,7 @@ static int ucc_geth_tx(struct 
> net_device *dev, u8 txQ)
>  		/* BD contains already transmitted buffer.   */
>  		/* Handle the transmitted buffer and release */
>  		/* the BD to be used with the current frame  */
> +		out_be32(uccf->p_ucce, UCCE_TX_EVENTS);
>  
>  		if ((bd == ugeth->txBd[txQ]) && 
> (netif_queue_stopped(dev) == 0))
>  			break;
> @@ -3619,10 +3633,8 @@ static irqreturn_t 
> ucc_geth_irq_handler(int irq, void *info)
>  	ug_info = ugeth->ug_info;
>  
>  	/* read and clear events */
> -	ucce = (u32) in_be32(uccf->p_ucce);
>  	uccm = (u32) in_be32(uccf->p_uccm);
> -	ucce &= uccm;
> -	out_be32(uccf->p_ucce, ucce);
> +	ucce = (u32) in_be32(uccf->p_ucce) & uccm;
>  
>  	/* check for receive events that require processing */
>  	if (ucce & UCCE_RX_EVENTS) {
> @@ -3643,6 +3655,7 @@ static irqreturn_t 
> ucc_geth_irq_handler(int irq, void *info)  #endif /* 
> CONFIG_UGETH_NAPI */
>  	}
>  
> +	ucce = (u32) in_be32(uccf->p_ucce) & uccm;
>  	/* Tx event processing */
>  	if (ucce & UCCE_TX_EVENTS) {
>  		spin_lock(&ugeth->lock);
> @@ -3655,15 +3668,10 @@ static irqreturn_t 
> ucc_geth_irq_handler(int irq, void *info)
>  		}
>  		spin_unlock(&ugeth->lock);
>  	}
> -
> -	/* Errors and other events */
> +	ucce = (u32) in_be32(uccf->p_ucce) & uccm;
> +	/* Other events */
>  	if (ucce & UCCE_OTHER) {
> -		if (ucce & UCCE_BSY) {
> -			dev->stats.rx_errors++;
> -		}
> -		if (ucce & UCCE_TXE) {
> -			dev->stats.tx_errors++;
> -		}
> +		out_be32(uccf->p_ucce, UCCE_OTHER);
>  	}
>  
>  	return IRQ_HANDLED;
> diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h 
> index cc24e87..7451f17 100644
> --- a/drivers/net/ucc_geth.h
> +++ b/drivers/net/ucc_geth.h
> @@ -207,8 +207,8 @@ struct ucc_geth {
>  			UCCE_RXB3 | UCCE_RXB2 | UCCE_RXB1 | UCCE_RXB0)
>  #define UCCE_RXF         (UCCE_RXF7 | UCCE_RXF6 | UCCE_RXF5 
> | UCCE_RXF4 |\
>  			UCCE_RXF3 | UCCE_RXF2 | UCCE_RXF1 | UCCE_RXF0)
> -#define UCCE_OTHER       (UCCE_SCAR | UCCE_GRA  | UCCE_CBPR 
> | UCCE_BSY  |\
> -			UCCE_RXC  | UCCE_TXC  | UCCE_TXE)
> +#define UCCE_OTHER       (UCCE_SCAR | UCCE_GRA | UCCE_CBPR |\
> +			UCCE_RXC  | UCCE_TXC)

This will remove UCCE_BSY and UCCE_TXE from the uccm_mask, hence
disabled them from generating interrupts.

How is the improvement after your change to put off interrupt ack?
Isn't it caused by disabling the busy interrupts?

- Leo
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ