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

📄 skdim.c

📁 D-link 千兆网卡 dge530t for linux 驱动,完全基于LINUX/UNIX下的.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * * Name:	skdim.c * Project:	GEnesis, PCI Gigabit Ethernet Adapter * Version:	$Revision: 1.1 $ * Date:	$Date: 2003/03/21 14:51:50 $ * Purpose:	All functions to maintain interrupt moderation * ******************************************************************************//****************************************************************************** * *	(C)Copyright 1998-2002 SysKonnect GmbH. * *	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. * ******************************************************************************//****************************************************************************** * * History: * * ******************************************************************************//****************************************************************************** * * 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.1 2003/03/21 14:51:50 rroesler Exp $ (C) SysKonnect.";#endif	/* !defined(lint) */#define __SKADDR_C#ifdef __cplusplus#error C++ is not yet supported.extern "C" {#endif	/* cplusplus *//*********************************************************************************** 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;    int           NbrCpu      = 0;    for (NbrCpu = 0; NbrCpu < smp_num_cpus; NbrCpu++) {        UserTime   = UserTime   + kstat.per_cpu_user[NbrCpu];        NiceTime   = NiceTime   + kstat.per_cpu_nice[NbrCpu];        SystemTime = SystemTime + kstat.per_cpu_system[NbrCpu];    }    UsedTime  = UserTime + NiceTime + SystemTime;    IdleTime  = jif * smp_num_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*******************************************************************************/static SK_U64GetIsrCalls(SK_AC *pAC) {    SK_U64   RxPort0IntDiff = 0;    SK_U64   RxPort1IntDiff = 0;    SK_U64   TxPort0IntDiff = 0;    SK_U64   TxPort1IntDiff = 0;    if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_TX_ONLY) {        if (pAC->GIni.GIMacsFound == 2) {            TxPort1IntDiff = pAC->Pnmi.Port[1].TxIntrCts -                              pAC->DynIrqModInfo.PrevPort1TxIntrCts;        }        TxPort0IntDiff = pAC->Pnmi.Port[0].TxIntrCts -                          pAC->DynIrqModInfo.PrevPort0TxIntrCts;    } else if (pAC->DynIrqModInfo.MaskIrqModeration == IRQ_MASK_RX_ONLY) {

⌨️ 快捷键说明

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