diff options
-rw-r--r-- | drivers/net/vxge/vxge-config.h | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h index e7877df092f3..01595242a6e8 100644 --- a/drivers/net/vxge/vxge-config.h +++ b/drivers/net/vxge/vxge-config.h | |||
@@ -1914,20 +1914,32 @@ static inline void *vxge_os_dma_malloc(struct pci_dev *pdev, | |||
1914 | gfp_t flags; | 1914 | gfp_t flags; |
1915 | void *vaddr; | 1915 | void *vaddr; |
1916 | unsigned long misaligned = 0; | 1916 | unsigned long misaligned = 0; |
1917 | int realloc_flag = 0; | ||
1917 | *p_dma_acch = *p_dmah = NULL; | 1918 | *p_dma_acch = *p_dmah = NULL; |
1918 | 1919 | ||
1919 | if (in_interrupt()) | 1920 | if (in_interrupt()) |
1920 | flags = GFP_ATOMIC | GFP_DMA; | 1921 | flags = GFP_ATOMIC | GFP_DMA; |
1921 | else | 1922 | else |
1922 | flags = GFP_KERNEL | GFP_DMA; | 1923 | flags = GFP_KERNEL | GFP_DMA; |
1923 | 1924 | realloc: | |
1924 | size += VXGE_CACHE_LINE_SIZE; | ||
1925 | |||
1926 | vaddr = kmalloc((size), flags); | 1925 | vaddr = kmalloc((size), flags); |
1927 | if (vaddr == NULL) | 1926 | if (vaddr == NULL) |
1928 | return vaddr; | 1927 | return vaddr; |
1929 | misaligned = (unsigned long)VXGE_ALIGN(*((u64 *)&vaddr), | 1928 | misaligned = (unsigned long)VXGE_ALIGN((unsigned long)vaddr, |
1930 | VXGE_CACHE_LINE_SIZE); | 1929 | VXGE_CACHE_LINE_SIZE); |
1930 | if (realloc_flag) | ||
1931 | goto out; | ||
1932 | |||
1933 | if (misaligned) { | ||
1934 | /* misaligned, free current one and try allocating | ||
1935 | * size + VXGE_CACHE_LINE_SIZE memory | ||
1936 | */ | ||
1937 | kfree((void *) vaddr); | ||
1938 | size += VXGE_CACHE_LINE_SIZE; | ||
1939 | realloc_flag = 1; | ||
1940 | goto realloc; | ||
1941 | } | ||
1942 | out: | ||
1931 | *(unsigned long *)p_dma_acch = misaligned; | 1943 | *(unsigned long *)p_dma_acch = misaligned; |
1932 | vaddr = (void *)((u8 *)vaddr + misaligned); | 1944 | vaddr = (void *)((u8 *)vaddr + misaligned); |
1933 | return vaddr; | 1945 | return vaddr; |