⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skdim.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Name:	skdim.c * Project:	GEnesis, PCI Gigabit Ethernet Adapter * Version:	$Revision: 1.5 $ * Date:	$Date: 2003/11/28 12:55:40 $ * Purpose:	All functions to maintain interrupt moderation * ******************************************************************************//****************************************************************************** * *	(C)Copyright 1998-2002 SysKonnect GmbH. *	(C)Copyright 2002-2003 Marvell. * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2 of the License, or *	(at your option) any later version. * *	The information in this file is provided "AS IS" without warranty. * ******************************************************************************//****************************************************************************** * * Description: * * This module is intended to manage the dynamic interrupt moderation on both    * GEnesis and Yukon adapters. * * Include File Hierarchy: * *	"skdrv1st.h" *	"skdrv2nd.h" * ******************************************************************************/#ifndef	lintstatic const char SysKonnectFileId[] =	"@(#) $Id: skdim.c,v 1.5 2003/11/28 12:55:40 rroesler Exp $ (C) SysKonnect.";#endif#define __SKADDR_C#ifdef __cplusplus#error C++ is not yet supported.extern "C" {#endif/*********************************************************************************** Includes*********************************************************************************/#ifndef __INC_SKDRV1ST_H#include "h/skdrv1st.h"#endif#ifndef __INC_SKDRV2ND_H#include "h/skdrv2nd.h"#endif#include	<linux/kernel_stat.h>/*********************************************************************************** Defines*********************************************************************************//*********************************************************************************** Typedefs*********************************************************************************//*********************************************************************************** Local function prototypes *********************************************************************************/static unsigned int GetCurrentSystemLoad(SK_AC *pAC);static SK_U64       GetIsrCalls(SK_AC *pAC);static SK_BOOL      IsIntModEnabled(SK_AC *pAC);static void         SetCurrIntCtr(SK_AC *pAC);static void         EnableIntMod(SK_AC *pAC); static void         DisableIntMod(SK_AC *pAC);static void         ResizeDimTimerDuration(SK_AC *pAC);static void         DisplaySelectedModerationType(SK_AC *pAC);static void         DisplaySelectedModerationMask(SK_AC *pAC);static void         DisplayDescrRatio(SK_AC *pAC);/*********************************************************************************** Global variables*********************************************************************************//*********************************************************************************** Local variables*********************************************************************************//*********************************************************************************** Global functions *********************************************************************************//********************************************************************************* Function     : SkDimModerate** Description  : Called in every ISR to check if moderation is to be applied**                or not for the current number of interrupts** Programmer   : Ralph Roesler** Last Modified: 22-mar-03** Returns      : void (!)** Notes        : -*******************************************************************************/void SkDimModerate(SK_AC *pAC) {    unsigned int CurrSysLoad    = 0;  /* expressed in percent */    unsigned int LoadIncrease   = 0;  /* expressed in percent */    SK_U64       ThresholdInts  = 0;    SK_U64       IsrCallsPerSec = 0;#define M_DIMINFO pAC->DynIrqModInfo    if (!IsIntModEnabled(pAC)) {        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {            CurrSysLoad = GetCurrentSystemLoad(pAC);            if (CurrSysLoad > 75) {                    /*                     ** More than 75% total system load! Enable the moderation                     ** to shield the system against too many interrupts.                    */                    EnableIntMod(pAC);            } else if (CurrSysLoad > M_DIMINFO.PrevSysLoad) {                LoadIncrease = (CurrSysLoad - M_DIMINFO.PrevSysLoad);                if (LoadIncrease > ((M_DIMINFO.PrevSysLoad *                                         C_INT_MOD_ENABLE_PERCENTAGE) / 100)) {                    if (CurrSysLoad > 10) {                        /*                         ** More than 50% increase with respect to the                         ** previous load of the system. Most likely this                         ** is due to our ISR-proc...                        */                        EnableIntMod(pAC);                    }                }            } else {                /*                ** Neither too much system load at all nor too much increase                ** with respect to the previous system load. Hence, we can leave                ** the ISR-handling like it is without enabling moderation.                */            }            M_DIMINFO.PrevSysLoad = CurrSysLoad;        }       } else {        if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {            ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *                                   C_INT_MOD_DISABLE_PERCENTAGE) / 100);            IsrCallsPerSec = GetIsrCalls(pAC);            if (IsrCallsPerSec <= ThresholdInts) {                /*                 ** The number of interrupts within the last second is                 ** lower than the disable_percentage of the desried                 ** maxrate. Therefore we can disable the moderation.                */                DisableIntMod(pAC);                M_DIMINFO.MaxModIntsPerSec =                    (M_DIMINFO.MaxModIntsPerSecUpperLimit +                    M_DIMINFO.MaxModIntsPerSecLowerLimit) / 2;            } else {                /*                ** The number of interrupts per sec is the same as expected.                ** Evalulate the descriptor-ratio. If it has changed, a resize                 ** in the moderation timer might be usefull                */                if (M_DIMINFO.AutoSizing) {                    ResizeDimTimerDuration(pAC);                }            }        }    }    /*    ** Some information to the log...    */    if (M_DIMINFO.DisplayStats) {        DisplaySelectedModerationType(pAC);        DisplaySelectedModerationMask(pAC);        DisplayDescrRatio(pAC);    }    M_DIMINFO.NbrProcessedDescr = 0;     SetCurrIntCtr(pAC);}/********************************************************************************* Function     : SkDimStartModerationTimer** Description  : Starts the audit-timer for the dynamic interrupt moderation** Programmer   : Ralph Roesler** Last Modified: 22-mar-03** Returns      : void (!)** Notes        : -*******************************************************************************/void SkDimStartModerationTimer(SK_AC *pAC) {    SK_EVPARA    EventParam;   /* Event struct for timer event */     SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));    EventParam.Para32[0] = SK_DRV_MODERATION_TIMER;    SkTimerStart(pAC, pAC->IoBase, &pAC->DynIrqModInfo.ModTimer,                 SK_DRV_MODERATION_TIMER_LENGTH,                 SKGE_DRV, SK_DRV_TIMER, EventParam);}/********************************************************************************* Function     : SkDimEnableModerationIfNeeded** Description  : Either enables or disables moderation** Programmer   : Ralph Roesler** Last Modified: 22-mar-03** Returns      : void (!)** Notes        : This function is called when a particular adapter is opened**                There is no Disable function, because when all interrupts **                might be disable, the moderation timer has no meaning at all******************************************************************************/voidSkDimEnableModerationIfNeeded(SK_AC *pAC) {    if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_STATIC) {        EnableIntMod(pAC);   /* notification print in this function */    } else if (M_DIMINFO.IntModTypeSelect == C_INT_MOD_DYNAMIC) {        SkDimStartModerationTimer(pAC);        if (M_DIMINFO.DisplayStats) {            printk("Dynamic moderation has been enabled\n");        }    } else {        if (M_DIMINFO.DisplayStats) {            printk("No moderation has been enabled\n");        }    }}/********************************************************************************* Function     : SkDimDisplayModerationSettings** Description  : Displays the current settings regaring interrupt moderation** Programmer   : Ralph Roesler** Last Modified: 22-mar-03** Returns      : void (!)** Notes        : -*******************************************************************************/void SkDimDisplayModerationSettings(SK_AC *pAC) {    DisplaySelectedModerationType(pAC);    DisplaySelectedModerationMask(pAC);}/*********************************************************************************** Local functions *********************************************************************************//********************************************************************************* Function     : GetCurrentSystemLoad** Description  : Retrieves the current system load of the system. This load**                is evaluated for all processors within the system.** Programmer   : Ralph Roesler** Last Modified: 22-mar-03** Returns      : unsigned int: load expressed in percentage** Notes        : The possible range being returned is from 0 up to 100.**                Whereas 0 means 'no load at all' and 100 'system fully loaded'**                It is impossible to determine what actually causes the system**                to be in 100%, but maybe that is due to too much interrupts.*******************************************************************************/static unsigned intGetCurrentSystemLoad(SK_AC *pAC) {	unsigned long jif         = jiffies;	unsigned int  UserTime    = 0;	unsigned int  SystemTime  = 0;	unsigned int  NiceTime    = 0;	unsigned int  IdleTime    = 0;	unsigned int  TotalTime   = 0;	unsigned int  UsedTime    = 0;	unsigned int  SystemLoad  = 0;	/* unsigned int  NbrCpu      = 0; */	/*	** The following lines have been commented out, because	** from kernel 2.5.44 onwards, the kernel-owned structure	**	**      struct kernel_stat kstat	**	** is not marked as an exported symbol in the file	**	**      kernel/ksyms.c 	**	** As a consequence, using this driver as KLM is not possible	** and any access of the structure kernel_stat via the 	** dedicated macros kstat_cpu(i).cpustat.xxx is to be avoided.	**	** The kstat-information might be added again in future 	** versions of the 2.5.xx kernel, but for the time being, 	** number of interrupts will serve as indication how much 	** load we currently have... 	**	** for (NbrCpu = 0; NbrCpu < num_online_cpus(); NbrCpu++) {	**	UserTime   = UserTime   + kstat_cpu(NbrCpu).cpustat.user;	**	NiceTime   = NiceTime   + kstat_cpu(NbrCpu).cpustat.nice;	**	SystemTime = SystemTime + kstat_cpu(NbrCpu).cpustat.system;	** }	*/	SK_U64 ThresholdInts  = 0;	SK_U64 IsrCallsPerSec = 0;	ThresholdInts  = ((M_DIMINFO.MaxModIntsPerSec *			   C_INT_MOD_ENABLE_PERCENTAGE) + 100);	IsrCallsPerSec = GetIsrCalls(pAC);	if (IsrCallsPerSec >= ThresholdInts) {	    /*	    ** We do not know how much the real CPU-load is!	    ** Return 80% as a default in order to activate DIM	    */	    SystemLoad = 80;	    return (SystemLoad);  	} 	UsedTime  = UserTime + NiceTime + SystemTime;	IdleTime  = jif * num_online_cpus() - UsedTime;	TotalTime = UsedTime + IdleTime;	SystemLoad = ( 100 * (UsedTime  - M_DIMINFO.PrevUsedTime) ) /						(TotalTime - M_DIMINFO.PrevTotalTime);	if (M_DIMINFO.DisplayStats) {		printk("Current system load is: %u\n", SystemLoad);	}	M_DIMINFO.PrevTotalTime = TotalTime;	M_DIMINFO.PrevUsedTime  = UsedTime;	return (SystemLoad);}/********************************************************************************* Function     : GetIsrCalls** Description  : Depending on the selected moderation mask, this function will**                return the number of interrupts handled in the previous time-**                frame. This evaluated number is based on the current number **                of interrupts stored in PNMI-context and the previous stored **                interrupts.** Programmer   : Ralph Roesler** Last Modified: 23-mar-03** Returns      : int:   the number of interrupts being executed in the last**                       timeframe** Notes        : It makes only sense to call this function, when dynamic **                interrupt moderation is applied*******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -