* [PATCH 05/16] drm: don't mark pages returned from drm_pci_alloc reserved
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
We are not allowed to call virt_to_page on pages returned from
dma_alloc_coherent, as in many cases the virtual address returned
is aactually a kernel direct mapping. Also there generally is no
need to mark dma memory as reserved.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/gpu/drm/drm_bufs.c | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 7418872d87c6..b640437ce90f 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -77,13 +77,6 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali
return NULL;
}
- /* XXX - Is virt_to_page() legal for consistent mem? */
- /* Reserve */
- for (addr = (unsigned long)dmah->vaddr, sz = size;
- sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
- SetPageReserved(virt_to_page((void *)addr));
- }
-
return dmah;
}
@@ -97,16 +90,9 @@ void __drm_legacy_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
unsigned long addr;
size_t sz;
- if (dmah->vaddr) {
- /* XXX - Is virt_to_page() legal for consistent mem? */
- /* Unreserve */
- for (addr = (unsigned long)dmah->vaddr, sz = dmah->size;
- sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
- ClearPageReserved(virt_to_page((void *)addr));
- }
+ if (dmah->vaddr)
dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
dmah->busaddr);
- }
}
/**
--
2.20.1
^ permalink raw reply related
* [PATCH 09/16] cnic: stop passing bogus gfp flags arguments to dma_alloc_coherent
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
dma_alloc_coherent is not just the page allocator. The only valid
arguments to pass are either GFP_ATOMIC or GFP_ATOMIC with possible
modifiers of __GFP_NORETRY or __GFP_NOWARN.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/net/ethernet/broadcom/cnic.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index 57dc3cbff36e..bd1c993680e5 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -1028,7 +1028,7 @@ static int __cnic_alloc_uio_rings(struct cnic_uio_dev *udev, int pages)
udev->l2_ring_size = pages * CNIC_PAGE_SIZE;
udev->l2_ring = dma_alloc_coherent(&udev->pdev->dev, udev->l2_ring_size,
&udev->l2_ring_map,
- GFP_KERNEL | __GFP_COMP);
+ GFP_KERNEL);
if (!udev->l2_ring)
return -ENOMEM;
@@ -1036,7 +1036,7 @@ static int __cnic_alloc_uio_rings(struct cnic_uio_dev *udev, int pages)
udev->l2_buf_size = CNIC_PAGE_ALIGN(udev->l2_buf_size);
udev->l2_buf = dma_alloc_coherent(&udev->pdev->dev, udev->l2_buf_size,
&udev->l2_buf_map,
- GFP_KERNEL | __GFP_COMP);
+ GFP_KERNEL);
if (!udev->l2_buf) {
__cnic_free_uio_rings(udev);
return -ENOMEM;
--
2.20.1
^ permalink raw reply related
* [PATCH 07/16] IB/hfi1: stop passing bogus gfp flags arguments to dma_alloc_coherent
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
dma_alloc_coherent is not just the page allocator. The only valid
arguments to pass are either GFP_ATOMIC or GFP_ATOMIC with possible
modifiers of __GFP_NORETRY or __GFP_NOWARN.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/infiniband/hw/hfi1/init.c | 22 +++-------------------
1 file changed, 3 insertions(+), 19 deletions(-)
diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c
index 71cb9525c074..ff9d106ee784 100644
--- a/drivers/infiniband/hw/hfi1/init.c
+++ b/drivers/infiniband/hw/hfi1/init.c
@@ -1846,17 +1846,10 @@ int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
u64 reg;
if (!rcd->rcvhdrq) {
- gfp_t gfp_flags;
-
amt = rcvhdrq_size(rcd);
- if (rcd->ctxt < dd->first_dyn_alloc_ctxt || rcd->is_vnic)
- gfp_flags = GFP_KERNEL;
- else
- gfp_flags = GFP_USER;
rcd->rcvhdrq = dma_alloc_coherent(&dd->pcidev->dev, amt,
- &rcd->rcvhdrq_dma,
- gfp_flags | __GFP_COMP);
+ &rcd->rcvhdrq_dma, GFP_KERNEL);
if (!rcd->rcvhdrq) {
dd_dev_err(dd,
@@ -1870,7 +1863,7 @@ int hfi1_create_rcvhdrq(struct hfi1_devdata *dd, struct hfi1_ctxtdata *rcd)
rcd->rcvhdrtail_kvaddr = dma_alloc_coherent(&dd->pcidev->dev,
PAGE_SIZE,
&rcd->rcvhdrqtailaddr_dma,
- gfp_flags);
+ GFP_KERNEL);
if (!rcd->rcvhdrtail_kvaddr)
goto bail_free;
}
@@ -1926,19 +1919,10 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd)
{
struct hfi1_devdata *dd = rcd->dd;
u32 max_entries, egrtop, alloced_bytes = 0;
- gfp_t gfp_flags;
u16 order, idx = 0;
int ret = 0;
u16 round_mtu = roundup_pow_of_two(hfi1_max_mtu);
- /*
- * GFP_USER, but without GFP_FS, so buffer cache can be
- * coalesced (we hope); otherwise, even at order 4,
- * heavy filesystem activity makes these fail, and we can
- * use compound pages.
- */
- gfp_flags = __GFP_RECLAIM | __GFP_IO | __GFP_COMP;
-
/*
* The minimum size of the eager buffers is a groups of MTU-sized
* buffers.
@@ -1969,7 +1953,7 @@ int hfi1_setup_eagerbufs(struct hfi1_ctxtdata *rcd)
dma_alloc_coherent(&dd->pcidev->dev,
rcd->egrbufs.rcvtid_size,
&rcd->egrbufs.buffers[idx].dma,
- gfp_flags);
+ GFP_KERNEL);
if (rcd->egrbufs.buffers[idx].addr) {
rcd->egrbufs.buffers[idx].len =
rcd->egrbufs.rcvtid_size;
--
2.20.1
^ permalink raw reply related
* [PATCH 11/16] s390/ism: stop passing bogus gfp flags arguments to dma_alloc_coherent
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
dma_alloc_coherent is not just the page allocator. The only valid
arguments to pass are either GFP_ATOMIC or GFP_ATOMIC with possible
modifiers of __GFP_NORETRY or __GFP_NOWARN.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/s390/net/ism_drv.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index 4fc2056bd227..4ff5506fa4c6 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -241,7 +241,8 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct smcd_dmb *dmb)
dmb->cpu_addr = dma_alloc_coherent(&ism->pdev->dev, dmb->dmb_len,
&dmb->dma_addr,
- GFP_KERNEL | __GFP_NOWARN | __GFP_NOMEMALLOC | __GFP_COMP | __GFP_NORETRY);
+ GFP_KERNEL | __GFP_NOWARN |
+ __GFP_NORETRY);
if (!dmb->cpu_addr)
clear_bit(dmb->sba_idx, ism->sba_bitmap);
--
2.20.1
^ permalink raw reply related
* [PATCH 13/16] mm: rename alloc_pages_exact_nid to alloc_pages_exact_node
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
This fits in with the naming scheme used by alloc_pages_node.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/gfp.h | 2 +-
mm/page_alloc.c | 4 ++--
mm/page_ext.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index fb07b503dc45..4274ea6bc72b 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -532,7 +532,7 @@ extern unsigned long get_zeroed_page(gfp_t gfp_mask);
void *alloc_pages_exact(size_t size, gfp_t gfp_mask);
void free_pages_exact(void *virt, size_t size);
-void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask);
+void * __meminit alloc_pages_exact_node(int nid, size_t size, gfp_t gfp_mask);
#define __get_free_page(gfp_mask) \
__get_free_pages((gfp_mask), 0)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d66bc8abe0af..dd2fed66b656 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4888,7 +4888,7 @@ void *alloc_pages_exact(size_t size, gfp_t gfp_mask)
EXPORT_SYMBOL(alloc_pages_exact);
/**
- * alloc_pages_exact_nid - allocate an exact number of physically-contiguous
+ * alloc_pages_exact_node - allocate an exact number of physically-contiguous
* pages on a node.
* @nid: the preferred node ID where memory should be allocated
* @size: the number of bytes to allocate
@@ -4899,7 +4899,7 @@ EXPORT_SYMBOL(alloc_pages_exact);
*
* Return: pointer to the allocated area or %NULL in case of error.
*/
-void * __meminit alloc_pages_exact_nid(int nid, size_t size, gfp_t gfp_mask)
+void * __meminit alloc_pages_exact_node(int nid, size_t size, gfp_t gfp_mask)
{
unsigned int order = get_order(size);
struct page *p;
diff --git a/mm/page_ext.c b/mm/page_ext.c
index d8f1aca4ad43..bca6bb316714 100644
--- a/mm/page_ext.c
+++ b/mm/page_ext.c
@@ -215,7 +215,7 @@ static void *__meminit alloc_page_ext(size_t size, int nid)
gfp_t flags = GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN;
void *addr = NULL;
- addr = alloc_pages_exact_nid(nid, size, flags);
+ addr = alloc_pages_exact_node(nid, size, flags);
if (addr) {
kmemleak_alloc(addr, size, 1, flags);
return addr;
--
2.20.1
^ permalink raw reply related
* [PATCH 12/16] staging/comedi: mark as broken
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
comedi_buf.c abuse the DMA API in gravely broken ways, as it assumes it
can call virt_to_page on the result, and the just remap it as uncached
using vmap. Disable the driver until this API abuse has been fixed.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/staging/comedi/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index 049b659fa6ad..e7c021d76cfa 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
config COMEDI
tristate "Data acquisition support (comedi)"
+ depends on BROKEN
help
Enable support for a wide range of data acquisition devices
for Linux.
--
2.20.1
^ permalink raw reply related
* [PATCH 15/16] dma-mapping: clear __GFP_COMP in dma_alloc_attrs
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
Lift the code to clear __GFP_COMP from arm into the common DMA
allocator path. For one this fixes the various other patches that
call alloc_pages_exact or split_page in case a bogus driver passes
the argument, and it also prepares for doing exact allocation in
the generic dma-direct allocator.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/arm/mm/dma-mapping.c | 17 -----------------
kernel/dma/mapping.c | 9 +++++++++
2 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 0a75058c11f3..86135feb2c05 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -759,14 +759,6 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
if (mask < 0xffffffffULL)
gfp |= GFP_DMA;
- /*
- * Following is a work-around (a.k.a. hack) to prevent pages
- * with __GFP_COMP being passed to split_page() which cannot
- * handle them. The real problem is that this flag probably
- * should be 0 on ARM as it is not supported on this
- * platform; see CONFIG_HUGETLBFS.
- */
- gfp &= ~(__GFP_COMP);
args.gfp = gfp;
*handle = DMA_MAPPING_ERROR;
@@ -1527,15 +1519,6 @@ static void *__arm_iommu_alloc_attrs(struct device *dev, size_t size,
return __iommu_alloc_simple(dev, size, gfp, handle,
coherent_flag, attrs);
- /*
- * Following is a work-around (a.k.a. hack) to prevent pages
- * with __GFP_COMP being passed to split_page() which cannot
- * handle them. The real problem is that this flag probably
- * should be 0 on ARM as it is not supported on this
- * platform; see CONFIG_HUGETLBFS.
- */
- gfp &= ~(__GFP_COMP);
-
pages = __iommu_alloc_buffer(dev, size, gfp, attrs, coherent_flag);
if (!pages)
return NULL;
diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
index f7afdadb6770..4b618e1abbc1 100644
--- a/kernel/dma/mapping.c
+++ b/kernel/dma/mapping.c
@@ -252,6 +252,15 @@ void *dma_alloc_attrs(struct device *dev, size_t size, dma_addr_t *dma_handle,
/* let the implementation decide on the zone to allocate from: */
flag &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
+ /*
+ * __GFP_COMP interacts badly with splitting up a larger order
+ * allocation. But as our allocations might not even come from the
+ * page allocator, the callers can't rely on the fact that they
+ * even get pages, never mind which kind.
+ */
+ if (WARN_ON_ONCE(flag & __GFP_COMP))
+ flag &= ~__GFP_COMP;
+
if (dma_is_direct(ops))
cpu_addr = dma_direct_alloc(dev, size, dma_handle, flag, attrs);
else if (ops->alloc)
--
2.20.1
^ permalink raw reply related
* [PATCH 14/16] mm: use alloc_pages_exact_node to implement alloc_pages_exact
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
No need to duplicate the logic over two functions that are almost the
same.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/gfp.h | 5 +++--
mm/page_alloc.c | 39 +++++++--------------------------------
2 files changed, 10 insertions(+), 34 deletions(-)
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 4274ea6bc72b..c616a23a3f81 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -530,9 +530,10 @@ extern struct page *alloc_pages_vma(gfp_t gfp_mask, int order,
extern unsigned long __get_free_pages(gfp_t gfp_mask, unsigned int order);
extern unsigned long get_zeroed_page(gfp_t gfp_mask);
-void *alloc_pages_exact(size_t size, gfp_t gfp_mask);
void free_pages_exact(void *virt, size_t size);
-void * __meminit alloc_pages_exact_node(int nid, size_t size, gfp_t gfp_mask);
+void *alloc_pages_exact_node(int nid, size_t size, gfp_t gfp_mask);
+#define alloc_pages_exact(size, gfp_mask) \
+ alloc_pages_exact_node(NUMA_NO_NODE, size, gfp_mask)
#define __get_free_page(gfp_mask) \
__get_free_pages((gfp_mask), 0)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index dd2fed66b656..dec68bd21a71 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4859,34 +4859,6 @@ static void *make_alloc_exact(unsigned long addr, unsigned int order,
return (void *)addr;
}
-/**
- * alloc_pages_exact - allocate an exact number physically-contiguous pages.
- * @size: the number of bytes to allocate
- * @gfp_mask: GFP flags for the allocation, must not contain __GFP_COMP
- *
- * This function is similar to alloc_pages(), except that it allocates the
- * minimum number of pages to satisfy the request. alloc_pages() can only
- * allocate memory in power-of-two pages.
- *
- * This function is also limited by MAX_ORDER.
- *
- * Memory allocated by this function must be released by free_pages_exact().
- *
- * Return: pointer to the allocated area or %NULL in case of error.
- */
-void *alloc_pages_exact(size_t size, gfp_t gfp_mask)
-{
- unsigned int order = get_order(size);
- unsigned long addr;
-
- if (WARN_ON_ONCE(gfp_mask & __GFP_COMP))
- gfp_mask &= ~__GFP_COMP;
-
- addr = __get_free_pages(gfp_mask, order);
- return make_alloc_exact(addr, order, size);
-}
-EXPORT_SYMBOL(alloc_pages_exact);
-
/**
* alloc_pages_exact_node - allocate an exact number of physically-contiguous
* pages on a node.
@@ -4894,12 +4866,15 @@ EXPORT_SYMBOL(alloc_pages_exact);
* @size: the number of bytes to allocate
* @gfp_mask: GFP flags for the allocation, must not contain __GFP_COMP
*
- * Like alloc_pages_exact(), but try to allocate on node nid first before falling
- * back.
+ * This function is similar to alloc_pages_node(), except that it allocates the
+ * minimum number of pages to satisfy the request while alloc_pages() can only
+ * allocate memory in power-of-two pages. This function is also limited by
+ * MAX_ORDER.
*
- * Return: pointer to the allocated area or %NULL in case of error.
+ * Returns a pointer to the allocated area or %NULL in case of error, memory
+ * allocated by this function must be released by free_pages_exact().
*/
-void * __meminit alloc_pages_exact_node(int nid, size_t size, gfp_t gfp_mask)
+void *alloc_pages_exact_node(int nid, size_t size, gfp_t gfp_mask)
{
unsigned int order = get_order(size);
struct page *p;
--
2.20.1
^ permalink raw reply related
* [PATCH 16/16] dma-mapping: use exact allocation in dma_alloc_contiguous
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
Many architectures (e.g. arm, m68 and sh) have always used exact
allocation in their dma coherent allocator, which avoids a lot of
memory waste especially for larger allocations. Lift this behavior
into the generic allocator so that dma-direct and the generic IOMMU
code benefit from this behavior as well.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/dma-contiguous.h | 8 +++++---
kernel/dma/contiguous.c | 17 +++++++++++------
2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/include/linux/dma-contiguous.h b/include/linux/dma-contiguous.h
index c05d4e661489..2e542e314acf 100644
--- a/include/linux/dma-contiguous.h
+++ b/include/linux/dma-contiguous.h
@@ -161,15 +161,17 @@ static inline struct page *dma_alloc_contiguous(struct device *dev, size_t size,
gfp_t gfp)
{
int node = dev ? dev_to_node(dev) : NUMA_NO_NODE;
- size_t align = get_order(PAGE_ALIGN(size));
+ void *cpu_addr = alloc_pages_exact_node(node, size, gfp);
- return alloc_pages_node(node, gfp, align);
+ if (!cpu_addr)
+ return NULL;
+ return virt_to_page(p);
}
static inline void dma_free_contiguous(struct device *dev, struct page *page,
size_t size)
{
- __free_pages(page, get_order(size));
+ free_pages_exact(page_address(page), get_order(size));
}
#endif
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
index bfc0c17f2a3d..84f41eea2741 100644
--- a/kernel/dma/contiguous.c
+++ b/kernel/dma/contiguous.c
@@ -232,9 +232,8 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
{
int node = dev ? dev_to_node(dev) : NUMA_NO_NODE;
size_t count = PAGE_ALIGN(size) >> PAGE_SHIFT;
- size_t align = get_order(PAGE_ALIGN(size));
- struct page *page = NULL;
struct cma *cma = NULL;
+ void *cpu_addr;
if (dev && dev->cma_area)
cma = dev->cma_area;
@@ -243,14 +242,20 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
/* CMA can be used only in the context which permits sleeping */
if (cma && gfpflags_allow_blocking(gfp)) {
+ size_t align = get_order(PAGE_ALIGN(size));
+ struct page *page;
+
align = min_t(size_t, align, CONFIG_CMA_ALIGNMENT);
page = cma_alloc(cma, count, align, gfp & __GFP_NOWARN);
+ if (page)
+ return page;
}
/* Fallback allocation of normal pages */
- if (!page)
- page = alloc_pages_node(node, gfp, align);
- return page;
+ cpu_addr = alloc_pages_exact_node(node, size, gfp);
+ if (!cpu_addr)
+ return NULL;
+ return virt_to_page(cpu_addr);
}
/**
@@ -267,7 +272,7 @@ struct page *dma_alloc_contiguous(struct device *dev, size_t size, gfp_t gfp)
void dma_free_contiguous(struct device *dev, struct page *page, size_t size)
{
if (!cma_release(dev_get_cma_area(dev), page, size >> PAGE_SHIFT))
- __free_pages(page, get_order(size));
+ free_pages_exact(page_address(page), get_order(size));
}
/*
--
2.20.1
^ permalink raw reply related
* [PATCH 08/16] IB/qib: stop passing bogus gfp flags arguments to dma_alloc_coherent
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
dma_alloc_coherent is not just the page allocator. The only valid
arguments to pass are either GFP_ATOMIC or GFP_ATOMIC with possible
modifiers of __GFP_NORETRY or __GFP_NOWARN.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/infiniband/hw/qib/qib_iba6120.c | 2 +-
drivers/infiniband/hw/qib/qib_init.c | 20 +++-----------------
2 files changed, 4 insertions(+), 18 deletions(-)
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c
index 531d8a1db2c3..d8a0b8993d22 100644
--- a/drivers/infiniband/hw/qib/qib_iba6120.c
+++ b/drivers/infiniband/hw/qib/qib_iba6120.c
@@ -2076,7 +2076,7 @@ static void alloc_dummy_hdrq(struct qib_devdata *dd)
dd->cspec->dummy_hdrq = dma_alloc_coherent(&dd->pcidev->dev,
dd->rcd[0]->rcvhdrq_size,
&dd->cspec->dummy_hdrq_phys,
- GFP_ATOMIC | __GFP_COMP);
+ GFP_ATOMIC);
if (!dd->cspec->dummy_hdrq) {
qib_devinfo(dd->pcidev, "Couldn't allocate dummy hdrq\n");
/* fallback to just 0'ing */
diff --git a/drivers/infiniband/hw/qib/qib_init.c b/drivers/infiniband/hw/qib/qib_init.c
index d4fd8a6cff7b..072885a6684d 100644
--- a/drivers/infiniband/hw/qib/qib_init.c
+++ b/drivers/infiniband/hw/qib/qib_init.c
@@ -1547,18 +1547,13 @@ int qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd)
if (!rcd->rcvhdrq) {
dma_addr_t phys_hdrqtail;
- gfp_t gfp_flags;
-
amt = ALIGN(dd->rcvhdrcnt * dd->rcvhdrentsize *
sizeof(u32), PAGE_SIZE);
- gfp_flags = (rcd->ctxt >= dd->first_user_ctxt) ?
- GFP_USER : GFP_KERNEL;
old_node_id = dev_to_node(&dd->pcidev->dev);
set_dev_node(&dd->pcidev->dev, rcd->node_id);
rcd->rcvhdrq = dma_alloc_coherent(
- &dd->pcidev->dev, amt, &rcd->rcvhdrq_phys,
- gfp_flags | __GFP_COMP);
+ &dd->pcidev->dev, amt, &rcd->rcvhdrq_phys, GFP_KERNEL);
set_dev_node(&dd->pcidev->dev, old_node_id);
if (!rcd->rcvhdrq) {
@@ -1578,7 +1573,7 @@ int qib_create_rcvhdrq(struct qib_devdata *dd, struct qib_ctxtdata *rcd)
set_dev_node(&dd->pcidev->dev, rcd->node_id);
rcd->rcvhdrtail_kvaddr = dma_alloc_coherent(
&dd->pcidev->dev, PAGE_SIZE, &phys_hdrqtail,
- gfp_flags);
+ GFP_KERNEL);
set_dev_node(&dd->pcidev->dev, old_node_id);
if (!rcd->rcvhdrtail_kvaddr)
goto bail_free;
@@ -1622,17 +1617,8 @@ int qib_setup_eagerbufs(struct qib_ctxtdata *rcd)
struct qib_devdata *dd = rcd->dd;
unsigned e, egrcnt, egrperchunk, chunk, egrsize, egroff;
size_t size;
- gfp_t gfp_flags;
int old_node_id;
- /*
- * GFP_USER, but without GFP_FS, so buffer cache can be
- * coalesced (we hope); otherwise, even at order 4,
- * heavy filesystem activity makes these fail, and we can
- * use compound pages.
- */
- gfp_flags = __GFP_RECLAIM | __GFP_IO | __GFP_COMP;
-
egrcnt = rcd->rcvegrcnt;
egroff = rcd->rcvegr_tid_base;
egrsize = dd->rcvegrbufsize;
@@ -1664,7 +1650,7 @@ int qib_setup_eagerbufs(struct qib_ctxtdata *rcd)
rcd->rcvegrbuf[e] =
dma_alloc_coherent(&dd->pcidev->dev, size,
&rcd->rcvegrbuf_phys[e],
- gfp_flags);
+ GFP_KERNEL);
set_dev_node(&dd->pcidev->dev, old_node_id);
if (!rcd->rcvegrbuf[e])
goto bail_rcvegrbuf_phys;
--
2.20.1
^ permalink raw reply related
* [PATCH 10/16] iwlwifi: stop passing bogus gfp flags arguments to dma_alloc_coherent
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
dma_alloc_coherent is not just the page allocator. The only valid
arguments to pass are either GFP_ATOMIC or GFP_ATOMIC with possible
modifiers of __GFP_NORETRY or __GFP_NOWARN.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 3 +--
drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 5f52e40a2903..323dc5d5ee88 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
@@ -2361,8 +2361,7 @@ iwl_fw_dbg_buffer_allocation(struct iwl_fw_runtime *fwrt, u32 size)
virtual_addr =
dma_alloc_coherent(fwrt->trans->dev, size, &phys_addr,
- GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO |
- __GFP_COMP);
+ GFP_KERNEL | __GFP_NOWARN);
/* TODO: alloc fragments if needed */
if (!virtual_addr)
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 803fcbac4152..22a47f928dc8 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -210,8 +210,7 @@ static void iwl_pcie_alloc_fw_monitor_block(struct iwl_trans *trans,
for (power = max_power; power >= min_power; power--) {
size = BIT(power);
cpu_addr = dma_alloc_coherent(trans->dev, size, &phys,
- GFP_KERNEL | __GFP_NOWARN |
- __GFP_ZERO | __GFP_COMP);
+ GFP_KERNEL | __GFP_NOWARN);
if (!cpu_addr)
continue;
--
2.20.1
^ permalink raw reply related
* [PATCH 06/16] drm: don't pass __GFP_COMP to dma_alloc_coherent in drm_pci_alloc
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
The memory returned from dma_alloc_coherent is opaqueue to the user,
thus the exact way of page refcounting shall not matter either.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/gpu/drm/drm_bufs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index b640437ce90f..7a79a16a055c 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -70,7 +70,7 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali
dmah->size = size;
dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size,
&dmah->busaddr,
- GFP_KERNEL | __GFP_COMP);
+ GFP_KERNEL);
if (dmah->vaddr == NULL) {
kfree(dmah);
--
2.20.1
^ permalink raw reply related
* use exact allocation for dma coherent memory
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
Hi all,
various architectures have used exact memory allocations for dma
allocations for a long time, but x86 and thus the common code based
on it kept using our normal power of two allocator, which tends to
waste a lot of memory for certain allocations.
Switching to a slightly cleaned up alloc_pages_exact is pretty easy,
but it turns out that because we didn't filter valid gfp_t flags
on the DMA allocator, a bunch of drivers were passing __GFP_COMP
to it, which is rather bogus in too many ways to explain. Arm has
been filtering it for a while, but this series instead tries to fix
the drivers and warn when __GFP_COMP is passed, which makes it much
larger than just adding the functionality.
^ permalink raw reply
* [PATCH 02/16] drm/ati_pcigart: stop using drm_pci_alloc
From: Christoph Hellwig @ 2019-06-14 13:47 UTC (permalink / raw)
To: Maarten Lankhorst, Maxime Ripard, Sean Paul, David Airlie,
Daniel Vetter, Jani Nikula, Joonas Lahtinen, Rodrigo Vivi,
Ian Abbott, H Hartley Sweeten
Cc: Intel Linux Wireless, moderated list:ARM PORT, dri-devel,
intel-gfx, linux-rdma, linux-media, netdev, linux-wireless,
linux-s390, devel, linux-mm, iommu, linux-kernel
In-Reply-To: <20190614134726.3827-1-hch@lst.de>
Remove usage of the legacy drm PCI DMA wrappers, and with that the
incorrect usage cocktail of __GFP_COMP, virt_to_page on DMA allocation
and SetPageReserved.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/gpu/drm/ati_pcigart.c | 27 +++++++++++----------------
include/drm/ati_pcigart.h | 5 ++++-
2 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c
index 2362f07fe1fc..f66d4fccd812 100644
--- a/drivers/gpu/drm/ati_pcigart.c
+++ b/drivers/gpu/drm/ati_pcigart.c
@@ -41,21 +41,14 @@
static int drm_ati_alloc_pcigart_table(struct drm_device *dev,
struct drm_ati_pcigart_info *gart_info)
{
- gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size,
- PAGE_SIZE);
- if (gart_info->table_handle == NULL)
+ gart_info->table_vaddr = dma_alloc_coherent(&dev->pdev->dev,
+ gart_info->table_size, &gart_info->table_handle,
+ GFP_KERNEL);
+ if (!gart_info->table_vaddr)
return -ENOMEM;
-
return 0;
}
-static void drm_ati_free_pcigart_table(struct drm_device *dev,
- struct drm_ati_pcigart_info *gart_info)
-{
- drm_pci_free(dev, gart_info->table_handle);
- gart_info->table_handle = NULL;
-}
-
int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
{
struct drm_sg_mem *entry = dev->sg;
@@ -87,8 +80,10 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
}
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN &&
- gart_info->table_handle) {
- drm_ati_free_pcigart_table(dev, gart_info);
+ gart_info->table_vaddr) {
+ dma_free_coherent(&dev->pdev->dev, gart_info->table_size,
+ gart_info->table_vaddr, gart_info->table_handle);
+ gart_info->table_vaddr = NULL;
}
return 1;
@@ -127,9 +122,9 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
goto done;
}
- pci_gart = gart_info->table_handle->vaddr;
- address = gart_info->table_handle->vaddr;
- bus_address = gart_info->table_handle->busaddr;
+ pci_gart = gart_info->table_vaddr;
+ address = gart_info->table_vaddr;
+ bus_address = gart_info->table_handle;
} else {
address = gart_info->addr;
bus_address = gart_info->bus_addr;
diff --git a/include/drm/ati_pcigart.h b/include/drm/ati_pcigart.h
index a728a1364e66..2ffe278ba3b3 100644
--- a/include/drm/ati_pcigart.h
+++ b/include/drm/ati_pcigart.h
@@ -18,7 +18,10 @@ struct drm_ati_pcigart_info {
void *addr;
dma_addr_t bus_addr;
dma_addr_t table_mask;
- struct drm_dma_handle *table_handle;
+
+ dma_addr_t table_handle;
+ void *table_vaddr;
+
struct drm_local_map mapping;
int table_size;
};
--
2.20.1
^ permalink raw reply related
* Re: [PATCH 1/3] net: wireless: trace: add trace for tx_mgmt_expired
From: Johannes Berg @ 2019-06-14 13:42 UTC (permalink / raw)
To: James Prestwood, linux-wireless
In-Reply-To: <20190612193510.27680-1-james.prestwood@linux.intel.com>
Applied, but
* I squashed 1 and 2, there's no point in 1 standalone
* please be more careful with indentation in the future,
I fixed a few places.
johannes
^ permalink raw reply
* Re: [PATCH-v3 1/2] wireless: Support assoc-at-ms timer in sta-info
From: Johannes Berg @ 2019-06-14 13:38 UTC (permalink / raw)
To: greearb, linux-wireless
In-Reply-To: <20190415172123.6532-1-greearb@candelatech.com>
On Mon, 2019-04-15 at 10:21 -0700, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> Report time stamp of when sta became associated.
I guess that makes sense.
> Signed-off-by: Ben Greear <greearb@candelatech.com>
> ---
> include/net/cfg80211.h | 2 ++
> include/uapi/linux/nl80211.h | 2 ++
> net/wireless/nl80211.c | 1 +
> 3 files changed, 5 insertions(+)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index f49eb1464b7a..a3ad78b9d9f4 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -1268,6 +1268,7 @@ struct cfg80211_tid_stats {
> * indicate the relevant values in this struct for them
> * @connected_time: time(in secs) since a station is last connected
> * @inactive_time: time since last station activity (tx/rx) in milliseconds
> + * @assoc_at_ms: time in ms of the last association
I think the "_at_ms" doesn't really make sense. "time in ms" also
doesn't make sense as documentation. I think you need to say what should
be assigned here.
Also, you're actually using ktime_get_real() for this, which again
doesn't make much sense. For exposing an absolute time, I think we're
better off with CLOCK_BOOTTIME like we use elsewhere:
* @boottime_ns: CLOCK_BOOTTIME timestamp the frame was received at, this is
* needed only for beacons and probe responses that update the scan cache.
> + * @NL80211_STA_INFO_ASSOC_AT_MS: Timestamp of last association
_ASSOC_TIMESTAMP or something would make more sense too as the attribute
name, and clearly the documentation needs to spell out the semantics
here too.
johannes
^ permalink raw reply
* Re: [PATCH v2] Revert "cfg80211: fix processing world regdomain when non modular"
From: Johannes Berg @ 2019-06-14 13:30 UTC (permalink / raw)
To: Hodaszi, Robert; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <20190614131600.GA13897@a1-hr>
On Fri, 2019-06-14 at 13:16 +0000, Hodaszi, Robert wrote:
> This reverts commit 96cce12ff6e0bc9d9fcb2235e08b7fc150f96fd2.
>
> Re-triggering a reg_process_hint with the last request on all events,
> can make the regulatory domain fail in case of multiple WiFi modules. On
> slower boards (espacially with mdev), enumeration of the WiFi modules
> can end up in an intersected regulatory domain, and user cannot set it
> with 'iw reg set' anymore.
>
> This is happening, because:
> - 1st module enumerates, queues up a regulatory request
> - request gets processed by __reg_process_hint_driver():
> - checks if previous was set by CORE -> yes
> - checks if regulator domain changed -> yes, from '00' to e.g. 'US'
> -> sends request to the 'crda'
> - 2nd module enumerates, queues up a regulator request (which triggers
> the reg_todo() work)
> - reg_todo() -> reg_process_pending_hints() sees, that the last request
> is not processed yet, so it tries to process it again.
> __reg_process_hint driver() will run again, and:
> - checks if the last request's initiator was the core -> no, it was
> the driver (1st WiFi module)
> - checks, if the previous initiator was the driver -> yes
> - checks if the regulator domain changed -> yes, it was '00' (set by
> core, and crda call did not return yet), and should be changed to 'US'
>
> ------> __reg_process_hint_driver calls an intersect
>
> Besides, the reg_process_hint call with the last request is meaningless
> since the crda call has a timeout work. If that timeout expires, the
> first module's request will lost.
It's pointless to resend when I still have the original patch pending,
at least without any changes.
That said, I looked at this today and I'm not sure how the code doesn't
now have the original issue again?
johannes
^ permalink raw reply
* [mac80211-next:master 17/20] drivers/net/wireless/intel/iwlwifi/dvm/rs.c:3317:3: error: 'const struct rate_control_ops' has no member named 'remove_sta_debugfs'; did you mean 'add_sta_debugfs'?
From: kbuild test robot @ 2019-06-14 13:17 UTC (permalink / raw)
To: Greg Kroah-Hartman; +Cc: kbuild-all, linux-wireless, Johannes Berg
[-- Attachment #1: Type: text/plain, Size: 5088 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master
head: 499169fb3a5a27b8322cdd559a09e79e390c211b
commit: d3f7e94bc458dd1b20bef591ee2b82e2ae631858 [17/20] mac80211: remove unused and unneeded remove_sta_debugfs callback
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
git checkout d3f7e94bc458dd1b20bef591ee2b82e2ae631858
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=xtensa
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> drivers/net/wireless/intel/iwlwifi/dvm/rs.c:3317:3: error: 'const struct rate_control_ops' has no member named 'remove_sta_debugfs'; did you mean 'add_sta_debugfs'?
.remove_sta_debugfs = rs_remove_debugfs,
^~~~~~~~~~~~~~~~~~
add_sta_debugfs
>> drivers/net/wireless/intel/iwlwifi/dvm/rs.c:3317:24: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.remove_sta_debugfs = rs_remove_debugfs,
^~~~~~~~~~~~~~~~~
drivers/net/wireless/intel/iwlwifi/dvm/rs.c:3317:24: note: (near initialization for 'rs_ops.get_expected_throughput')
cc1: some warnings being treated as errors
--
>> drivers/net/wireless/intel/iwlwifi/mvm/rs.c:4138:3: error: 'const struct rate_control_ops' has no member named 'remove_sta_debugfs'; did you mean 'add_sta_debugfs'?
.remove_sta_debugfs = rs_remove_sta_debugfs,
^~~~~~~~~~~~~~~~~~
add_sta_debugfs
>> drivers/net/wireless/intel/iwlwifi/mvm/rs.c:4138:24: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.remove_sta_debugfs = rs_remove_sta_debugfs,
^~~~~~~~~~~~~~~~~~~~~
drivers/net/wireless/intel/iwlwifi/mvm/rs.c:4138:24: note: (near initialization for 'rs_mvm_ops_drv.get_expected_throughput')
cc1: some warnings being treated as errors
--
>> drivers/net//wireless/intel/iwlegacy/4965-rs.c:2815:3: error: 'const struct rate_control_ops' has no member named 'remove_sta_debugfs'; did you mean 'add_sta_debugfs'?
.remove_sta_debugfs = il4965_rs_remove_debugfs,
^~~~~~~~~~~~~~~~~~
add_sta_debugfs
>> drivers/net//wireless/intel/iwlegacy/4965-rs.c:2815:24: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
.remove_sta_debugfs = il4965_rs_remove_debugfs,
^~~~~~~~~~~~~~~~~~~~~~~~
drivers/net//wireless/intel/iwlegacy/4965-rs.c:2815:24: note: (near initialization for 'rs_4965_ops.get_expected_throughput')
cc1: some warnings being treated as errors
vim +3317 drivers/net/wireless/intel/iwlwifi/dvm/rs.c
631ad703b drivers/net/wireless/iwlwifi/dvm/rs.c Johannes Berg 2014-01-20 3305
631ad703b drivers/net/wireless/iwlwifi/dvm/rs.c Johannes Berg 2014-01-20 3306 static const struct rate_control_ops rs_ops = {
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3307 .name = RS_NAME,
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3308 .tx_status = rs_tx_status,
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3309 .get_rate = rs_get_rate,
fe6b23dd3 drivers/net/wireless/iwlwifi/iwl-agn-rs.c Reinette Chatre 2010-02-22 3310 .rate_init = rs_rate_init_stub,
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3311 .alloc = rs_alloc,
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3312 .free = rs_free,
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3313 .alloc_sta = rs_alloc_sta,
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3314 .free_sta = rs_free_sta,
93dc646ad drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-27 3315 #ifdef CONFIG_MAC80211_DEBUGFS
93dc646ad drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-27 3316 .add_sta_debugfs = rs_add_debugfs,
93dc646ad drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-27 @3317 .remove_sta_debugfs = rs_remove_debugfs,
93dc646ad drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-27 3318 #endif
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3319 };
b481de9ca drivers/net/wireless/iwlwifi/iwl-4965-rs.c Zhu Yi 2007-09-25 3320
:::::: The code at line 3317 was first introduced by commit
:::::: 93dc646adb94127ca1c2e74275a85265ec57b9af [PATCH] iwlwifi: add debugfs framework to rate scale
:::::: TO: Zhu Yi <yi.zhu@intel.com>
:::::: CC: David S. Miller <davem@sunset.davemloft.net>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 58622 bytes --]
^ permalink raw reply
* [PATCH v2] Revert "cfg80211: fix processing world regdomain when non modular"
From: Hodaszi, Robert @ 2019-06-14 13:16 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless@vger.kernel.org
This reverts commit 96cce12ff6e0bc9d9fcb2235e08b7fc150f96fd2.
Re-triggering a reg_process_hint with the last request on all events,
can make the regulatory domain fail in case of multiple WiFi modules. On
slower boards (espacially with mdev), enumeration of the WiFi modules
can end up in an intersected regulatory domain, and user cannot set it
with 'iw reg set' anymore.
This is happening, because:
- 1st module enumerates, queues up a regulatory request
- request gets processed by __reg_process_hint_driver():
- checks if previous was set by CORE -> yes
- checks if regulator domain changed -> yes, from '00' to e.g. 'US'
-> sends request to the 'crda'
- 2nd module enumerates, queues up a regulator request (which triggers
the reg_todo() work)
- reg_todo() -> reg_process_pending_hints() sees, that the last request
is not processed yet, so it tries to process it again.
__reg_process_hint driver() will run again, and:
- checks if the last request's initiator was the core -> no, it was
the driver (1st WiFi module)
- checks, if the previous initiator was the driver -> yes
- checks if the regulator domain changed -> yes, it was '00' (set by
core, and crda call did not return yet), and should be changed to 'US'
------> __reg_process_hint_driver calls an intersect
Besides, the reg_process_hint call with the last request is meaningless
since the crda call has a timeout work. If that timeout expires, the
first module's request will lost.
Signed-off-by: Robert Hodaszi <robert.hodaszi@digi.com>
---
net/wireless/reg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4831ad745f91..327479ce69f5 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2788,7 +2788,7 @@ static void reg_process_pending_hints(void)
/* When last_request->processed becomes true this will be rescheduled */
if (lr && !lr->processed) {
- reg_process_hint(lr);
+ pr_debug("Pending regulatory request, waiting for it to be processed...\n");
return;
}
^ permalink raw reply related
* Re: [PATCH v3 wireless-drivers 3/3] mt76: usb: do not always copy the first part of received frames
From: Lorenzo Bianconi @ 2019-06-14 12:46 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, kvalo, linux-wireless, nbd
In-Reply-To: <20190614110442.GA17298@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2738 bytes --]
> On Fri, Jun 14, 2019 at 12:22:48PM +0200, Lorenzo Bianconi wrote:
> > > On Thu, Jun 13, 2019 at 11:43:13PM +0200, Lorenzo Bianconi wrote:
> > > > Set usb buffer size taking into account skb_shared_info in order to
> > > > not always copy the first part of received frames if A-MSDU is enabled
> > > > for SG capable devices. Moreover align usb buffer size to max_ep
> > > > boundaries and set buf_size to PAGE_SIZE even for sg case
> > >
> > > I think this should not be applied to wirless-drivers, only first patch
> > > that fix the bug and optimizations should be done in -next.
> >
> > ack, right. I think patch 2/3 and 3/3 can go directly in Felix's tree
> >
> > >
> > > > + int i, data_size;
> > > >
> > > > + data_size = rounddown(SKB_WITH_OVERHEAD(q->buf_size),
> > > > + dev->usb.in_ep[MT_EP_IN_PKT_RX].max_packet);
> > > > for (i = 0; i < nsgs; i++) {
> > > > struct page *page;
> > > > void *data;
> > > > @@ -302,7 +304,7 @@ mt76u_fill_rx_sg(struct mt76_dev *dev, struct mt76_queue *q, struct urb *urb,
> > > >
> > > > page = virt_to_head_page(data);
> > > > offset = data - page_address(page);
> > > > - sg_set_page(&urb->sg[i], page, q->buf_size, offset);
> > > > + sg_set_page(&urb->sg[i], page, data_size, offset);
> > > <snip>
> > > > - q->buf_size = dev->usb.sg_en ? MT_RX_BUF_SIZE : PAGE_SIZE;
> > > > q->ndesc = MT_NUM_RX_ENTRIES;
> > > > + q->buf_size = PAGE_SIZE;
> > > > +
> > >
> > > This should be associated with decrease of MT_SG_MAX_SIZE to value that
> > > is actually needed and currently this is 2 for 4k AMSDU.
> >
> > MT_SG_MAX_SIZE is used even on tx side and I do not think we will end up with a
> > huge difference here
>
> So use different value as argument for mt76u_fill_rx_sg() in
> mt76u_rx_urb_alloc(). After changing buf_size to PAGE_SIZE we will
> allocate 8 pages per rx queue entry, but only 2 pages will be used
> (with data_size change, 1 without data_size change). Or I'm wrong?
yes, it is right (we will use two pages with data_size change). Maybe better to
use 4 pages for each rx queue entry? (otherwise we will probably change it in
the future)
>
> > > However I don't think allocating 2 pages to avoid ieee80211 header and SNAP
> > > copy is worth to do. For me best approach would be allocate 1 page for
> > > 4k AMSDU, 2 for 8k and 3 for 12k (still using sg, but without data_size
> > > change to avoid 32B copying).
> >
> > From my point of view it is better to avoid copying if it is possible. Are you
> > sure there is no difference?
>
> I do not understand what you mean by difference here.
tpt differences, not sure if there are any
Regards,
Lorenzo
>
> Stanislaw
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH V2 4/6] mac80211: HE: add Spatial Reuse IE parsing support
From: Johannes Berg @ 2019-06-14 12:34 UTC (permalink / raw)
To: John Crispin; +Cc: linux-wireless, ath11k, Shashidhar Lakkavalli
In-Reply-To: <20190528114952.838-5-john@phrozen.org>
> +/*
> + * ieee80211_he_spr_size - calculate 802.11ax HE Spatial Reuse IE size
> + * @he_spr_ie: byte data of the He Spatial Reuse IE, stating from the the byte
> + * after the ext ID byte. It is assumed that he_spr_ie has at least
> + * sizeof(struct ieee80211_he_spr) bytes, checked already in
> + * ieee802_11_parse_elems_crc()
That reference to mac80211 isn't really quite appropriate here - should
say something like "the caller must have validated this". This is a
lower layer usable by non-mac80211 as well.
johannes
^ permalink raw reply
* Re: [PATCH 2/2] mac80211: add support for the ADDBA extension element
From: Johannes Berg @ 2019-06-14 12:32 UTC (permalink / raw)
To: John Crispin; +Cc: linux-wireless, ath11k, Shashidhar Lakkavalli
In-Reply-To: <20190521150259.2414-2-john@phrozen.org>
>
> +#define IEEE80211_ADDBA_EXT_ELEM_ID 0x9f
That doesn't really belong here.
> +#define IEEE80211_ADDBA_EXT_ELEM_ID_LEN 0x01
And that's usually not a define?
> +#define IEEE80211_ADDBA_EXT_FRAG_LEVEL_MASK GENMASK(2, 1)
> +#define IEEE80211_ADDBA_EXT_FRAG_LEVEL_SHIFT 1
> +#define IEEE80211_ADDBA_EXT_NO_FRAG BIT(0)
> +
> +struct ieee80211_addbaext {
> + u8 eid;
> + u8 length;
> + u8 data;
> +} __packed;
I think we don't typically put the eid/len inside, and then we use
sizeof(struct ...) for the size.
johannes
^ permalink raw reply
* Re: [PATCH v3 wireless-drivers 1/3] mt76: usb: fix rx A-MSDU support
From: Lorenzo Bianconi @ 2019-06-14 12:32 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Lorenzo Bianconi, kvalo, linux-wireless, nbd, johannes
In-Reply-To: <20190614111414.GB17298@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 3429 bytes --]
> On Fri, Jun 14, 2019 at 12:11:17PM +0200, Lorenzo Bianconi wrote:
> > > On Thu, Jun 13, 2019 at 11:43:11PM +0200, Lorenzo Bianconi wrote:
> > > > Commit f8f527b16db5 ("mt76: usb: use EP max packet aligned buffer sizes
> > > > for rx") breaks A-MSDU support. When A-MSDU is enable the device can
> > > > receive frames up to q->buf_size but they will be discarded in
> > > > mt76u_process_rx_entry since there is no enough room for
> > > > skb_shared_info. Fix the issue reallocating the skb and copying in the
> > > > linear area the first 128B of the received frames and in the frag_list
> > > > the remaining part.
> > > >
> > > > Fixes: f8f527b16db5 ("mt76: usb: use EP max packet aligned buffer sizes for rx")
> > > > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > > > ---
> > > > drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
> > > > drivers/net/wireless/mediatek/mt76/usb.c | 49 ++++++++++++++++++-----
> > > > 2 files changed, 41 insertions(+), 9 deletions(-)
> > > >
> > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> > > > index 8ecbf81a906f..889b76deb703 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> > > > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> > > > @@ -30,6 +30,7 @@
> > > > #define MT_TX_RING_SIZE 256
> > > > #define MT_MCU_RING_SIZE 32
> > > > #define MT_RX_BUF_SIZE 2048
> > > > +#define MT_SKB_HEAD_LEN 128
> > > >
> > > > struct mt76_dev;
> > > > struct mt76_wcid;
> > > > diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
> > > > index bbaa1365bbda..12d60d31cb51 100644
> > > > --- a/drivers/net/wireless/mediatek/mt76/usb.c
> > > > +++ b/drivers/net/wireless/mediatek/mt76/usb.c
> > > > @@ -429,6 +429,45 @@ static int mt76u_get_rx_entry_len(u8 *data, u32 data_len)
> > > > return dma_len;
> > > > }
> > > >
> > > > +static struct sk_buff *
> > > > +mt76u_build_rx_skb(u8 *data, int len, int buf_size)
> > > > +{
> > > > + struct sk_buff *skb;
> > > > +
> > > > + if (SKB_WITH_OVERHEAD(buf_size) < MT_DMA_HDR_LEN + len) {
> > > > + struct page *page;
> > > > + int offset;
> > > > +
> > > > + /* slow path, not enough space for data and
> > > > + * skb_shared_info
> > > > + */
> > > > + skb = alloc_skb(MT_SKB_HEAD_LEN, GFP_ATOMIC);
> > > > + if (!skb)
> > > > + return NULL;
> > > > +
> > > > + skb_put_data(skb, data + MT_DMA_HDR_LEN, MT_SKB_HEAD_LEN);
> > >
> > > I looked how rx amsdu is processed in mac80211 and it is decomposed and
> > > copied into newly allocated individual skb's, see ieee80211_amsdu_to_8023s()
> > >
> > > So copy L3 & L4 headers doesn't do anything good here, actually seems to
> > > be better to have them in frag as __ieee80211_amsdu_copy_frag() do some
> > > magic to avid copy.
> >
> > Looking at __ieee80211_amsdu_copy() now I got why other drivers copy hdrlen +
> > 8, thx :)
> > In our case reuse_frag is true in __ieee80211_amsdu_copy, so we will end up
>
> I don't think reuse_frag is true in our case since skb->head_frag is
> not set when we use alloc_skb().
Oh, right. In this case it is probably better to use netdev_alloc_skb().
I will repost using the approach used in mt7601u since for the moment it will
not make any difference to copy more data.
Regards,
Lorenzo
>
> Stanislaw
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v3 1/2] nl80211: Add support for EDMG channels
From: Johannes Berg @ 2019-06-14 12:31 UTC (permalink / raw)
To: Alexei Avshalom Lazar; +Cc: linux-wireless, wil6210
In-Reply-To: <1558364020-11064-2-git-send-email-ailizaro@codeaurora.org>
Hi Alexei,
Sorry for the long delay here.
I have a few questions.
Looking at this:
> /**
> + * struct ieee80211_sta_edmg_cap - EDMG capabilities
> + *
> + * This structure describes most essential parameters needed
> + * to describe 802.11ay EDMG capabilities
> + *
> + * @channels: bitmap that indicates the 2.16 GHz channel(s)
> + * that are allowed to be used for transmissions in the BSS.
> + * Set to 0 indicate EDMG not supported.
> + * @bw_config: Channel BW Configuration subfield encodes
> + * the allowed channel bandwidth configurations
> + */
> +struct ieee80211_sta_edmg_cap {
> + u8 channels;
> + u8 bw_config;
> +};
What are the bits actually? Seems you should define some enum or so that
shows which bits are used here?
> * @center_freq1: center frequency of first segment
> * @center_freq2: center frequency of second segment
> * (only with 80+80 MHz)
> + * @edmg_channels: bitmap that indicates the 2.16 GHz channel(s)
> + * that are allowed to be used for transmissions in the BSS.
> + * @edmg_bw_config: Channel BW Configuration subfield encodes
> + * the allowed channel bandwidth configurations
> */
> struct cfg80211_chan_def {
> struct ieee80211_channel *chan;
> enum nl80211_chan_width width;
> u32 center_freq1;
> u32 center_freq2;
> + u8 edmg_channels;
> + u8 edmg_bw_config;
> };
This isn't clear to me. How can the capability and the configuration be
exactly the same? In the capability, you should be able to capture
multiple possible things, and in the setting only choose one?
And if they really are the same, why not use the struct
ieee80211_sta_edmg_cap here? Seems weird to me, but I don't know 11ay.
Also, I think you should describe a bit more how this plays together
with the existing settings. Will ->chan still be set, to something like
the control channel?
> /**
> @@ -1144,15 +1169,17 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
> * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS
> * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS
> * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval
> - * @RATE_INFO_FLAGS_60G: 60GHz MCS
> + * @RATE_INFO_FLAGS_DMG: 60GHz MCS
> * @RATE_INFO_FLAGS_HE_MCS: HE MCS information
> + * @RATE_INFO_FLAGS_EDMG: 60GHz MCS in EDMG mode
> */
> enum rate_info_flags {
> RATE_INFO_FLAGS_MCS = BIT(0),
> RATE_INFO_FLAGS_VHT_MCS = BIT(1),
> RATE_INFO_FLAGS_SHORT_GI = BIT(2),
> - RATE_INFO_FLAGS_60G = BIT(3),
> + RATE_INFO_FLAGS_DMG = BIT(3),
> RATE_INFO_FLAGS_HE_MCS = BIT(4),
> + RATE_INFO_FLAGS_EDMG = BIT(5),
> };
>
> /**
> @@ -1192,6 +1219,7 @@ enum rate_info_bw {
> * @he_dcm: HE DCM value
> * @he_ru_alloc: HE RU allocation (from &enum nl80211_he_ru_alloc,
> * only valid if bw is %RATE_INFO_BW_HE_RU)
> + * @n_bonded_ch: In case of EDMG the number of bonded channels (1-4)
> */
> struct rate_info {
> u8 flags;
> @@ -1202,6 +1230,7 @@ struct rate_info {
> u8 he_gi;
> u8 he_dcm;
> u8 he_ru_alloc;
> + u8 n_bonded_ch;
> };
It seems like this is missing corresponding nl80211.h changes?
> @@ -2436,6 +2469,8 @@ struct cfg80211_connect_params {
> const u8 *fils_erp_rrk;
> size_t fils_erp_rrk_len;
> bool want_1x;
> + u8 edmg_channels;
> + u8 edmg_bw_config;
> };
Same question as above, why not embed the struct if it's the same?
Again it seems like it shouldn't be the same though.
> + * @NL80211_ATTR_WIPHY_EDMG_CHANNELS: bitmap that indicates the 2.16 GHz
> + * channel(s) that are allowed to be used for EDMG transmissions in the
> + * BSS as defined by IEEE 802.11 section 9.4.2.251.
> + * @NL80211_ATTR_WIPHY_EDMG_BW_CONFIG: Channel BW Configuration subfield encodes
> + * the allowed channel bandwidth configurations as defined by IEEE 802.11
> + * section 9.4.2.251, Table 13.
This is unclear - "in the BSS" means nothing in this context, since
you're using this to advertise capabilities?
This isn't a BSS attribute, after all.
Ah - but looking further, you use this to *set* the channel, not for
capabilities... I guess that makes sense.
> * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE
> * @NL80211_BAND_ATTR_IFTYPE_DATA: nested array attribute, with each entry using
> * attributes from &enum nl80211_band_iftype_attr
> + * @NL80211_BAND_ATTR_EDMG_CHANNELS: bitmap that indicates the 2.16 GHz
> + * channel(s) that are allowed to be used for EDMG transmissions in the
> + * BSS as defined by IEEE 802.11 section 9.4.2.251.
> + * @NL80211_BAND_ATTR_EDMG_BW_CONFIG: Channel BW Configuration subfield
> + * encodes the allowed channel bandwidth configurations as defined by
> + * IEEE 802.11 section 9.4.2.251, Table 13.
> * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined
> * @__NL80211_BAND_ATTR_AFTER_LAST: internal use
And ... that makes more sense than the global attribute I guess?
> +static bool cfg80211_edmg_chandef_valid(const struct cfg80211_chan_def *chandef)
> +{
> + int max_continuous = 0;
> + int num_of_enabled = 0;
> + int continuous = 0;
do you mean "contiguous"? "continuous" doesn't make much sense?
> + int i;
> +
> + if (!chandef->edmg_channels && !chandef->edmg_bw_config)
> + return true;
> +
> + if ((!chandef->edmg_channels && chandef->edmg_bw_config) ||
> + (chandef->edmg_channels && !chandef->edmg_bw_config))
> + return false;
There probably should be some kind of WARN_ON() check that validates you
get here only if the ->chan is actually 60GHz?
> +++ b/net/wireless/nl80211.c
> @@ -288,6 +288,9 @@ static int validate_ie_attr(const struct nlattr *attr,
>
> [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
> [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
> + [NL80211_ATTR_WIPHY_EDMG_CHANNELS] = { .type = NLA_U8 },
> + [NL80211_ATTR_WIPHY_EDMG_BW_CONFIG] = { .type = NLA_U8 },
You probably want something like NLA_POLICY_RANGE() here? This was only
1-4 IIRC?
> + if (info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]) {
> + chandef->edmg_channels =
> + nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_CHANNELS]);
> +
> + if (info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG])
> + chandef->edmg_bw_config =
> + nla_get_u8(info->attrs[NL80211_ATTR_WIPHY_EDMG_BW_CONFIG]);
> + } else {
> + chandef->edmg_bw_config = 0;
> + chandef->edmg_channels = 0;
> + }
> +
> if (!cfg80211_chandef_valid(chandef)) {
So I guess what I suggested above shouldn't actually be a WARN_ON() but
just a check w/o WARN_ON()?
johannes
^ permalink raw reply
* Re: [PATCH v4 4/5] mmc: core: Add sdio_retune_hold_now() and sdio_retune_release()
From: Ulf Hansson @ 2019-06-14 12:09 UTC (permalink / raw)
To: Douglas Anderson
Cc: Kalle Valo, Adrian Hunter, Arend van Spriel,
brcm80211-dev-list.pdl, open list:ARM/Rockchip SoC..., Double Lo,
Brian Norris, linux-wireless, Naveen Gupta, Madhan Mohan R,
Matthias Kaehlcke, Wright Feng, Chi-Hsien Lin, netdev,
brcm80211-dev-list, linux-mmc@vger.kernel.org,
Linux Kernel Mailing List, Thomas Gleixner, Greg Kroah-Hartman,
Avri Altman
In-Reply-To: <20190613234153.59309-5-dianders@chromium.org>
On Fri, 14 Jun 2019 at 01:42, Douglas Anderson <dianders@chromium.org> wrote:
>
> We want SDIO drivers to be able to temporarily stop retuning when the
> driver knows that the SDIO card is not in a state where retuning will
> work (maybe because the card is asleep). We'll move the relevant
> functions to a place where drivers can call them.
>
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
This looks good to me.
BTW, seems like this series is best funneled via my mmc tree, no? In
such case, I need acks for the brcmfmac driver patches.
Kind regards
Uffe
> ---
>
> Changes in v4:
> - Moved retune hold/release to SDIO API (Adrian).
>
> Changes in v3:
> - ("mmc: core: Export mmc_retune_hold_now() mmc_retune_release()") new for v3.
>
> Changes in v2: None
>
> drivers/mmc/core/sdio_io.c | 40 +++++++++++++++++++++++++++++++++++
> include/linux/mmc/sdio_func.h | 3 +++
> 2 files changed, 43 insertions(+)
>
> diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
> index f822a9630b0e..1b6fe737bd72 100644
> --- a/drivers/mmc/core/sdio_io.c
> +++ b/drivers/mmc/core/sdio_io.c
> @@ -15,6 +15,7 @@
> #include "sdio_ops.h"
> #include "core.h"
> #include "card.h"
> +#include "host.h"
>
> /**
> * sdio_claim_host - exclusively claim a bus for a certain SDIO function
> @@ -770,3 +771,42 @@ void sdio_retune_crc_enable(struct sdio_func *func)
> func->card->host->retune_crc_disable = false;
> }
> EXPORT_SYMBOL_GPL(sdio_retune_crc_enable);
> +
> +/**
> + * sdio_retune_hold_now - start deferring retuning requests till release
> + * @func: SDIO function attached to host
> + *
> + * This function can be called if it's currently a bad time to do
> + * a retune of the SDIO card. Retune requests made during this time
> + * will be held and we'll actually do the retune sometime after the
> + * release.
> + *
> + * This function could be useful if an SDIO card is in a power state
> + * where it can respond to a small subset of commands that doesn't
> + * include the retuning command. Care should be taken when using
> + * this function since (presumably) the retuning request we might be
> + * deferring was made for a good reason.
> + *
> + * This function should be called while the host is claimed.
> + */
> +void sdio_retune_hold_now(struct sdio_func *func)
> +{
> + mmc_retune_hold_now(func->card->host);
> +}
> +EXPORT_SYMBOL_GPL(sdio_retune_hold_now);
> +
> +/**
> + * sdio_retune_release - signal that it's OK to retune now
> + * @func: SDIO function attached to host
> + *
> + * This is the complement to sdio_retune_hold_now(). Calling this
> + * function won't make a retune happen right away but will allow
> + * them to be scheduled normally.
> + *
> + * This function should be called while the host is claimed.
> + */
> +void sdio_retune_release(struct sdio_func *func)
> +{
> + mmc_retune_release(func->card->host);
> +}
> +EXPORT_SYMBOL_GPL(sdio_retune_release);
> diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h
> index 4820e6d09dac..5a177f7a83c3 100644
> --- a/include/linux/mmc/sdio_func.h
> +++ b/include/linux/mmc/sdio_func.h
> @@ -170,4 +170,7 @@ extern int sdio_set_host_pm_flags(struct sdio_func *func, mmc_pm_flag_t flags);
> extern void sdio_retune_crc_disable(struct sdio_func *func);
> extern void sdio_retune_crc_enable(struct sdio_func *func);
>
> +extern void sdio_retune_hold_now(struct sdio_func *func);
> +extern void sdio_retune_release(struct sdio_func *func);
> +
> #endif /* LINUX_MMC_SDIO_FUNC_H */
> --
> 2.22.0.rc2.383.gf4fbbf30c2-goog
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox