/****************************************************************************** * drivers/xen/netback/netback.c * * Back-end of the driver for virtual network devices. This portion of the * driver exports a 'unified' network-device interface that can be accessed * by any operating system that implements a compatible front end. A * reference front-end implementation can be found in: * drivers/xen/netfront/netfront.c * * Copyright (c) 2002-2005, K A Fraser */ #include "common.h" #include #include /*#define NETBE_DEBUG_INTERRUPT*/ static void netif_idx_release(u16 pending_idx); static void netif_page_release(struct page *page); static void make_tx_response(netif_t *netif, u16 id, s8 st); static int make_rx_response(netif_t *netif, u16 id, s8 st, u16 offset, u16 size, u16 flags); static void net_tx_action(unsigned long unused); static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0); static void net_rx_action(unsigned long unused); static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0); static struct timer_list net_timer; #define MAX_PENDING_REQS 256 static struct sk_buff_head rx_queue; static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1]; static mmu_update_t rx_mmu[NET_RX_RING_SIZE]; static gnttab_transfer_t grant_rx_op[NET_RX_RING_SIZE]; static unsigned char rx_notify[NR_IRQS]; static unsigned long mmap_vstart; #define MMAP_VADDR(_req) (mmap_vstart + ((_req) * PAGE_SIZE)) #define PKT_PROT_LEN 64 static struct { netif_tx_request_t req; netif_t *netif; } pending_tx_info[MAX_PENDING_REQS]; static u16 pending_ring[MAX_PENDING_REQS]; typedef unsigned int PEND_RING_IDX; #define MASK_PEND_IDX(_i) ((_i)&(MAX_PENDING_REQS-1)) static PEND_RING_IDX pending_prod, pending_cons; #define NR_PENDING_REQS (MAX_PENDING_REQS - pending_prod + pending_cons) /* Freed TX SKBs get batched on this ring before return to pending_ring. */ static u16 dealloc_ring[MAX_PENDING_REQS]; static PEND_RING_IDX dealloc_prod, dealloc_cons; static struct sk_buff_head tx_queue; static grant_handle_t grant_tx_handle[MAX_PENDING_REQS]; static gnttab_unmap_grant_ref_t tx_unmap_ops[MAX_PENDING_REQS]; static gnttab_map_grant_ref_t tx_map_ops[MAX_PENDING_REQS]; static struct list_head net_schedule_list; static spinlock_t net_schedule_list_lock; #define MAX_MFN_ALLOC 64 static unsigned long mfn_list[MAX_MFN_ALLOC]; static unsigned int alloc_index = 0; static spinlock_t mfn_lock = SPIN_LOCK_UNLOCKED; static unsigned long alloc_mfn(void) { unsigned long mfn = 0, flags; struct xen_memory_reservation reservation = { .extent_start = mfn_list, .nr_extents = MAX_MFN_ALLOC, .extent_order = 0, .domid = DOMID_SELF }; spin_lock_irqsave(&mfn_lock, flags); if ( unlikely(alloc_index == 0) ) alloc_index = HYPERVISOR_memory_op( XENMEM_increase_reservation, &reservation); if ( alloc_index != 0 ) mfn = mfn_list[--alloc_index]; spin_unlock_irqrestore(&mfn_lock, flags); return mfn; } static inline void maybe_schedule_tx_action(void) { smp_mb(); if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) && !list_empty(&net_schedule_list)) tasklet_schedule(&net_tx_tasklet); } /* * A gross way of confirming the origin of an skb data page. The slab * allocator abuses a field in the page struct to cache the kmem_cache_t ptr. */ static inline int is_xen_skb(struct sk_buff *skb) { extern kmem_cache_t *skbuff_cachep; kmem_cache_t *cp = (kmem_cache_t *)virt_to_page(skb->head)->lru.next; return (cp == skbuff_cachep); } int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) { netif_t *netif = netdev_priv(dev); BUG_ON(skb->dev != dev); /* Drop the packet if the target domain has no receive buffers. */ if (!netif->active || (netif->rx_req_cons_peek == netif->rx.sring->req_prod) || ((netif->rx_req_cons_peek - netif->rx.rsp_prod_pvt) == NET_RX_RING_SIZE)) goto drop; /* * We do not copy the packet unless: * 1. The data is shared; or * 2. The data is not allocated from our special cache. * NB. We also couldn't cope with fragmented packets, but we won't get * any because we not advertise the NETIF_F_SG feature. */ if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) { int hlen = skb->data - skb->head; int ret; struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len); if ( unlikely(nskb == NULL) ) goto drop; skb_reserve(nskb, hlen); __skb_put(nskb, skb->len); ret = skb_copy_bits(skb, -hlen, nskb->data - hlen, skb->len + hlen); BUG_ON(ret); nskb->dev = skb->dev; nskb->proto_csum_valid = skb->proto_csum_valid; dev_kfree_skb(skb); skb = nskb; } netif->rx_req_cons_peek++; netif_get(netif); skb_queue_tail(&rx_queue, skb); tasklet_schedule(&net_rx_tasklet); return 0; drop: netif->stats.tx_dropped++; dev_kfree_skb(skb); return 0; } #if 0 static void xen_network_done_notify(void) { static struct net_device *eth0_dev = NULL; if (unlikely(eth0_dev == NULL)) eth0_dev = __dev_get_by_name("eth0"); netif_rx_schedule(eth0_dev); } /* * Add following to poll() function in NAPI driver (Tigon3 is example): * if ( xen_network_done() ) * tg3_enable_ints(tp); */ int xen_network_done(void) { return skb_queue_empty(&rx_queue); } #endif static void net_rx_action(unsigned long unused) { netif_t *netif = NULL; s8 status; u16 size, id, irq; multicall_entry_t *mcl; mmu_update_t *mmu; gnttab_transfer_t *gop; unsigned long vdata, old_mfn, new_mfn; struct sk_buff_head rxq; struct sk_buff *skb; u16 notify_list[NET_RX_RING_SIZE]; int notify_nr = 0; int ret; skb_queue_head_init(&rxq); mcl = rx_mcl; mmu = rx_mmu; gop = grant_rx_op; while ((skb = skb_dequeue(&rx_queue)) != NULL) { netif = netdev_priv(skb->dev); vdata = (unsigned long)skb->data; old_mfn = virt_to_mfn(vdata); /* Memory squeeze? Back off for an arbitrary while. */ if ((new_mfn = alloc_mfn()) == 0) { if ( net_ratelimit() ) WPRINTK("Memory squeeze in netback driver.\n"); mod_timer(&net_timer, jiffies + HZ); skb_queue_head(&rx_queue, skb); break; } /* * Set the new P2M table entry before reassigning the old data * page. Heed the comment in pgtable-2level.h:pte_page(). :-) */ set_phys_to_machine(__pa(skb->data) >> PAGE_SHIFT, new_mfn); MULTI_update_va_mapping(mcl, vdata, pfn_pte_ma(new_mfn, PAGE_KERNEL), 0); mcl++; gop->mfn = old_mfn; gop->domid = netif->domid; gop->ref = RING_GET_REQUEST( &netif->rx, netif->rx.req_cons)->gref; netif->rx.req_cons++; gop++; if (!xen_feature(XENFEAT_auto_translated_physmap)) { mmu->ptr = ((maddr_t)new_mfn << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE; mmu->val = __pa(vdata) >> PAGE_SHIFT; mmu++; } __skb_queue_tail(&rxq, skb); /* Filled the batch queue? */ if ((gop - grant_rx_op) == ARRAY_SIZE(grant_rx_op)) break; } if (mcl == rx_mcl) return; mcl[-1].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; if (mmu - rx_mmu) { mcl->op = __HYPERVISOR_mmu_update; mcl->args[0] = (unsigned long)rx_mmu; mcl->args[1] = mmu - rx_mmu; mcl->args[2] = 0; mcl->args[3] = DOMID_SELF; mcl++; } ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); BUG_ON(ret != 0); ret = HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, gop - grant_rx_op); BUG_ON(ret != 0); mcl = rx_mcl; gop = grant_rx_op; while ((skb = __skb_dequeue(&rxq)) != NULL) { netif = netdev_priv(skb->dev); size = skb->tail - skb->data; /* Rederive the machine addresses. */ new_mfn = mcl->args[1] >> PAGE_SHIFT; old_mfn = gop->mfn; atomic_set(&(skb_shinfo(skb)->dataref), 1); skb_shinfo(skb)->nr_frags = 0; skb_shinfo(skb)->frag_list = NULL; netif->stats.tx_bytes += size; netif->stats.tx_packets++; /* The update_va_mapping() must not fail. */ BUG_ON(mcl->result != 0); /* Check the reassignment error code. */ status = NETIF_RSP_OKAY; if (g
namespace CPUMonitor
{
    partial class frmCPU
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.serSerialPort = new System.IO.Ports.SerialPort(this.components);
            this.tmrCPUTimer = new System.Windows.Forms.Timer(this.components);
            this.cmbComPort = new System.Windows.Forms.ComboBox();
            this.pcCPUUsage = new System.Diagnostics.PerformanceCounter();
            this.lblCPU = new System.Windows.Forms.Label();
            this.nicoNotifyIcon = new System.Windows.Forms.NotifyIcon(this.components);
            this.btnMinimizeToTray = new System.Windows.Forms.Button();
            this.btnExit = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.pcCPUUsage)).BeginInit();
            this.SuspendLayout();
            // 
            // tmrCPUTimer
            // 
            this.tmrCPUTimer.Enabled = true;
            this.tmrCPUTimer.Interval = 1000;
            this.tmrCPUTimer.Tick += new System.EventHandler(this.tmrCPUTimer_Tick);
            // 
            // cmbComPort
            // 
            this.cmbComPort.FormattingEnabled = true;
            this.cmbComPort.Location = new System.Drawing.Point(48, 12);
            this.cmbComPort.Name = "cmbComPort";
            this.cmbComPort.Size = new System.Drawing.Size(156, 21);
            this.cmbComPort.TabIndex = 0;
            this.cmbComPort.SelectedIndexChanged += new System.EventHandler(this.cbPort_SelectedIndexChanged);
            // 
            // pcCPUUsage
            // 
            this.pcCPUUsage.CategoryName = "Processor";
            this.pcCPUUsage.CounterName = "% Processor Time";
            this.pcCPUUsage.InstanceName = "_Total";
            // 
            // lblCPU
            // 
            this.lblCPU.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblCPU.Location = new System.Drawing.Point(44, 36);
            this.lblCPU.Name = "lblCPU";
            this.lblCPU.Size = new System.Drawing.Size(160, 28);
            this.lblCPU.TabIndex = 1;
            this.lblCPU.Text = "0%";
            this.lblCPU.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // nicoNotifyIcon
            // 
            this.nicoNotifyIcon.Text = "CPU Usage Monitor";
            this.nicoNotifyIcon.Visible = true;
            // 
            // btnMinimizeToTray
            // 
            this.btnMinimizeToTray.Location = new System.Drawing.Point(12, 67);
            this.btnMinimizeToTray.Name = "btnMinimizeToTray";
            this.btnMinimizeToTray.Size = new System.Drawing.Size(111, 28);
            this.btnMinimizeToTray.TabIndex = 2;
            this.btnMinimizeToTray.Text = "Minimize to Tray";
            this.btnMinimizeToTray.UseVisualStyleBackColor = true;
            this.btnMinimizeToTray.Click += new System.EventHandler(this.btnMinimizeToTray_Click);
            // 
            // btnExit
            // 
            this.btnExit.Location = new System.Drawing.Point(126, 67);
            this.btnExit.Name = "btnExit";
            this.btnExit.Size = new System.Drawing.Size(111, 28);
            this.btnExit.TabIndex = 3;
            this.btnExit.Text = "Exit";
            this.btnExit.UseVisualStyleBackColor = true;
            this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
            // 
            // frmCPU
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(249, 106);
            this.Controls.Add(this.btnExit);
            this.Controls.Add(this.btnMinimizeToTray);
            this.Controls.Add(this.lblCPU);
            this.Controls.Add(this.cmbComPort);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.Name = "frmCPU";
            this.Text = "CPU Usage Monitor";
            this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.pcCPUUsage)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.IO.Ports.SerialPort serSerialPort;
        private System.Windows.Forms.Timer tmrCPUTimer;
        private System.Windows.Forms.ComboBox cmbComPort;
        private System.Diagnostics.PerformanceCounter pcCPUUsage;
        private System.Windows.Forms.Label lblCPU;
        private System.Windows.Forms.NotifyIcon nicoNotifyIcon;
        private System.Windows.Forms.Button btnMinimizeToTray;
        private System.Windows.Forms.Button btnExit;
    }
}