@@ -141,6 +141,7 @@ struct nvme_dev {
141
141
struct nvme_ctrl ctrl ;
142
142
u32 last_ps ;
143
143
bool hmb ;
144
+ struct sg_table * hmb_sgt ;
144
145
145
146
mempool_t * iod_mempool ;
146
147
@@ -1952,7 +1953,7 @@ static int nvme_set_host_mem(struct nvme_dev *dev, u32 bits)
1952
1953
return ret ;
1953
1954
}
1954
1955
1955
- static void nvme_free_host_mem (struct nvme_dev * dev )
1956
+ static void nvme_free_host_mem_multi (struct nvme_dev * dev )
1956
1957
{
1957
1958
int i ;
1958
1959
@@ -1967,14 +1968,50 @@ static void nvme_free_host_mem(struct nvme_dev *dev)
1967
1968
1968
1969
kfree (dev -> host_mem_desc_bufs );
1969
1970
dev -> host_mem_desc_bufs = NULL ;
1971
+ }
1972
+
1973
+ static void nvme_free_host_mem (struct nvme_dev * dev )
1974
+ {
1975
+ if (dev -> hmb_sgt )
1976
+ dma_free_noncontiguous (dev -> dev , dev -> host_mem_size ,
1977
+ dev -> hmb_sgt , DMA_BIDIRECTIONAL );
1978
+ else
1979
+ nvme_free_host_mem_multi (dev );
1980
+
1970
1981
dma_free_coherent (dev -> dev , dev -> host_mem_descs_size ,
1971
1982
dev -> host_mem_descs , dev -> host_mem_descs_dma );
1972
1983
dev -> host_mem_descs = NULL ;
1973
1984
dev -> host_mem_descs_size = 0 ;
1974
1985
dev -> nr_host_mem_descs = 0 ;
1975
1986
}
1976
1987
1977
- static int __nvme_alloc_host_mem (struct nvme_dev * dev , u64 preferred ,
1988
+ static int nvme_alloc_host_mem_single (struct nvme_dev * dev , u64 size )
1989
+ {
1990
+ dev -> hmb_sgt = dma_alloc_noncontiguous (dev -> dev , size ,
1991
+ DMA_BIDIRECTIONAL , GFP_KERNEL , 0 );
1992
+ if (!dev -> hmb_sgt )
1993
+ return - ENOMEM ;
1994
+
1995
+ dev -> host_mem_descs = dma_alloc_coherent (dev -> dev ,
1996
+ sizeof (* dev -> host_mem_descs ), & dev -> host_mem_descs_dma ,
1997
+ GFP_KERNEL );
1998
+ if (!dev -> host_mem_descs ) {
1999
+ dma_free_noncontiguous (dev -> dev , dev -> host_mem_size ,
2000
+ dev -> hmb_sgt , DMA_BIDIRECTIONAL );
2001
+ dev -> hmb_sgt = NULL ;
2002
+ return - ENOMEM ;
2003
+ }
2004
+ dev -> host_mem_size = size ;
2005
+ dev -> host_mem_descs_size = sizeof (* dev -> host_mem_descs );
2006
+ dev -> nr_host_mem_descs = 1 ;
2007
+
2008
+ dev -> host_mem_descs [0 ].addr =
2009
+ cpu_to_le64 (dev -> hmb_sgt -> sgl -> dma_address );
2010
+ dev -> host_mem_descs [0 ].size = cpu_to_le32 (size / NVME_CTRL_PAGE_SIZE );
2011
+ return 0 ;
2012
+ }
2013
+
2014
+ static int nvme_alloc_host_mem_multi (struct nvme_dev * dev , u64 preferred ,
1978
2015
u32 chunk_size )
1979
2016
{
1980
2017
struct nvme_host_mem_buf_desc * descs ;
@@ -2049,9 +2086,18 @@ static int nvme_alloc_host_mem(struct nvme_dev *dev, u64 min, u64 preferred)
2049
2086
u64 hmminds = max_t (u32 , dev -> ctrl .hmminds * 4096 , PAGE_SIZE * 2 );
2050
2087
u64 chunk_size ;
2051
2088
2089
+ /*
2090
+ * If there is an IOMMU that can merge pages, try a virtually
2091
+ * non-contiguous allocation for a single segment first.
2092
+ */
2093
+ if (!(PAGE_SIZE & dma_get_merge_boundary (dev -> dev ))) {
2094
+ if (!nvme_alloc_host_mem_single (dev , preferred ))
2095
+ return 0 ;
2096
+ }
2097
+
2052
2098
/* start big and work our way down */
2053
2099
for (chunk_size = min_chunk ; chunk_size >= hmminds ; chunk_size /= 2 ) {
2054
- if (!__nvme_alloc_host_mem (dev , preferred , chunk_size )) {
2100
+ if (!nvme_alloc_host_mem_multi (dev , preferred , chunk_size )) {
2055
2101
if (!min || dev -> host_mem_size >= min )
2056
2102
return 0 ;
2057
2103
nvme_free_host_mem (dev );
@@ -2099,8 +2145,10 @@ static int nvme_setup_host_mem(struct nvme_dev *dev)
2099
2145
}
2100
2146
2101
2147
dev_info (dev -> ctrl .device ,
2102
- "allocated %lld MiB host memory buffer.\n" ,
2103
- dev -> host_mem_size >> ilog2 (SZ_1M ));
2148
+ "allocated %lld MiB host memory buffer (%u segment%s).\n" ,
2149
+ dev -> host_mem_size >> ilog2 (SZ_1M ),
2150
+ dev -> nr_host_mem_descs ,
2151
+ str_plural (dev -> nr_host_mem_descs ));
2104
2152
}
2105
2153
2106
2154
ret = nvme_set_host_mem (dev , enable_bits );
0 commit comments