# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Node ID c98a65daa7bda62fbe72f8093c6017a5f6b3d264 # Parent 139a6a3195c5c61aa08a88112126a3a944bc81b9 restrict netfront to 256 grant reference. grant ref must be smaller than MAPTRACK_MAX_ENTRIES because only 11bit of grant_mapping_t:ref_and_flags is used to track grant ref. NR_GRANT_ENTRIES must be smaller or equal to MAPTRACK_MAX_ENTRIES. PATCHNAME: restrict_netfront_to_256_grant_reference Signed-off-by: Isaku Yamahata diff -r 139a6a3195c5 -r c98a65daa7bd linux-2.6-xen-sparse/drivers/xen/core/gnttab.c --- a/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Wed Apr 12 21:56:47 2006 +0900 +++ b/linux-2.6-xen-sparse/drivers/xen/core/gnttab.c Wed Apr 12 22:00:12 2006 +0900 @@ -74,7 +74,7 @@ EXPORT_SYMBOL_GPL(gnttab_grant_foreign_t /* External tools reserve first few grant table entries. */ #define NR_RESERVED_ENTRIES 8 -#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t)) +#define NR_GRANT_ENTRIES GNTTAB_GRANT_REF_MAX #define GNTTAB_LIST_END (NR_GRANT_ENTRIES + 1) static grant_ref_t gnttab_list[NR_GRANT_ENTRIES]; @@ -442,6 +442,8 @@ gnttab_init(void) if (gnttab_resume() < 0) return -ENODEV; + BUG_ON((NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t)) < + GNTTAB_GRANT_REF_MAX); for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++) gnttab_list[i] = i + 1; gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES; diff -r 139a6a3195c5 -r c98a65daa7bd linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Apr 12 21:56:47 2006 +0900 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Apr 12 22:00:12 2006 +0900 @@ -106,7 +106,7 @@ struct netfront_info /* Receive-ring batched refills. */ #define RX_MIN_TARGET 8 #define RX_DFL_MIN_TARGET 64 -#define RX_MAX_TARGET NET_RX_RING_SIZE +#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) int rx_min_target, rx_max_target, rx_target; struct sk_buff_head rx_batch; @@ -120,6 +120,8 @@ struct netfront_info struct sk_buff *rx_skbs[NET_RX_RING_SIZE+1]; grant_ref_t gref_tx_head; +#define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) + int gref_tx_head_cnt; grant_ref_t grant_tx_ref[NET_TX_RING_SIZE + 1]; grant_ref_t gref_rx_head; grant_ref_t grant_rx_ref[NET_TX_RING_SIZE + 1]; @@ -482,8 +484,9 @@ static void network_tx_buf_gc(struct net } gnttab_end_foreign_access_ref( np->grant_tx_ref[id], GNTMAP_readonly); - gnttab_release_grant_reference( - &np->gref_tx_head, np->grant_tx_ref[id]); + gnttab_release_grant_reference(&np->gref_tx_head, + np->grant_tx_ref[id]); + np->gref_tx_head_cnt++; np->grant_tx_ref[id] = GRANT_INVALID_REF; add_id_to_freelist(np->tx_skbs, id); dev_kfree_skb_irq(skb); @@ -505,8 +508,9 @@ static void network_tx_buf_gc(struct net } while (prod != np->tx.sring->rsp_prod); out: - if (np->tx_full && - ((np->tx.sring->req_prod - prod) < NET_TX_RING_SIZE)) { + if ((np->tx_full) && + ((np->tx.sring->req_prod - prod) < NET_TX_RING_SIZE) && + (np->gref_tx_head_cnt > 0)) { np->tx_full = 0; if (np->user_state == UST_OPEN) netif_wake_queue(dev); @@ -684,6 +688,7 @@ static int network_start_xmit(struct sk_ tx->id = id; ref = gnttab_claim_grant_reference(&np->gref_tx_head); + np->gref_tx_head_cnt--; BUG_ON((signed short)ref < 0); mfn = virt_to_mfn(skb->data); gnttab_grant_foreign_access_ref( @@ -705,7 +710,7 @@ static int network_start_xmit(struct sk_ network_tx_buf_gc(dev); - if (RING_FULL(&np->tx)) { + if (RING_FULL(&np->tx) || (np->gref_tx_head_cnt == 0)) { np->tx_full = 1; netif_stop_queue(dev); } @@ -1140,14 +1145,16 @@ static int create_netdev(int handle, str } /* A grant for every tx ring slot */ - if (gnttab_alloc_grant_references(NET_TX_RING_SIZE, + if (gnttab_alloc_grant_references(TX_MAX_TARGET, &np->gref_tx_head) < 0) { printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n"); err = -ENOMEM; goto exit; } + np->gref_tx_head_cnt = TX_MAX_TARGET; + /* A grant for every rx ring slot */ - if (gnttab_alloc_grant_references(NET_RX_RING_SIZE, + if (gnttab_alloc_grant_references(RX_MAX_TARGET, &np->gref_rx_head) < 0) { printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n"); gnttab_free_grant_references(np->gref_tx_head); diff -r 139a6a3195c5 -r c98a65daa7bd xen/include/public/grant_table.h --- a/xen/include/public/grant_table.h Wed Apr 12 21:56:47 2006 +0900 +++ b/xen/include/public/grant_table.h Wed Apr 12 22:00:12 2006 +0900 @@ -132,6 +132,10 @@ typedef struct grant_entry { * Reference to a grant entry in a specified domain's grant table. */ typedef uint32_t grant_ref_t; +/* + * from xen/include/xen/grant_table.h + */ +#define GNTTAB_GRANT_REF_MAX ((uint32_t)2048U) /* * Handle to track a mapping created via a grant reference. diff -r 139a6a3195c5 -r c98a65daa7bd xen/include/xen/grant_table.h --- a/xen/include/xen/grant_table.h Wed Apr 12 21:56:47 2006 +0900 +++ b/xen/include/xen/grant_table.h Wed Apr 12 22:00:12 2006 +0900 @@ -53,8 +53,11 @@ typedef struct { #define GNTPIN_devr_mask (0xFFU << GNTPIN_devr_shift) #define NR_GRANT_FRAMES (1U << ORDER_GRANT_FRAMES) -#define NR_GRANT_ENTRIES \ - ((NR_GRANT_FRAMES << PAGE_SHIFT) / sizeof(grant_entry_t)) +#define NR_GRANT_ENTRIES \ + (min_t(unsigned int, \ + (NR_GRANT_FRAMES << PAGE_SHIFT) / sizeof(grant_entry_t), \ + MAPTRACK_MAX_ENTRIES)) + /* * Tracks a mapping of another domain's grant reference. Each domain has a