Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 1/7] usbnet: Run unregister_netdev() before unbind() again
From: Lukas Wunner @ 2022-04-27  5:48 UTC (permalink / raw)
  To: Steve Glendinning, UNGLinuxDriver, Oliver Neukum, David S. Miller,
	Jakub Kicinski, Paolo Abeni
  Cc: netdev, linux-usb, Andre Edich, Oleksij Rempel, Martyn Welch,
	Gabriel Hojda, Christoph Fritz, Lino Sanfilippo,
	Philipp Rosenberger, Heiner Kallweit, Andrew Lunn, Russell King
In-Reply-To: <cover.1651037513.git.lukas@wunner.de>

Commit 2c9d6c2b871d ("usbnet: run unbind() before unregister_netdev()")
sought to fix a use-after-free on disconnect of USB Ethernet adapters.

It turns out that a different fix is necessary to address the issue:
https://lore.kernel.org/netdev/18b3541e5372bc9b9fc733d422f4e698c089077c.1650177997.git.lukas@wunner.de/

So the commit was not necessary.

The commit made binding and unbinding of USB Ethernet asymmetrical:
Before, usbnet_probe() first invoked the ->bind() callback and then
register_netdev().  usbnet_disconnect() mirrored that by first invoking
unregister_netdev() and then ->unbind().

Since the commit, the order in usbnet_disconnect() is reversed and no
longer mirrors usbnet_probe().

One consequence is that a PHY disconnected (and stopped) in ->unbind()
is afterwards stopped once more by unregister_netdev() as it closes the
netdev before unregistering.  That necessitates a contortion in ->stop()
because the PHY may only be stopped if it hasn't already been
disconnected.

Reverting the commit allows making the call to phy_stop() unconditional
in ->stop().

Signed-off-by: Lukas Wunner <lukas@wunner.de>
Cc: Oleksij Rempel <o.rempel@pengutronix.de>
Cc: Martyn Welch <martyn.welch@collabora.com>
Cc: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/usb/asix_devices.c | 6 +-----
 drivers/net/usb/smsc95xx.c     | 3 +--
 drivers/net/usb/usbnet.c       | 6 +++---
 3 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c
index 38e47a93fb83..5b5eb630c4b7 100644
--- a/drivers/net/usb/asix_devices.c
+++ b/drivers/net/usb/asix_devices.c
@@ -795,11 +795,7 @@ static int ax88772_stop(struct usbnet *dev)
 {
 	struct asix_common_private *priv = dev->driver_priv;
 
-	/* On unplugged USB, we will get MDIO communication errors and the
-	 * PHY will be set in to PHY_HALTED state.
-	 */
-	if (priv->phydev->state != PHY_HALTED)
-		phy_stop(priv->phydev);
+	phy_stop(priv->phydev);
 
 	return 0;
 }
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index 4ef61f6b85df..edf0492ad489 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1243,8 +1243,7 @@ static int smsc95xx_start_phy(struct usbnet *dev)
 
 static int smsc95xx_stop(struct usbnet *dev)
 {
-	if (dev->net->phydev)
-		phy_stop(dev->net->phydev);
+	phy_stop(dev->net->phydev);
 
 	return 0;
 }
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 9a6450f796dc..36b24ec11650 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1616,9 +1616,6 @@ void usbnet_disconnect (struct usb_interface *intf)
 		   xdev->bus->bus_name, xdev->devpath,
 		   dev->driver_info->description);
 
-	if (dev->driver_info->unbind)
-		dev->driver_info->unbind(dev, intf);
-
 	net = dev->net;
 	unregister_netdev (net);
 
@@ -1626,6 +1623,9 @@ void usbnet_disconnect (struct usb_interface *intf)
 
 	usb_scuttle_anchored_urbs(&dev->deferred);
 
+	if (dev->driver_info->unbind)
+		dev->driver_info->unbind(dev, intf);
+
 	usb_kill_urb(dev->interrupt);
 	usb_free_urb(dev->interrupt);
 	kfree(dev->padding_pkt);
-- 
2.35.2


^ permalink raw reply related

* [PATCH net-next 0/7] Polling be gone on LAN95xx
From: Lukas Wunner @ 2022-04-27  5:48 UTC (permalink / raw)
  To: Steve Glendinning, UNGLinuxDriver, Oliver Neukum, David S. Miller,
	Jakub Kicinski, Paolo Abeni
  Cc: netdev, linux-usb, Andre Edich, Oleksij Rempel, Martyn Welch,
	Gabriel Hojda, Christoph Fritz, Lino Sanfilippo,
	Philipp Rosenberger, Heiner Kallweit, Andrew Lunn, Russell King

Do away with link status polling on LAN95XX USB Ethernet
and rely on interrupts instead, thereby reducing bus traffic,
CPU overhead and improving interface bringup latency.

The meat of the series is in patch [5/7].  The preceding and
following patches are various cleanups to prepare for and
adjust to interrupt-driven link state detection.

Please review and test.  Thanks!

Lukas Wunner (7):
  usbnet: Run unregister_netdev() before unbind() again
  usbnet: smsc95xx: Don't clear read-only PHY interrupt
  usbnet: smsc95xx: Don't reset PHY behind PHY driver's back
  usbnet: smsc95xx: Avoid link settings race on interrupt reception
  usbnet: smsc95xx: Forward PHY interrupts to PHY driver to avoid
    polling
  net: phy: smsc: Cache interrupt mask
  net: phy: smsc: Cope with hot-removal in interrupt handler

 drivers/net/phy/smsc.c         |  28 +++---
 drivers/net/usb/asix_devices.c |   6 +-
 drivers/net/usb/smsc95xx.c     | 155 ++++++++++++++++-----------------
 drivers/net/usb/usbnet.c       |   6 +-
 4 files changed, 91 insertions(+), 104 deletions(-)

-- 
2.35.2


^ permalink raw reply

* Re: [PATCH V2] vDPA/ifcvf: allow userspace to suspend a queue
From: Jason Wang @ 2022-04-27  5:56 UTC (permalink / raw)
  To: Zhu Lingshan, mst; +Cc: virtualization, netdev
In-Reply-To: <20220424113321.7176-1-lingshan.zhu@intel.com>


在 2022/4/24 19:33, Zhu Lingshan 写道:
> Formerly, ifcvf driver has implemented a lazy-initialization mechanism
> for the virtqueues, it would store all virtqueue config fields that
> passed down from the userspace, then load them to the virtqueues and
> enable the queues upon DRIVER_OK.
>
> To allow the userspace to suspend a virtqueue,
> this commit passes queue_enable to the virtqueue directly through
> set_vq_ready().
>
> This feature requires and this commits implementing all virtqueue
> ops(set_vq_addr, set_vq_num and set_vq_ready) to take immediate
> actions than lazy-initialization, so ifcvf_hw_enable() is retired.
>
> set_features() should take immediate actions as well.
>
> ifcvf_add_status() is retierd because we should not add
> status like FEATURES_OK by ifcvf's decision, this driver should
> only set device status upon vdpa_ops.set_status()
>
> To avoid losing virtqueue configurations caused by multiple
> rounds of reset(), this commit also refactors thed evice reset
> routine, now it simply reset the config handler and the virtqueues,
> and only once device-reset().


It looks like the patch tries to do too many things at one run. I'd 
suggest to split them:


1) on-the-fly set via set_vq_ready(), but I don't see a reason why we 
need to change other lazy stuffs, since setting queue_enable to 1 before 
DRIVER_OK won't start the virtqueue anyhow
2) if necessary, converting the lazy stuffs
3) the synchornize_irq() fixes
4) other stuffs

Thanks


>
> Signed-off-by: Zhu Lingshan <lingshan.zhu@intel.com>
> ---
>   drivers/vdpa/ifcvf/ifcvf_base.c | 150 +++++++++++++++++++-------------
>   drivers/vdpa/ifcvf/ifcvf_base.h |  16 ++--
>   drivers/vdpa/ifcvf/ifcvf_main.c |  81 +++--------------
>   3 files changed, 111 insertions(+), 136 deletions(-)
>
> diff --git a/drivers/vdpa/ifcvf/ifcvf_base.c b/drivers/vdpa/ifcvf/ifcvf_base.c
> index 48c4dadb0c7c..bbc9007a6f34 100644
> --- a/drivers/vdpa/ifcvf/ifcvf_base.c
> +++ b/drivers/vdpa/ifcvf/ifcvf_base.c
> @@ -179,20 +179,7 @@ void ifcvf_set_status(struct ifcvf_hw *hw, u8 status)
>   
>   void ifcvf_reset(struct ifcvf_hw *hw)
>   {
> -	hw->config_cb.callback = NULL;
> -	hw->config_cb.private = NULL;
> -
>   	ifcvf_set_status(hw, 0);
> -	/* flush set_status, make sure VF is stopped, reset */
> -	ifcvf_get_status(hw);
> -}
> -
> -static void ifcvf_add_status(struct ifcvf_hw *hw, u8 status)
> -{
> -	if (status != 0)
> -		status |= ifcvf_get_status(hw);
> -
> -	ifcvf_set_status(hw, status);
>   	ifcvf_get_status(hw);
>   }
>   
> @@ -213,7 +200,7 @@ u64 ifcvf_get_hw_features(struct ifcvf_hw *hw)
>   	return features;
>   }
>   
> -u64 ifcvf_get_features(struct ifcvf_hw *hw)
> +u64 ifcvf_get_device_features(struct ifcvf_hw *hw)
>   {
>   	return hw->hw_features;
>   }
> @@ -280,7 +267,7 @@ void ifcvf_write_dev_config(struct ifcvf_hw *hw, u64 offset,
>   		vp_iowrite8(*p++, hw->dev_cfg + offset + i);
>   }
>   
> -static void ifcvf_set_features(struct ifcvf_hw *hw, u64 features)
> +void ifcvf_set_features(struct ifcvf_hw *hw, u64 features)
>   {
>   	struct virtio_pci_common_cfg __iomem *cfg = hw->common_cfg;
>   
> @@ -289,22 +276,22 @@ static void ifcvf_set_features(struct ifcvf_hw *hw, u64 features)
>   
>   	vp_iowrite32(1, &cfg->guest_feature_select);
>   	vp_iowrite32(features >> 32, &cfg->guest_feature);
> +
> +	vp_ioread32(&cfg->guest_feature);
>   }
>   
> -static int ifcvf_config_features(struct ifcvf_hw *hw)
> +u64 ifcvf_get_features(struct ifcvf_hw *hw)
>   {
> -	struct ifcvf_adapter *ifcvf;
> +	struct virtio_pci_common_cfg __iomem *cfg = hw->common_cfg;
> +	u64 features;
>   
> -	ifcvf = vf_to_adapter(hw);
> -	ifcvf_set_features(hw, hw->req_features);
> -	ifcvf_add_status(hw, VIRTIO_CONFIG_S_FEATURES_OK);
> +	vp_iowrite32(0, &cfg->device_feature_select);
> +	features = vp_ioread32(&cfg->device_feature);
>   
> -	if (!(ifcvf_get_status(hw) & VIRTIO_CONFIG_S_FEATURES_OK)) {
> -		IFCVF_ERR(ifcvf->pdev, "Failed to set FEATURES_OK status\n");
> -		return -EIO;
> -	}
> +	vp_iowrite32(1, &cfg->device_feature_select);
> +	features |= ((u64)vp_ioread32(&cfg->guest_feature) << 32);
>   
> -	return 0;
> +	return features;
>   }
>   
>   u16 ifcvf_get_vq_state(struct ifcvf_hw *hw, u16 qid)
> @@ -331,68 +318,111 @@ int ifcvf_set_vq_state(struct ifcvf_hw *hw, u16 qid, u16 num)
>   	ifcvf_lm = (struct ifcvf_lm_cfg __iomem *)hw->lm_cfg;
>   	q_pair_id = qid / hw->nr_vring;
>   	avail_idx_addr = &ifcvf_lm->vring_lm_cfg[q_pair_id].idx_addr[qid % 2];
> -	hw->vring[qid].last_avail_idx = num;
>   	vp_iowrite16(num, avail_idx_addr);
>   
>   	return 0;
>   }
>   
> -static int ifcvf_hw_enable(struct ifcvf_hw *hw)
> +void ifcvf_set_vq_num(struct ifcvf_hw *hw, u16 qid, u32 num)
>   {
> -	struct virtio_pci_common_cfg __iomem *cfg;
> -	u32 i;
> +	struct virtio_pci_common_cfg __iomem *cfg = hw->common_cfg;
>   
> -	cfg = hw->common_cfg;
> -	for (i = 0; i < hw->nr_vring; i++) {
> -		if (!hw->vring[i].ready)
> -			break;
> +	vp_iowrite16(qid, &cfg->queue_select);
> +	vp_iowrite16(num, &cfg->queue_size);
> +}
>   
> -		vp_iowrite16(i, &cfg->queue_select);
> -		vp_iowrite64_twopart(hw->vring[i].desc, &cfg->queue_desc_lo,
> -				     &cfg->queue_desc_hi);
> -		vp_iowrite64_twopart(hw->vring[i].avail, &cfg->queue_avail_lo,
> -				      &cfg->queue_avail_hi);
> -		vp_iowrite64_twopart(hw->vring[i].used, &cfg->queue_used_lo,
> -				     &cfg->queue_used_hi);
> -		vp_iowrite16(hw->vring[i].size, &cfg->queue_size);
> -		ifcvf_set_vq_state(hw, i, hw->vring[i].last_avail_idx);
> -		vp_iowrite16(1, &cfg->queue_enable);
> -	}
> +int ifcvf_set_vq_address(struct ifcvf_hw *hw, u16 qid, u64 desc_area,
> +			 u64 driver_area, u64 device_area)
> +{
> +	struct virtio_pci_common_cfg __iomem *cfg = hw->common_cfg;
> +
> +	vp_iowrite16(qid, &cfg->queue_select);
> +	vp_iowrite64_twopart(desc_area, &cfg->queue_desc_lo,
> +			     &cfg->queue_desc_hi);
> +	vp_iowrite64_twopart(driver_area, &cfg->queue_avail_lo,
> +			     &cfg->queue_avail_hi);
> +	vp_iowrite64_twopart(device_area, &cfg->queue_used_lo,
> +			     &cfg->queue_used_hi);
>   
>   	return 0;
>   }
>   
> -static void ifcvf_hw_disable(struct ifcvf_hw *hw)
> +void ifcvf_set_vq_ready(struct ifcvf_hw *hw, u16 qid, bool ready)
>   {
> -	u32 i;
> +	struct virtio_pci_common_cfg __iomem *cfg = hw->common_cfg;
> +
> +	vp_iowrite16(qid, &cfg->queue_select);
> +	/* write 0 to queue_enable will suspend a queue*/
> +	vp_iowrite16(ready, &cfg->queue_enable);
> +}
> +
> +bool ifcvf_get_vq_ready(struct ifcvf_hw *hw, u16 qid)
> +{
> +	struct virtio_pci_common_cfg __iomem *cfg = hw->common_cfg;
> +	bool queue_enable;
> +
> +	vp_iowrite16(qid, &cfg->queue_select);
> +	queue_enable = vp_ioread16(&cfg->queue_enable);
> +
> +	return (bool)queue_enable;
> +}
> +
> +static void synchronize_per_vq_irq(struct ifcvf_hw *hw)
> +{
> +	int i;
>   
> -	ifcvf_set_config_vector(hw, VIRTIO_MSI_NO_VECTOR);
>   	for (i = 0; i < hw->nr_vring; i++) {
> -		ifcvf_set_vq_vector(hw, i, VIRTIO_MSI_NO_VECTOR);
> +		if (hw->vring[i].irq != -EINVAL)
> +			synchronize_irq(hw->vring[i].irq);
>   	}
>   }
>   
> -int ifcvf_start_hw(struct ifcvf_hw *hw)
> +static void synchronize_vqs_reused_irq(struct ifcvf_hw *hw)
>   {
> -	ifcvf_reset(hw);
> -	ifcvf_add_status(hw, VIRTIO_CONFIG_S_ACKNOWLEDGE);
> -	ifcvf_add_status(hw, VIRTIO_CONFIG_S_DRIVER);
> +	if (hw->vqs_reused_irq != -EINVAL)
> +		synchronize_irq(hw->vqs_reused_irq);
> +}
>   
> -	if (ifcvf_config_features(hw) < 0)
> -		return -EINVAL;
> +static void synchronize_vq_irq(struct ifcvf_hw *hw)
> +{
> +	u8 status = hw->msix_vector_status;
>   
> -	if (ifcvf_hw_enable(hw) < 0)
> -		return -EINVAL;
> +	if (status == MSIX_VECTOR_PER_VQ_AND_CONFIG)
> +		synchronize_per_vq_irq(hw);
> +	else
> +		synchronize_vqs_reused_irq(hw);
> +}
>   
> -	ifcvf_add_status(hw, VIRTIO_CONFIG_S_DRIVER_OK);
> +static void synchronize_config_irq(struct ifcvf_hw *hw)
> +{
> +	if (hw->config_irq != -EINVAL)
> +		synchronize_irq(hw->config_irq);
> +}
>   
> -	return 0;
> +static void ifcvf_reset_vring(struct ifcvf_hw *hw)
> +{
> +	int i;
> +
> +	for (i = 0; i < hw->nr_vring; i++) {
> +		synchronize_vq_irq(hw);
> +		hw->vring[i].cb.callback = NULL;
> +		hw->vring[i].cb.private = NULL;
> +		ifcvf_set_vq_vector(hw, i, VIRTIO_MSI_NO_VECTOR);
> +	}
> +}
> +
> +static void ifcvf_reset_config_handler(struct ifcvf_hw *hw)
> +{
> +	synchronize_config_irq(hw);
> +	hw->config_cb.callback = NULL;
> +	hw->config_cb.private = NULL;
> +	ifcvf_set_config_vector(hw, VIRTIO_MSI_NO_VECTOR);
>   }
>   
>   void ifcvf_stop_hw(struct ifcvf_hw *hw)
>   {
> -	ifcvf_hw_disable(hw);
> -	ifcvf_reset(hw);
> +	ifcvf_reset_vring(hw);
> +	ifcvf_reset_config_handler(hw);
>   }
>   
>   void ifcvf_notify_queue(struct ifcvf_hw *hw, u16 qid)
> diff --git a/drivers/vdpa/ifcvf/ifcvf_base.h b/drivers/vdpa/ifcvf/ifcvf_base.h
> index 115b61f4924b..f3dce0d795cb 100644
> --- a/drivers/vdpa/ifcvf/ifcvf_base.h
> +++ b/drivers/vdpa/ifcvf/ifcvf_base.h
> @@ -49,12 +49,6 @@
>   #define MSIX_VECTOR_DEV_SHARED			3
>   
>   struct vring_info {
> -	u64 desc;
> -	u64 avail;
> -	u64 used;
> -	u16 size;
> -	u16 last_avail_idx;
> -	bool ready;
>   	void __iomem *notify_addr;
>   	phys_addr_t notify_pa;
>   	u32 irq;
> @@ -76,7 +70,6 @@ struct ifcvf_hw {
>   	phys_addr_t notify_base_pa;
>   	u32 notify_off_multiplier;
>   	u32 dev_type;
> -	u64 req_features;
>   	u64 hw_features;
>   	struct virtio_pci_common_cfg __iomem *common_cfg;
>   	void __iomem *dev_cfg;
> @@ -123,7 +116,7 @@ u8 ifcvf_get_status(struct ifcvf_hw *hw);
>   void ifcvf_set_status(struct ifcvf_hw *hw, u8 status);
>   void io_write64_twopart(u64 val, u32 *lo, u32 *hi);
>   void ifcvf_reset(struct ifcvf_hw *hw);
> -u64 ifcvf_get_features(struct ifcvf_hw *hw);
> +u64 ifcvf_get_device_features(struct ifcvf_hw *hw);
>   u64 ifcvf_get_hw_features(struct ifcvf_hw *hw);
>   int ifcvf_verify_min_features(struct ifcvf_hw *hw, u64 features);
>   u16 ifcvf_get_vq_state(struct ifcvf_hw *hw, u16 qid);
> @@ -131,6 +124,13 @@ int ifcvf_set_vq_state(struct ifcvf_hw *hw, u16 qid, u16 num);
>   struct ifcvf_adapter *vf_to_adapter(struct ifcvf_hw *hw);
>   int ifcvf_probed_virtio_net(struct ifcvf_hw *hw);
>   u32 ifcvf_get_config_size(struct ifcvf_hw *hw);
> +int ifcvf_set_vq_address(struct ifcvf_hw *hw, u16 qid, u64 desc_area,
> +			 u64 driver_area, u64 device_area);
>   u16 ifcvf_set_vq_vector(struct ifcvf_hw *hw, u16 qid, int vector);
>   u16 ifcvf_set_config_vector(struct ifcvf_hw *hw, int vector);
> +void ifcvf_set_vq_num(struct ifcvf_hw *hw, u16 qid, u32 num);
> +void ifcvf_set_vq_ready(struct ifcvf_hw *hw, u16 qid, bool ready);
> +bool ifcvf_get_vq_ready(struct ifcvf_hw *hw, u16 qid);
> +void ifcvf_set_features(struct ifcvf_hw *hw, u64 features);
> +u64 ifcvf_get_features(struct ifcvf_hw *hw);
>   #endif /* _IFCVF_H_ */
> diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c
> index 4366320fb68d..0257ba98cffe 100644
> --- a/drivers/vdpa/ifcvf/ifcvf_main.c
> +++ b/drivers/vdpa/ifcvf/ifcvf_main.c
> @@ -358,53 +358,6 @@ static int ifcvf_request_irq(struct ifcvf_adapter *adapter)
>   	return 0;
>   }
>   
> -static int ifcvf_start_datapath(void *private)
> -{
> -	struct ifcvf_hw *vf = ifcvf_private_to_vf(private);
> -	u8 status;
> -	int ret;
> -
> -	ret = ifcvf_start_hw(vf);
> -	if (ret < 0) {
> -		status = ifcvf_get_status(vf);
> -		status |= VIRTIO_CONFIG_S_FAILED;
> -		ifcvf_set_status(vf, status);
> -	}
> -
> -	return ret;
> -}
> -
> -static int ifcvf_stop_datapath(void *private)
> -{
> -	struct ifcvf_hw *vf = ifcvf_private_to_vf(private);
> -	int i;
> -
> -	for (i = 0; i < vf->nr_vring; i++)
> -		vf->vring[i].cb.callback = NULL;
> -
> -	ifcvf_stop_hw(vf);
> -
> -	return 0;
> -}
> -
> -static void ifcvf_reset_vring(struct ifcvf_adapter *adapter)
> -{
> -	struct ifcvf_hw *vf = ifcvf_private_to_vf(adapter);
> -	int i;
> -
> -	for (i = 0; i < vf->nr_vring; i++) {
> -		vf->vring[i].last_avail_idx = 0;
> -		vf->vring[i].desc = 0;
> -		vf->vring[i].avail = 0;
> -		vf->vring[i].used = 0;
> -		vf->vring[i].ready = 0;
> -		vf->vring[i].cb.callback = NULL;
> -		vf->vring[i].cb.private = NULL;
> -	}
> -
> -	ifcvf_reset(vf);
> -}
> -
>   static struct ifcvf_adapter *vdpa_to_adapter(struct vdpa_device *vdpa_dev)
>   {
>   	return container_of(vdpa_dev, struct ifcvf_adapter, vdpa);
> @@ -426,7 +379,7 @@ static u64 ifcvf_vdpa_get_device_features(struct vdpa_device *vdpa_dev)
>   	u64 features;
>   
>   	if (type == VIRTIO_ID_NET || type == VIRTIO_ID_BLOCK)
> -		features = ifcvf_get_features(vf);
> +		features = ifcvf_get_device_features(vf);
>   	else {
>   		features = 0;
>   		IFCVF_ERR(pdev, "VIRTIO ID %u not supported\n", vf->dev_type);
> @@ -444,7 +397,7 @@ static int ifcvf_vdpa_set_driver_features(struct vdpa_device *vdpa_dev, u64 feat
>   	if (ret)
>   		return ret;
>   
> -	vf->req_features = features;
> +	ifcvf_set_features(vf, features);
>   
>   	return 0;
>   }
> @@ -453,7 +406,7 @@ static u64 ifcvf_vdpa_get_driver_features(struct vdpa_device *vdpa_dev)
>   {
>   	struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);
>   
> -	return vf->req_features;
> +	return ifcvf_get_features(vf);
>   }
>   
>   static u8 ifcvf_vdpa_get_status(struct vdpa_device *vdpa_dev)
> @@ -486,11 +439,6 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
>   			ifcvf_set_status(vf, status);
>   			return;
>   		}
> -
> -		if (ifcvf_start_datapath(adapter) < 0)
> -			IFCVF_ERR(adapter->pdev,
> -				  "Failed to set ifcvf vdpa  status %u\n",
> -				  status);
>   	}
>   
>   	ifcvf_set_status(vf, status);
> @@ -509,12 +457,10 @@ static int ifcvf_vdpa_reset(struct vdpa_device *vdpa_dev)
>   	if (status_old == 0)
>   		return 0;
>   
> -	if (status_old & VIRTIO_CONFIG_S_DRIVER_OK) {
> -		ifcvf_stop_datapath(adapter);
> -		ifcvf_free_irq(adapter);
> -	}
> +	ifcvf_stop_hw(vf);
> +	ifcvf_free_irq(adapter);
>   
> -	ifcvf_reset_vring(adapter);
> +	ifcvf_reset(vf);
>   
>   	return 0;
>   }
> @@ -554,14 +500,17 @@ static void ifcvf_vdpa_set_vq_ready(struct vdpa_device *vdpa_dev,
>   {
>   	struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);
>   
> -	vf->vring[qid].ready = ready;
> +	ifcvf_set_vq_ready(vf, qid, ready);
>   }
>   
>   static bool ifcvf_vdpa_get_vq_ready(struct vdpa_device *vdpa_dev, u16 qid)
>   {
>   	struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);
> +	bool ready;
> +
> +	ready = ifcvf_get_vq_ready(vf, qid);
>   
> -	return vf->vring[qid].ready;
> +	return ready;
>   }
>   
>   static void ifcvf_vdpa_set_vq_num(struct vdpa_device *vdpa_dev, u16 qid,
> @@ -569,7 +518,7 @@ static void ifcvf_vdpa_set_vq_num(struct vdpa_device *vdpa_dev, u16 qid,
>   {
>   	struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);
>   
> -	vf->vring[qid].size = num;
> +	ifcvf_set_vq_num(vf, qid, num);
>   }
>   
>   static int ifcvf_vdpa_set_vq_address(struct vdpa_device *vdpa_dev, u16 qid,
> @@ -578,11 +527,7 @@ static int ifcvf_vdpa_set_vq_address(struct vdpa_device *vdpa_dev, u16 qid,
>   {
>   	struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);
>   
> -	vf->vring[qid].desc = desc_area;
> -	vf->vring[qid].avail = driver_area;
> -	vf->vring[qid].used = device_area;
> -
> -	return 0;
> +	return ifcvf_set_vq_address(vf, qid, desc_area, driver_area, device_area);
>   }
>   
>   static void ifcvf_vdpa_kick_vq(struct vdpa_device *vdpa_dev, u16 qid)


^ permalink raw reply

* Re: [PATCH memcg v4] net: set proper memcg for net_init hooks allocations
From: Shakeel Butt @ 2022-04-27  5:23 UTC (permalink / raw)
  To: Vasily Averin
  Cc: Vlastimil Babka, Roman Gushchin, kernel, Florian Westphal, LKML,
	Michal Hocko, Cgroups, netdev, David S. Miller, Jakub Kicinski,
	Paolo Abeni
In-Reply-To: <33085523-a8b9-1bf6-2726-f456f59015ef@openvz.org>

On Mon, Apr 25, 2022 at 11:43 PM Vasily Averin <vvs@openvz.org> wrote:
>
> __register_pernet_operations() executes init hook of registered
> pernet_operation structure in all existing net namespaces.
>
> Typically, these hooks are called by a process associated with
> the specified net namespace, and all __GFP_ACCOUNT marked
> allocation are accounted for corresponding container/memcg.
>
> However __register_pernet_operations() calls the hooks in the same
> context, and as a result all marked allocations are accounted
> to one memcg for all processed net namespaces.
>
> This patch adjusts active memcg for each net namespace and helps
> to account memory allocated inside ops_init() into the proper memcg.
>
> Signed-off-by: Vasily Averin <vvs@openvz.org>

Acked-by: Shakeel Butt <shakeelb@google.com>

[...]
>
> +static inline struct mem_cgroup *get_mem_cgroup_from_obj(void *p)
> +{
> +       struct mem_cgroup *memcg;
> +

Do we need memcg_kmem_enabled() check here or maybe
mem_cgroup_from_obj() should be doing memcg_kmem_enabled() instead of
mem_cgroup_disabled() as we can have "cgroup.memory=nokmem" boot
param.

> +       rcu_read_lock();
> +       do {
> +               memcg = mem_cgroup_from_obj(p);
> +       } while (memcg && !css_tryget(&memcg->css));
> +       rcu_read_unlock();
> +       return memcg;
> +}

^ permalink raw reply

* Re: [PATCH v2] ath10k: skip ath10k_halt during suspend for driver state RESTARTING
From: Abhishek Kumar @ 2022-04-27  5:20 UTC (permalink / raw)
  To: Brian Norris
  Cc: kvalo, quic_wgong, Linux Kernel, linux-wireless, ath10k,
	<netdev@vger.kernel.org>, David S. Miller, Jakub Kicinski,
	Paolo Abeni
In-Reply-To: <CA+ASDXPNFwvYVBMHjbTNQ-uTnQrs5TvPAH2jXgPKuFLUw2GbZA@mail.gmail.com>

On Tue, Apr 26, 2022 at 3:34 PM Brian Norris <briannorris@chromium.org> wrote:
>
> On Tue, Apr 26, 2022 at 3:20 PM Abhishek Kumar <kuabhs@chromium.org> wrote:
> >
> > Double free crash is observed when FW recovery(caused by wmi
> > timeout/crash) is followed by immediate suspend event. The FW recovery
> > is triggered by ath10k_core_restart() which calls driver clean up via
> > ath10k_halt(). When the suspend event occurs between the FW recovery,
> > the restart worker thread is put into frozen state until suspend completes.
> > The suspend event triggers ath10k_stop() which again triggers ath10k_halt()
> > The double invocation of ath10k_halt() causes ath10k_htt_rx_free() to be
> > called twice(Note: ath10k_htt_rx_alloc was not called by restart worker
> > thread because of its frozen state), causing the crash.
> ...
> > Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1
> > Co-developed-by: Wen Gong <quic_wgong@quicinc.com>
> > Signed-off-by: Wen Gong <quic_wgong@quicinc.com>
> > Signed-off-by: Abhishek Kumar <kuabhs@chromium.org>
> > ---
> >
> > Changes in v2:
> > - Fixed typo, replaced ath11k by ath10k in the comments.
> > - Adjusted the position of my S-O-B tag.
> > - Added the Tested-on tag.
>
> You could have retained my:
>
> Reviewed-by: Brian Norris <briannorris@chromium.org>
>
> but no worries; it's just a few characters ;)
Oh! sorry about that, I was under the impression that if the next
iteration is posted, then I cannot just add the Reviewed-by tag
provided in the previous iteration by myself.

^ permalink raw reply

* Re: [PATCH v2] rtlwifi: btcoex: fix if == else warning
From: Kalle Valo @ 2022-04-27  5:04 UTC (permalink / raw)
  To: Guo Zhengkui
  Cc: Ping-Ke Shih, David S. Miller, Jakub Kicinski, Paolo Abeni,
	Guo Zhengkui, open list:REALTEK WIRELESS DRIVER (rtlwifi family),
	open list:NETWORKING DRIVERS, open list, zhengkui_guo
In-Reply-To: <20220425031725.5808-1-guozhengkui@vivo.com>

Guo Zhengkui <guozhengkui@vivo.com> wrote:

> Fix the following coccicheck warning:
> 
> drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8821a1ant.c:1604:2-4:
> WARNING: possible condition with no effect (if == else).
> 
> Signed-off-by: Guo Zhengkui <guozhengkui@vivo.com>
> Acked-by: Ping-Ke Shih <pkshih@realtek.com>

Patch applied to wireless-next.git, thanks.

8c783024d6ac rtlwifi: btcoex: fix if == else warning

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20220425031725.5808-1-guozhengkui@vivo.com/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH] brcmfmac: use ISO3166 country code and 0 rev as fallback on brcmfmac43602 chips
From: Kalle Valo @ 2022-04-27  5:03 UTC (permalink / raw)
  To: Hamid Zamani
  Cc: Arend van Spriel, Franky Lin, Hante Meuleman, Shawn Guo,
	Hans de Goede, Soeren Moch, linux-wireless,
	brcm80211-dev-list.pdl, SHA-cyfmac-dev-list, netdev, linux-kernel,
	Hamid Zamani
In-Reply-To: <20220423111237.60892-1-hzamani.cs91@gmail.com>

Hamid Zamani <hzamani.cs91@gmail.com> wrote:

> This uses ISO3166 country code and 0 rev on brcmfmac43602 chips.
> Without this patch 80 MHz width is not selected on 5 GHz channels.
> 
> Commit a21bf90e927f ("brcmfmac: use ISO3166 country code and 0 rev as
> fallback on some devices") provides a way to specify chips for using the
> fallback case.
> 
> Before commit 151a7c12c4fc ("Revert "brcmfmac: use ISO3166 country code
> and 0 rev as fallback"") brcmfmac43602 devices works correctly and for
> this specific case 80 MHz width is selected.
> 
> Signed-off-by: Hamid Zamani <hzamani.cs91@gmail.com>

Patch applied to wireless-next.git, thanks.

21947f3a74d6 brcmfmac: use ISO3166 country code and 0 rev as fallback on brcmfmac43602 chips

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20220423111237.60892-1-hzamani.cs91@gmail.com/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH v2 1/2] mwifiex: Select firmware based on strapping
From: Kalle Valo @ 2022-04-27  4:56 UTC (permalink / raw)
  To: Andrejs Cainikovs
  Cc: linux-wireless, Amitkumar Karwar, Ganapathi Bhat,
	Sharvari Harisangam, Xinming Hu, Andrejs Cainikovs,
	David S . Miller, Jakub Kicinski, Brian Norris,
	Jonas Dreßler, Alvin Šipraga, Francesco Dolcini, netdev
In-Reply-To: <20220422090313.125857-2-andrejs.cainikovs@toradex.com>

Andrejs Cainikovs <andrejs.cainikovs@toradex.com> wrote:

> Some WiFi/Bluetooth modules might have different host connection
> options, allowing to either use SDIO for both WiFi and Bluetooth,
> or SDIO for WiFi and UART for Bluetooth. It is possible to detect
> whether a module has SDIO-SDIO or SDIO-UART connection by reading
> its host strap register.
> 
> This change introduces a way to automatically select appropriate
> firmware depending of the connection method, and removes a need
> of symlinking or overwriting the original firmware file with a
> required one.
> 
> Host strap register used in this commit comes from the NXP driver [1]
> hosted at Code Aurora.
> 
> [1] https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/net/wireless/nxp/mxm_wifiex/wlan_src/mlinux/moal_sdio_mmc.c?h=rel_imx_5.4.70_2.3.2&id=688b67b2c7220b01521ffe560da7eee33042c7bd#n1274
> 
> Signed-off-by: Andrejs Cainikovs <andrejs.cainikovs@toradex.com>
> Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>

2 patches applied to wireless-next.git, thanks.

255ca28a659d mwifiex: Select firmware based on strapping
562354ab9f0a mwifiex: Add SD8997 SDIO-UART firmware

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20220422090313.125857-2-andrejs.cainikovs@toradex.com/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH v22 1/2] wireless: Initial driver submission for pureLiFi STA devices
From: Kalle Valo @ 2022-04-27  4:55 UTC (permalink / raw)
  To: Srinivasan Raju
  Cc: mostafa.afgani, David S. Miller, Jakub Kicinski, open list,
	open list:NETWORKING DRIVERS (WIRELESS),
	open list:NETWORKING DRIVERS
In-Reply-To: <20220224182042.132466-3-srini.raju@purelifi.com>

Srinivasan Raju <srini.raju@purelifi.com> wrote:

> This driver implementation has been based on the zd1211rw driver
> 
> Driver is based on 802.11 softMAC Architecture and uses
> native 802.11 for configuration and management
> 
> The driver is compiled and tested in ARM, x86 architectures and
> compiled in powerpc architecture
> 
> Signed-off-by: Srinivasan Raju <srini.raju@purelifi.com>

Applied with my changes to wireless-next:

68d57a07bfe5 wireless: add plfxlc driver for pureLiFi X, XL, XC devices

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20220224182042.132466-3-srini.raju@purelifi.com/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


^ permalink raw reply

* Re: [PATCH net-next 03/28] sfc: Copy shared files needed for Siena
From: Benjamin Poirier @ 2022-04-27  4:47 UTC (permalink / raw)
  To: Jakub Kicinski, pabeni, davem, netdev, ecree.xilinx
In-Reply-To: <20220425072257.sfsmelc42favw2th@gmail.com>

On 2022-04-25 08:22 +0100, Martin Habets wrote:
> On Sat, Apr 23, 2022 at 06:50:07AM -0700, Jakub Kicinski wrote:
> > On Fri, 22 Apr 2022 15:57:43 +0100 Martin Habets wrote:
> > > From: Martin Habets <martinh@xilinx.com>
> > > 
> > > No changes are done, those will be done with subsequent commits.
> > 
> > This ginormous patch does not make it thru the mail systems.
> > I'm guessing there is a (perfectly reasonable) 1MB limit somewhere.
> 
> I think the issue is with mcdi_pcol.h, which is 1.1MB of defines
> generated from the hardware databases. It has grown slowely over the
> years.
> I'll split up this patch and see if I can manually cut down mcdi_pcol.h.
> 

In this case, by using `git format-patch --find-copies-harder [...]` it
greatly reduces the size of patch 03 from 1.9M to 22K and makes the
actual changes easier to spot as well:

[...]
 .../net/ethernet/sfc/{ => siena}/bitfield.h   |   0
 drivers/net/ethernet/sfc/{ => siena}/efx.c    |   0
 drivers/net/ethernet/sfc/{ => siena}/efx.h    |   0
 .../ethernet/sfc/{ => siena}/efx_channels.c   | 148 ++++++++----------
 .../ethernet/sfc/{ => siena}/efx_channels.h   |   0
 .../net/ethernet/sfc/{ => siena}/efx_common.c |   0
 .../net/ethernet/sfc/{ => siena}/efx_common.h |   0

That being said, I don't want to discourage you from doing that rework!

^ permalink raw reply

* Re: [PATCH net 1/2] ptp: ptp_clockmatrix: Add PTP_CLK_REQ_EXTTS support
From: kernel test robot @ 2022-04-27  4:46 UTC (permalink / raw)
  To: Min Li, richardcochran, lee.jones
  Cc: kbuild-all, linux-kernel, netdev, Min Li
In-Reply-To: <1651001574-32457-1-git-send-email-min.li.xe@renesas.com>

Hi Min,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on net/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Min-Li/ptp-ptp_clockmatrix-Add-PTP_CLK_REQ_EXTTS-support/20220427-033506
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git acb16b395c3f3d7502443e0c799c2b42df645642
config: mips-allmodconfig (https://download.01.org/0day-ci/archive/20220427/202204271207.RNo6doix-lkp@intel.com/config)
compiler: mips-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/afadc4edd1bf64b40cb61b38dedf67354baeb147
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Min-Li/ptp-ptp_clockmatrix-Add-PTP_CLK_REQ_EXTTS-support/20220427-033506
        git checkout afadc4edd1bf64b40cb61b38dedf67354baeb147
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=mips SHELL=/bin/bash drivers/iio/imu/ drivers/ptp/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/ptp/ptp_clockmatrix.c:1734: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst
    * Maximum absolute value for write phase offset in picoseconds


vim +1734 drivers/ptp/ptp_clockmatrix.c

3a6ba7dc779935 Vincent Cheng 2019-10-31  1732  
afadc4edd1bf64 Min Li        2022-04-26  1733  /**
da9facf1c18252 Min Li        2021-09-13 @1734   * Maximum absolute value for write phase offset in picoseconds
da9facf1c18252 Min Li        2021-09-13  1735   *
afadc4edd1bf64 Min Li        2022-04-26  1736   * @channel:  channel
afadc4edd1bf64 Min Li        2022-04-26  1737   * @delta_ns: delta in nanoseconds
afadc4edd1bf64 Min Li        2022-04-26  1738   *
425d2b1c563826 Vincent Cheng 2020-05-01  1739   * Destination signed register is 32-bit register in resolution of 50ps
425d2b1c563826 Vincent Cheng 2020-05-01  1740   *
425d2b1c563826 Vincent Cheng 2020-05-01  1741   * 0x7fffffff * 50 =  2147483647 * 50 = 107374182350
425d2b1c563826 Vincent Cheng 2020-05-01  1742   */
425d2b1c563826 Vincent Cheng 2020-05-01  1743  static int _idtcm_adjphase(struct idtcm_channel *channel, s32 delta_ns)
425d2b1c563826 Vincent Cheng 2020-05-01  1744  {
425d2b1c563826 Vincent Cheng 2020-05-01  1745  	struct idtcm *idtcm = channel->idtcm;
425d2b1c563826 Vincent Cheng 2020-05-01  1746  	int err;
425d2b1c563826 Vincent Cheng 2020-05-01  1747  	u8 i;
425d2b1c563826 Vincent Cheng 2020-05-01  1748  	u8 buf[4] = {0};
425d2b1c563826 Vincent Cheng 2020-05-01  1749  	s32 phase_50ps;
425d2b1c563826 Vincent Cheng 2020-05-01  1750  	s64 offset_ps;
425d2b1c563826 Vincent Cheng 2020-05-01  1751  
da9facf1c18252 Min Li        2021-09-13  1752  	if (channel->mode != PTP_PLL_MODE_WRITE_PHASE) {
da9facf1c18252 Min Li        2021-09-13  1753  		err = channel->configure_write_phase(channel);
425d2b1c563826 Vincent Cheng 2020-05-01  1754  		if (err)
425d2b1c563826 Vincent Cheng 2020-05-01  1755  			return err;
425d2b1c563826 Vincent Cheng 2020-05-01  1756  	}
425d2b1c563826 Vincent Cheng 2020-05-01  1757  
425d2b1c563826 Vincent Cheng 2020-05-01  1758  	offset_ps = (s64)delta_ns * 1000;
425d2b1c563826 Vincent Cheng 2020-05-01  1759  
425d2b1c563826 Vincent Cheng 2020-05-01  1760  	/*
425d2b1c563826 Vincent Cheng 2020-05-01  1761  	 * Check for 32-bit signed max * 50:
425d2b1c563826 Vincent Cheng 2020-05-01  1762  	 *
425d2b1c563826 Vincent Cheng 2020-05-01  1763  	 * 0x7fffffff * 50 =  2147483647 * 50 = 107374182350
425d2b1c563826 Vincent Cheng 2020-05-01  1764  	 */
425d2b1c563826 Vincent Cheng 2020-05-01  1765  	if (offset_ps > MAX_ABS_WRITE_PHASE_PICOSECONDS)
425d2b1c563826 Vincent Cheng 2020-05-01  1766  		offset_ps = MAX_ABS_WRITE_PHASE_PICOSECONDS;
425d2b1c563826 Vincent Cheng 2020-05-01  1767  	else if (offset_ps < -MAX_ABS_WRITE_PHASE_PICOSECONDS)
425d2b1c563826 Vincent Cheng 2020-05-01  1768  		offset_ps = -MAX_ABS_WRITE_PHASE_PICOSECONDS;
425d2b1c563826 Vincent Cheng 2020-05-01  1769  
7260d1c8fd8667 Min Li        2020-12-08  1770  	phase_50ps = div_s64(offset_ps, 50);
425d2b1c563826 Vincent Cheng 2020-05-01  1771  
425d2b1c563826 Vincent Cheng 2020-05-01  1772  	for (i = 0; i < 4; i++) {
425d2b1c563826 Vincent Cheng 2020-05-01  1773  		buf[i] = phase_50ps & 0xff;
425d2b1c563826 Vincent Cheng 2020-05-01  1774  		phase_50ps >>= 8;
425d2b1c563826 Vincent Cheng 2020-05-01  1775  	}
425d2b1c563826 Vincent Cheng 2020-05-01  1776  
425d2b1c563826 Vincent Cheng 2020-05-01  1777  	err = idtcm_write(idtcm, channel->dpll_phase, DPLL_WR_PHASE,
425d2b1c563826 Vincent Cheng 2020-05-01  1778  			  buf, sizeof(buf));
425d2b1c563826 Vincent Cheng 2020-05-01  1779  
425d2b1c563826 Vincent Cheng 2020-05-01  1780  	return err;
425d2b1c563826 Vincent Cheng 2020-05-01  1781  }
425d2b1c563826 Vincent Cheng 2020-05-01  1782  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply

* Re: [PATCH] vDPA/ifcvf: fix uninitialized config_vector warning
From: Jason Wang @ 2022-04-27  4:22 UTC (permalink / raw)
  To: Zhu Lingshan; +Cc: mst, virtualization, netdev, Dan Carpenter
In-Reply-To: <20220424072806.1083189-1-lingshan.zhu@intel.com>

On Sun, Apr 24, 2022 at 3:36 PM Zhu Lingshan <lingshan.zhu@intel.com> wrote:
>
> Static checkers are not informed that config_vector is controlled
> by vf->msix_vector_status, which can only be
> MSIX_VECTOR_SHARED_VQ_AND_CONFIG, MSIX_VECTOR_SHARED_VQ_AND_CONFIG
> and MSIX_VECTOR_DEV_SHARED.
>
> This commit uses an "if...elseif...else" code block to tell the
> checkers that it is a complete set, and config_vector can be
> initialized anyway
>
> Signed-off-by: Zhu Lingshan <lingshan.zhu@intel.com>
> Reviewed-by: Dan Carpenter <dan.carpenter@oracle.com>

Acked-by: Jason Wang <jasowang@redhat.com>

> ---
>  drivers/vdpa/ifcvf/ifcvf_main.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c
> index 4366320fb68d..9172905fc7ae 100644
> --- a/drivers/vdpa/ifcvf/ifcvf_main.c
> +++ b/drivers/vdpa/ifcvf/ifcvf_main.c
> @@ -290,16 +290,16 @@ static int ifcvf_request_config_irq(struct ifcvf_adapter *adapter)
>         struct ifcvf_hw *vf = &adapter->vf;
>         int config_vector, ret;
>
> -       if (vf->msix_vector_status == MSIX_VECTOR_DEV_SHARED)
> -               return 0;
> -
>         if (vf->msix_vector_status == MSIX_VECTOR_PER_VQ_AND_CONFIG)
> -               /* vector 0 ~ vf->nr_vring for vqs, num vf->nr_vring vector for config interrupt */
>                 config_vector = vf->nr_vring;
> -
> -       if (vf->msix_vector_status ==  MSIX_VECTOR_SHARED_VQ_AND_CONFIG)
> +       else if (vf->msix_vector_status ==  MSIX_VECTOR_SHARED_VQ_AND_CONFIG)
>                 /* vector 0 for vqs and 1 for config interrupt */
>                 config_vector = 1;
> +       else if (vf->msix_vector_status == MSIX_VECTOR_DEV_SHARED)
> +               /* re-use the vqs vector */
> +               return 0;
> +       else
> +               return -EINVAL;
>
>         snprintf(vf->config_msix_name, 256, "ifcvf[%s]-config\n",
>                  pci_name(pdev));
> --
> 2.31.1
>


^ permalink raw reply

* [PATCH net-next v6 3/3] ARM: dts: aspeed: add reset properties into MDIO nodes
From: Dylan Hung @ 2022-04-27  3:55 UTC (permalink / raw)
  To: robh+dt, joel, andrew, andrew, hkallweit1, linux, davem, kuba,
	pabeni, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, netdev, krzk+dt
  Cc: BMC-SW
In-Reply-To: <20220427035501.17500-1-dylan_hung@aspeedtech.com>

Add reset control properties into MDIO nodes.  The 4 MDIO controllers in
AST2600 SOC share one reset control bit SCU50[3].

Signed-off-by: Dylan Hung <dylan_hung@aspeedtech.com>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
---
 arch/arm/boot/dts/aspeed-g6.dtsi | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed-g6.dtsi
index 3d5ce9da42c3..6aa1fd5c9359 100644
--- a/arch/arm/boot/dts/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed-g6.dtsi
@@ -181,6 +181,7 @@ mdio0: mdio@1e650000 {
 			status = "disabled";
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_mdio1_default>;
+			resets = <&syscon ASPEED_RESET_MII>;
 		};
 
 		mdio1: mdio@1e650008 {
@@ -191,6 +192,7 @@ mdio1: mdio@1e650008 {
 			status = "disabled";
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_mdio2_default>;
+			resets = <&syscon ASPEED_RESET_MII>;
 		};
 
 		mdio2: mdio@1e650010 {
@@ -201,6 +203,7 @@ mdio2: mdio@1e650010 {
 			status = "disabled";
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_mdio3_default>;
+			resets = <&syscon ASPEED_RESET_MII>;
 		};
 
 		mdio3: mdio@1e650018 {
@@ -211,6 +214,7 @@ mdio3: mdio@1e650018 {
 			status = "disabled";
 			pinctrl-names = "default";
 			pinctrl-0 = <&pinctrl_mdio4_default>;
+			resets = <&syscon ASPEED_RESET_MII>;
 		};
 
 		mac0: ftgmac@1e660000 {
-- 
2.25.1


^ permalink raw reply related

* [PATCH net-next v6 0/3] Add reset deassertion for Aspeed MDIO
From: Dylan Hung @ 2022-04-27  3:54 UTC (permalink / raw)
  To: robh+dt, joel, andrew, andrew, hkallweit1, linux, davem, kuba,
	pabeni, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, netdev, krzk+dt
  Cc: BMC-SW

Add missing reset deassertion for Aspeed MDIO bus controller. The reset
is asserted by the hardware when power-on so the driver only needs to
deassert it. To be able to work with the old DT blobs, the reset is
optional since it may be deasserted by the bootloader or the previous
kernel.

V6:
- fix merge conflict for net-next

V5:
- fix error of dt_binding_check

V4:
- use ASPEED_RESET_MII instead of hardcoding in dt-binding example

V3:
- remove reset property from the required list of the device tree
  bindings
- remove "Cc: stable@vger.kernel.org" from the commit messages
- add more description in the commit message of the dt-binding

V2:
- add reset property in the device tree bindings
- add reset assertion in the error path and driver remove

Dylan Hung (3):
  dt-bindings: net: add reset property for aspeed, ast2600-mdio binding
  net: mdio: add reset control for Aspeed MDIO
  ARM: dts: aspeed: add reset properties into MDIO nodes

 .../bindings/net/aspeed,ast2600-mdio.yaml         |  6 ++++++
 arch/arm/boot/dts/aspeed-g6.dtsi                  |  4 ++++
 drivers/net/mdio/mdio-aspeed.c                    | 15 ++++++++++++++-
 3 files changed, 24 insertions(+), 1 deletion(-)

-- 
2.25.1


^ permalink raw reply

* [PATCH net-next v6 1/3] dt-bindings: net: add reset property for aspeed, ast2600-mdio binding
From: Dylan Hung @ 2022-04-27  3:54 UTC (permalink / raw)
  To: robh+dt, joel, andrew, andrew, hkallweit1, linux, davem, kuba,
	pabeni, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, netdev, krzk+dt
  Cc: BMC-SW, Krzysztof Kozlowski
In-Reply-To: <20220427035501.17500-1-dylan_hung@aspeedtech.com>

The AST2600 MDIO bus controller has a reset control bit and must be
deasserted before manipulating the MDIO controller. By default, the
hardware asserts the reset so the driver only need to deassert it.

Regarding to the old DT blobs which don't have reset property in them,
the reset deassertion is usually done by the bootloader so the reset
property is optional to work with them.

Signed-off-by: Dylan Hung <dylan_hung@aspeedtech.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
---
 .../devicetree/bindings/net/aspeed,ast2600-mdio.yaml        | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml b/Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml
index 1c88820cbcdf..f81eda8cb0a5 100644
--- a/Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml
+++ b/Documentation/devicetree/bindings/net/aspeed,ast2600-mdio.yaml
@@ -20,10 +20,14 @@ allOf:
 properties:
   compatible:
     const: aspeed,ast2600-mdio
+
   reg:
     maxItems: 1
     description: The register range of the MDIO controller instance
 
+  resets:
+    maxItems: 1
+
 required:
   - compatible
   - reg
@@ -34,11 +38,13 @@ unevaluatedProperties: false
 
 examples:
   - |
+    #include <dt-bindings/clock/ast2600-clock.h>
     mdio0: mdio@1e650000 {
             compatible = "aspeed,ast2600-mdio";
             reg = <0x1e650000 0x8>;
             #address-cells = <1>;
             #size-cells = <0>;
+            resets = <&syscon ASPEED_RESET_MII>;
 
             ethphy0: ethernet-phy@0 {
                     compatible = "ethernet-phy-ieee802.3-c22";
-- 
2.25.1


^ permalink raw reply related

* [PATCH net-next v6 2/3] net: mdio: add reset control for Aspeed MDIO
From: Dylan Hung @ 2022-04-27  3:55 UTC (permalink / raw)
  To: robh+dt, joel, andrew, andrew, hkallweit1, linux, davem, kuba,
	pabeni, p.zabel, devicetree, linux-arm-kernel, linux-aspeed,
	linux-kernel, netdev, krzk+dt
  Cc: BMC-SW
In-Reply-To: <20220427035501.17500-1-dylan_hung@aspeedtech.com>

Add reset assertion/deassertion for Aspeed MDIO.  There are 4 MDIO
controllers embedded in Aspeed AST2600 SOC and share one reset control
register SCU50[3].  To work with old DT blobs which don't have the reset
property, devm_reset_control_get_optional_shared is used in this change.

Signed-off-by: Dylan Hung <dylan_hung@aspeedtech.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
---
 drivers/net/mdio/mdio-aspeed.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mdio/mdio-aspeed.c b/drivers/net/mdio/mdio-aspeed.c
index 7aa49827196f..944d005d2bd1 100644
--- a/drivers/net/mdio/mdio-aspeed.c
+++ b/drivers/net/mdio/mdio-aspeed.c
@@ -3,6 +3,7 @@
 
 #include <linux/bitfield.h>
 #include <linux/delay.h>
+#include <linux/reset.h>
 #include <linux/iopoll.h>
 #include <linux/mdio.h>
 #include <linux/module.h>
@@ -41,6 +42,7 @@
 
 struct aspeed_mdio {
 	void __iomem *base;
+	struct reset_control *reset;
 };
 
 static int aspeed_mdio_op(struct mii_bus *bus, u8 st, u8 op, u8 phyad, u8 regad,
@@ -174,6 +176,12 @@ static int aspeed_mdio_probe(struct platform_device *pdev)
 	if (IS_ERR(ctx->base))
 		return PTR_ERR(ctx->base);
 
+	ctx->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+	if (IS_ERR(ctx->reset))
+		return PTR_ERR(ctx->reset);
+
+	reset_control_deassert(ctx->reset);
+
 	bus->name = DRV_NAME;
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s%d", pdev->name, pdev->id);
 	bus->parent = &pdev->dev;
@@ -184,6 +192,7 @@ static int aspeed_mdio_probe(struct platform_device *pdev)
 	rc = of_mdiobus_register(bus, pdev->dev.of_node);
 	if (rc) {
 		dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
+		reset_control_assert(ctx->reset);
 		return rc;
 	}
 
@@ -194,7 +203,11 @@ static int aspeed_mdio_probe(struct platform_device *pdev)
 
 static int aspeed_mdio_remove(struct platform_device *pdev)
 {
-	mdiobus_unregister(platform_get_drvdata(pdev));
+	struct mii_bus *bus = (struct mii_bus *)platform_get_drvdata(pdev);
+	struct aspeed_mdio *ctx = bus->priv;
+
+	reset_control_assert(ctx->reset);
+	mdiobus_unregister(bus);
 
 	return 0;
 }
-- 
2.25.1


^ permalink raw reply related

* Re: [RFC PATCH bpf-next 0/2] bpf: Introduce ternary search tree for string key
From: Andrii Nakryiko @ 2022-04-27  3:57 UTC (permalink / raw)
  To: Hou Tao
  Cc: Alexei Starovoitov, Yonghong Song, Daniel Borkmann,
	Martin KaFai Lau, Andrii Nakryiko, Song Liu, KP Singh,
	David S . Miller, Jakub Kicinski, John Fastabend, Networking, bpf
In-Reply-To: <bcaef485-fca6-a5e3-68da-c895b802b352@huawei.com>

On Tue, Apr 26, 2022 at 1:03 AM Hou Tao <houtao1@huawei.com> wrote:
>
> Hi,
>
> On 4/15/2022 5:25 AM, Andrii Nakryiko wrote:
> > On Wed, Apr 13, 2022 at 6:03 PM Hou Tao <houtao1@huawei.com> wrote:
> >> Hi,
> >>
> >> (I send my previous reply in HTML mode mistakenly and the mail list doesn't
> >> receive it, so send it again in the plain text mode.)
> >>
> >> On 4/13/2022 12:09 PM, Andrii Nakryiko wrote:
> >>> On Fri, Apr 8, 2022 at 8:08 PM Hou Tao <houtao1@huawei.com> wrote:
> >>>> Hi,
> >>>>
> >>>> On 4/7/2022 1:38 AM, Andrii Nakryiko wrote:
> >>>>> On Thu, Mar 31, 2022 at 5:04 AM Hou Tao <houtao1@huawei.com> wrote:
> >>>>>> Hi,
> >>>>>>
> >>>>>> The initial motivation for the patchset is due to the suggestion of Alexei.
> >>>>>> During the discuss of supporting of string key in hash-table, he saw the
> >>>>>> space efficiency of ternary search tree under our early test and suggest
> >>>>>> us to post it as a new bpf map [1].
> >>>>>>
> >>>>>> Ternary search tree is a special trie where nodes are arranged in a
> >>>>>> manner similar to binary search tree, but with up to three children
> >>>>>> rather than two. The three children correpond to nodes whose value is
> >>>>>> less than, equal to, and greater than the value of current node
> >>>>>> respectively.
> >>>>>>
> >>>>>> In ternary search tree map, only the valid content of string is saved.
> >>>>>> The trailing null byte and unused bytes after it are not saved. If there
> >>>>>> are common prefixes between these strings, the prefix is only saved once.
> >>>>>> Compared with other space optimized trie (e.g. HAT-trie, succinct trie),
> >>>>>> the advantage of ternary search tree is simple and being writeable.
> >> snip
> >>>>> Have you heard and tried qp-trie ([0]) by any chance? It is elegant
> >>>>> and simple data structure. By all the available benchmarks it handily
> >>>>> beats Red-Black trees in terms of memory usage and performance (though
> >>>>> it of course depends on the data set, just like "memory compression"
> >>>>> for ternary tree of yours depends on large set of common prefixes).
> >>>>> qp-trie based BPF map seems (at least on paper) like a better
> >>>>> general-purpose BPF map that is dynamically sized (avoiding current
> >>>>> HASHMAP limitations) and stores keys in sorted order (and thus allows
> >>>>> meaningful ordered iteration *and*, importantly for longest prefix
> >>>>> match tree, allows efficient prefix matches). I did a quick experiment
> >>>>> about a month ago trying to replace libbpf's internal use of hashmap
> >>>>> with qp-trie for BTF string dedup and it was slightly slower than
> >>>>> hashmap (not surprisingly, though, because libbpf over-sizes hashmap
> >>>>> to avoid hash collisions and long chains in buckets), but it was still
> >>>>> very decent even in that scenario. So I've been mulling the idea of
> >>>>> implementing BPF map based on qp-trie elegant design and ideas, but
> >>>>> can't find time to do this.
> >>>> I have heard about it when check the space efficient of HAT trie [0], because
> >>>> qp-trie needs to save the whole string key in the leaf node and its space
> >>>> efficiency can not be better than ternary search tree for strings with common
> >>>> prefix, so I did not consider about it. But I will do some benchmarks to check
> >>>> the lookup performance and space efficiency of qp-trie and tst for string with
> >>>> common prefix and strings without much common prefix.
> >>>> If qp-trie is better, I think I can take the time to post it as a bpf map if you
> >>>> are OK with that.
> >>> You can probably always craft a data set where prefix sharing is so
> >>> prevalent that space savings are very significant. But I think for a
> >>> lot of real-world data it won't be as extreme and qp-trie might be
> >>> very comparable (if not more memory-efficient) due to very compact
> >>> node layout (which was the point of qp-trie). So I'd be really curious
> >>> to see some comparisons. Would be great if you can try both!
> >> It is a bit surprised to me that qp-trie has better memory efficiency  (and
> >> better lookup performance sometimes) compared with tst when there are not so
> >> many common prefix between input strings (All tests below are conducted by
> >> implementing the data structure in user-space):
> > Thanks for a quick follow up and a benchmark!
> >
> > Low memory use is probably due to the minimal amount of pointers and
> > extra metadata used per node in qp-trie. qp-trie approach is very
> > lean, which is why I was recommending trying it out.
> >
> >> * all unique symbols in /proc/kallsyms (171428 sorted symbols,  4.2MB in total)
> >>
> >>                                         | qp-trie   | tst    | hash   |
> >> total memory used (MB) | 8.6       | 11.2   | 22.3   |
> >> total update time (us) | 94623     | 87396  | 24477  |
> >> total lookup time (us) | 50681     | 67395  | 22842  |
> >>
> >> * all strings in BTF string area (115980 unsorted strings, 2MB in total)
> >>
> >>                                         | qp-trie   | tst    | hash   |
> >> total memory used (MB) | 5.0       | 7.3    | 13.5   |
> >> total update time (us) | 67764     | 43484  | 16462  |
> >> total lookup time (us) | 33732     | 31612  | 16462  |
> >>
> >> * all strings in BTF string area (115980 sorted string, 2MB in total)
> >>
> >>                                        | qp-trie   | tst    | hash   |
> >> total memory used (MB) | 5.0       | 7.3    | 13.5   |
> >> total update time (us) | 58745     | 57756  | 16210  |
> >> total lookup time (us) | 26922     | 40850  | 16896  |
> >>
> >> * all files under Linux kernel (2.7MB, 74359 files generated by find utility
> >> with "./" stripped)
> >>
> >>                                         | qp-trie   | tst    | hash   |
> >> total memory used (MB) | 4.6       | 5.2    | 11.6   |
> >> total update time (us) | 50422     | 28842  | 15255  |
> >> total lookup time (us) | 22543     | 18252  | 11836  |
> > Seems like lookup time is more or less on par (and for kallsyms
> > noticeably faster), but update is sometimes a bit slower. I don't know
> > if you did your own code or used open-source implementation, but keep
> > in mind that performance of qp-trie very much depends on fast
> > __builtin_popcount, so make sure you are using proper -march when
> > compiling. See [0]
> >
> >   [0] https://stackoverflow.com/questions/52161596/why-is-builtin-popcount-slower-than-my-own-bit-counting-function
> I used the open source code from github [0] directly.  And after adding
> -march=native, both the lookup and update performance of qp-trie are improved.
> And the lookup performance of qp-trie is always better than tst, but the update
> performance of  qp-trie is still worse than tst.

Cool, thanks for update! If update is not much worse and the lookup is
better, I think it's a pretty good tradeoff!

>
> [0]: https://github.com/fanf2/qp.git
> >> When the length of common prefix increases, ternary search tree becomes better
> >> than qp-trie.
> >>
> >> * all files under Linux kernel with a comm prefix (e.g. "/home/houtao")
> >>
> >>                                         | qp-trie   | tst    | hash   |
> >> total memory used (MB) | 5.5       | 5.2    | 12.2   |
> >> total update time (us) | 51558     | 29835  | 15345  |
> >> total lookup time (us) | 23121     | 19638  | 11540  |
> >>
> >> Because the lengthy prefix is not so common, and for string map I think the
> >> memory efficiency and lookup performance is more importance than update
> >> performance, so maybe qp-trie is a better choice for string map ?  Any suggestions ?
> >>
> > I'm biased :) But I like the idea of qp-trie as a general purpose
> > ordered and dynamically sized BPF map. It makes no assumption about
> > data being string-like and sharing common prefixes. It can be made to
> > work just as fine with any array of bytes, making it very suitable as
> > a generic lookup table map. Note that upstream implementation does
> > assume zero-terminated strings and no key being a prefix of another
> > key. But all that can be removed. For fixed-length keys this can never
> > happen by construction, for variable-length keys (and we'll be able to
> > support this finally with bpf_dynptr's help very soon), we can record
> > length of the key in each leaf and use that during comparisons.
> Using the trailing zero byte to make sure no key will be a prefix of another is
> simple, but I will check whether or not there is other way to make the bytes
> array key work out. Alexei had suggest me to use the length of key as part of
> key just like bpf_lpm_trie_key does, maybe i can try it first.

Yeah, using key length as part of the key during comparison is what I
meant as well. I didn't mean to aritificially add trailing zero (this
idea doesn't work for arbitrary binary data).

> >
> > Also note that qp-trie can be internally used by BPF_MAP_TYPE_LPM_TRIE
> > very efficiently and speed it up considerable in the process (and
> > especially to get rid of the global lock).
> >
> > So if you were to invest in a proper full-featured production
> > implementation of a BPF map, I'd start with qp-trie. From available
> > benchmarks it's both faster and more memory efficient than Red-Black
> > trees, which could be an alternative underlying implementation of such
> > ordered and "resizable" map.
> Thanks for your suggestions. I will give it a try.

Awesome!

>
> Regards,
> Tao
>
> >> Regards,
> >> Tao
> >>>>> This prefix sharing is nice when you have a lot of long common
> >>>>> prefixes, but I'm a bit skeptical that as a general-purpose BPF data
> >>>>> structure it's going to be that beneficial. 192 bytes of common
> >>>>> prefixes seems like a very unusual dataset :)
> >>>> Yes. The case with common prefix I known is full file path.
> >>>>> More specifically about TST implementation in your paches. One global
> >>>>> per-map lock I think is a very big downside. We have LPM trie which is
> >>>>> very slow in big part due to global lock. It might be possible to
> >>>>> design more granular schema for TST, but this whole in-place splitting
> >>>>> logic makes this harder. I think qp-trie can be locked in a granular
> >>>>> fashion much more easily by having a "hand over hand" locking: lock
> >>>>> parent, find child, lock child, unlock parent, move into child node.
> >>>>> Something like that would be more scalable overall, especially if the
> >>>>> access pattern is not focused on a narrow set of nodes.
> >>>> Yes. The global lock is a problem but the splitting is not in-place. I will try
> >>>> to figure out whether the lock can be more scalable after the benchmark test
> >>>> between qp-trie and tst.
> >>> Great, looking forward!
> >>>
> >>>> Regards,
> >>>> Tao
> >>>>
> >>>> [0]: https://github.com/Tessil/hat-trie
> >>>>> Anyways, I love data structures and this one is an interesting idea.
> >>>>> But just my few cents of "production-readiness" for general-purpose
> >>>>> data structures for BPF.
> >>>>>
> >>>>>   [0] https://dotat.at/prog/qp/README.html
> >>>>>
> >>>>>> Regards,
> >>>>>> Tao
> >>>>>>
> >>>>>> [1]: https://lore.kernel.org/bpf/CAADnVQJUJp3YBcpESwR3Q1U6GS1mBM=Vp-qYuQX7eZOaoLjdUA@mail.gmail.com/
> >>>>>>
> >>>>>> Hou Tao (2):
> >>>>>>   bpf: Introduce ternary search tree for string key
> >>>>>>   selftests/bpf: add benchmark for ternary search tree map
> >>>>>>
> >>>>>>  include/linux/bpf_types.h                     |   1 +
> >>>>>>  include/uapi/linux/bpf.h                      |   1 +
> >>>>>>  kernel/bpf/Makefile                           |   1 +
> >>>>>>  kernel/bpf/bpf_tst.c                          | 411 +++++++++++++++++
> >>>>>>  tools/include/uapi/linux/bpf.h                |   1 +
> >>>>>>  tools/testing/selftests/bpf/Makefile          |   5 +-
> >>>>>>  tools/testing/selftests/bpf/bench.c           |   6 +
> >>>>>>  .../selftests/bpf/benchs/bench_tst_map.c      | 415 ++++++++++++++++++
> >>>>>>  .../selftests/bpf/benchs/run_bench_tst.sh     |  54 +++
> >>>>>>  tools/testing/selftests/bpf/progs/tst_bench.c |  70 +++
> >>>>>>  10 files changed, 964 insertions(+), 1 deletion(-)
> >>>>>>  create mode 100644 kernel/bpf/bpf_tst.c
> >>>>>>  create mode 100644 tools/testing/selftests/bpf/benchs/bench_tst_map.c
> >>>>>>  create mode 100755 tools/testing/selftests/bpf/benchs/run_bench_tst.sh
> >>>>>>  create mode 100644 tools/testing/selftests/bpf/progs/tst_bench.c
> >>>>>>
> >>>>>> --
> >>>>>> 2.31.1
> >>>>>>
> >>>>> .
> >>> .
> > .
>

^ permalink raw reply

* Re: [PATCH net-next] net: Add SO_RCVMARK socket option to provide SO_MARK with recvmsg().
From: kernel test robot @ 2022-04-27  3:25 UTC (permalink / raw)
  To: Erin MacNeil, netdev; +Cc: llvm, kbuild-all, Erin MacNeil
In-Reply-To: <20220426173805.2652-1-lnx.erin@gmail.com>

Hi Erin,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Erin-MacNeil/net-Add-SO_RCVMARK-socket-option-to-provide-SO_MARK-with-recvmsg/20220427-014257
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 561215482cc69d1c758944d4463b3d5d96d37bd1
config: mips-malta_kvm_defconfig (https://download.01.org/0day-ci/archive/20220427/202204271132.O9UPUBp2-lkp@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 1cddcfdc3c683b393df1a5c9063252eb60e52818)
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # install mips cross compiling tool for clang build
        # apt-get install binutils-mips-linux-gnu
        # https://github.com/intel-lab-lkp/linux/commit/ba0c57c49e3f18b23fe626dd2e603cf4ed91ebf7
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Erin-MacNeil/net-Add-SO_RCVMARK-socket-option-to-provide-SO_MARK-with-recvmsg/20220427-014257
        git checkout ba0c57c49e3f18b23fe626dd2e603cf4ed91ebf7
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=mips SHELL=/bin/bash net/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> net/core/sock.c:1314:7: error: use of undeclared identifier 'SO_RCVMARK'; did you mean 'SOCK_RCVMARK'?
           case SO_RCVMARK:
                ^~~~~~~~~~
                SOCK_RCVMARK
   include/net/sock.h:898:2: note: 'SOCK_RCVMARK' declared here
           SOCK_RCVMARK, /* Receive SO_MARK  ancillary data with packet */
           ^
>> net/core/sock.c:1314:7: error: duplicate case value: '27' and 'SOCK_RCVMARK' both equal '27'
           case SO_RCVMARK:
                ^
   net/core/sock.c:1288:7: note: previous case defined here
           case SO_DETACH_FILTER:
                ^
   arch/mips/include/uapi/asm/socket.h:65:26: note: expanded from macro 'SO_DETACH_FILTER'
   #define SO_DETACH_FILTER        27
                                   ^
   net/core/sock.c:1743:7: error: use of undeclared identifier 'SO_RCVMARK'; did you mean 'SOCK_RCVMARK'?
           case SO_RCVMARK:
                ^~~~~~~~~~
                SOCK_RCVMARK
   include/net/sock.h:898:2: note: 'SOCK_RCVMARK' declared here
           SOCK_RCVMARK, /* Receive SO_MARK  ancillary data with packet */
           ^
   3 errors generated.


vim +1314 net/core/sock.c

  1031	
  1032	/*
  1033	 *	This is meant for all protocols to use and covers goings on
  1034	 *	at the socket level. Everything here is generic.
  1035	 */
  1036	
  1037	int sock_setsockopt(struct socket *sock, int level, int optname,
  1038			    sockptr_t optval, unsigned int optlen)
  1039	{
  1040		struct so_timestamping timestamping;
  1041		struct sock_txtime sk_txtime;
  1042		struct sock *sk = sock->sk;
  1043		int val;
  1044		int valbool;
  1045		struct linger ling;
  1046		int ret = 0;
  1047	
  1048		/*
  1049		 *	Options without arguments
  1050		 */
  1051	
  1052		if (optname == SO_BINDTODEVICE)
  1053			return sock_setbindtodevice(sk, optval, optlen);
  1054	
  1055		if (optlen < sizeof(int))
  1056			return -EINVAL;
  1057	
  1058		if (copy_from_sockptr(&val, optval, sizeof(val)))
  1059			return -EFAULT;
  1060	
  1061		valbool = val ? 1 : 0;
  1062	
  1063		lock_sock(sk);
  1064	
  1065		switch (optname) {
  1066		case SO_DEBUG:
  1067			if (val && !capable(CAP_NET_ADMIN))
  1068				ret = -EACCES;
  1069			else
  1070				sock_valbool_flag(sk, SOCK_DBG, valbool);
  1071			break;
  1072		case SO_REUSEADDR:
  1073			sk->sk_reuse = (valbool ? SK_CAN_REUSE : SK_NO_REUSE);
  1074			break;
  1075		case SO_REUSEPORT:
  1076			sk->sk_reuseport = valbool;
  1077			break;
  1078		case SO_TYPE:
  1079		case SO_PROTOCOL:
  1080		case SO_DOMAIN:
  1081		case SO_ERROR:
  1082			ret = -ENOPROTOOPT;
  1083			break;
  1084		case SO_DONTROUTE:
  1085			sock_valbool_flag(sk, SOCK_LOCALROUTE, valbool);
  1086			sk_dst_reset(sk);
  1087			break;
  1088		case SO_BROADCAST:
  1089			sock_valbool_flag(sk, SOCK_BROADCAST, valbool);
  1090			break;
  1091		case SO_SNDBUF:
  1092			/* Don't error on this BSD doesn't and if you think
  1093			 * about it this is right. Otherwise apps have to
  1094			 * play 'guess the biggest size' games. RCVBUF/SNDBUF
  1095			 * are treated in BSD as hints
  1096			 */
  1097			val = min_t(u32, val, sysctl_wmem_max);
  1098	set_sndbuf:
  1099			/* Ensure val * 2 fits into an int, to prevent max_t()
  1100			 * from treating it as a negative value.
  1101			 */
  1102			val = min_t(int, val, INT_MAX / 2);
  1103			sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
  1104			WRITE_ONCE(sk->sk_sndbuf,
  1105				   max_t(int, val * 2, SOCK_MIN_SNDBUF));
  1106			/* Wake up sending tasks if we upped the value. */
  1107			sk->sk_write_space(sk);
  1108			break;
  1109	
  1110		case SO_SNDBUFFORCE:
  1111			if (!capable(CAP_NET_ADMIN)) {
  1112				ret = -EPERM;
  1113				break;
  1114			}
  1115	
  1116			/* No negative values (to prevent underflow, as val will be
  1117			 * multiplied by 2).
  1118			 */
  1119			if (val < 0)
  1120				val = 0;
  1121			goto set_sndbuf;
  1122	
  1123		case SO_RCVBUF:
  1124			/* Don't error on this BSD doesn't and if you think
  1125			 * about it this is right. Otherwise apps have to
  1126			 * play 'guess the biggest size' games. RCVBUF/SNDBUF
  1127			 * are treated in BSD as hints
  1128			 */
  1129			__sock_set_rcvbuf(sk, min_t(u32, val, sysctl_rmem_max));
  1130			break;
  1131	
  1132		case SO_RCVBUFFORCE:
  1133			if (!capable(CAP_NET_ADMIN)) {
  1134				ret = -EPERM;
  1135				break;
  1136			}
  1137	
  1138			/* No negative values (to prevent underflow, as val will be
  1139			 * multiplied by 2).
  1140			 */
  1141			__sock_set_rcvbuf(sk, max(val, 0));
  1142			break;
  1143	
  1144		case SO_KEEPALIVE:
  1145			if (sk->sk_prot->keepalive)
  1146				sk->sk_prot->keepalive(sk, valbool);
  1147			sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
  1148			break;
  1149	
  1150		case SO_OOBINLINE:
  1151			sock_valbool_flag(sk, SOCK_URGINLINE, valbool);
  1152			break;
  1153	
  1154		case SO_NO_CHECK:
  1155			sk->sk_no_check_tx = valbool;
  1156			break;
  1157	
  1158		case SO_PRIORITY:
  1159			if ((val >= 0 && val <= 6) ||
  1160			    ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) ||
  1161			    ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
  1162				sk->sk_priority = val;
  1163			else
  1164				ret = -EPERM;
  1165			break;
  1166	
  1167		case SO_LINGER:
  1168			if (optlen < sizeof(ling)) {
  1169				ret = -EINVAL;	/* 1003.1g */
  1170				break;
  1171			}
  1172			if (copy_from_sockptr(&ling, optval, sizeof(ling))) {
  1173				ret = -EFAULT;
  1174				break;
  1175			}
  1176			if (!ling.l_onoff)
  1177				sock_reset_flag(sk, SOCK_LINGER);
  1178			else {
  1179	#if (BITS_PER_LONG == 32)
  1180				if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
  1181					sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;
  1182				else
  1183	#endif
  1184					sk->sk_lingertime = (unsigned int)ling.l_linger * HZ;
  1185				sock_set_flag(sk, SOCK_LINGER);
  1186			}
  1187			break;
  1188	
  1189		case SO_BSDCOMPAT:
  1190			break;
  1191	
  1192		case SO_PASSCRED:
  1193			if (valbool)
  1194				set_bit(SOCK_PASSCRED, &sock->flags);
  1195			else
  1196				clear_bit(SOCK_PASSCRED, &sock->flags);
  1197			break;
  1198	
  1199		case SO_TIMESTAMP_OLD:
  1200		case SO_TIMESTAMP_NEW:
  1201		case SO_TIMESTAMPNS_OLD:
  1202		case SO_TIMESTAMPNS_NEW:
  1203			sock_set_timestamp(sk, optname, valbool);
  1204			break;
  1205	
  1206		case SO_TIMESTAMPING_NEW:
  1207		case SO_TIMESTAMPING_OLD:
  1208			if (optlen == sizeof(timestamping)) {
  1209				if (copy_from_sockptr(&timestamping, optval,
  1210						      sizeof(timestamping))) {
  1211					ret = -EFAULT;
  1212					break;
  1213				}
  1214			} else {
  1215				memset(&timestamping, 0, sizeof(timestamping));
  1216				timestamping.flags = val;
  1217			}
  1218			ret = sock_set_timestamping(sk, optname, timestamping);
  1219			break;
  1220	
  1221		case SO_RCVLOWAT:
  1222			if (val < 0)
  1223				val = INT_MAX;
  1224			if (sock->ops->set_rcvlowat)
  1225				ret = sock->ops->set_rcvlowat(sk, val);
  1226			else
  1227				WRITE_ONCE(sk->sk_rcvlowat, val ? : 1);
  1228			break;
  1229	
  1230		case SO_RCVTIMEO_OLD:
  1231		case SO_RCVTIMEO_NEW:
  1232			ret = sock_set_timeout(&sk->sk_rcvtimeo, optval,
  1233					       optlen, optname == SO_RCVTIMEO_OLD);
  1234			break;
  1235	
  1236		case SO_SNDTIMEO_OLD:
  1237		case SO_SNDTIMEO_NEW:
  1238			ret = sock_set_timeout(&sk->sk_sndtimeo, optval,
  1239					       optlen, optname == SO_SNDTIMEO_OLD);
  1240			break;
  1241	
  1242		case SO_ATTACH_FILTER: {
  1243			struct sock_fprog fprog;
  1244	
  1245			ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
  1246			if (!ret)
  1247				ret = sk_attach_filter(&fprog, sk);
  1248			break;
  1249		}
  1250		case SO_ATTACH_BPF:
  1251			ret = -EINVAL;
  1252			if (optlen == sizeof(u32)) {
  1253				u32 ufd;
  1254	
  1255				ret = -EFAULT;
  1256				if (copy_from_sockptr(&ufd, optval, sizeof(ufd)))
  1257					break;
  1258	
  1259				ret = sk_attach_bpf(ufd, sk);
  1260			}
  1261			break;
  1262	
  1263		case SO_ATTACH_REUSEPORT_CBPF: {
  1264			struct sock_fprog fprog;
  1265	
  1266			ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
  1267			if (!ret)
  1268				ret = sk_reuseport_attach_filter(&fprog, sk);
  1269			break;
  1270		}
  1271		case SO_ATTACH_REUSEPORT_EBPF:
  1272			ret = -EINVAL;
  1273			if (optlen == sizeof(u32)) {
  1274				u32 ufd;
  1275	
  1276				ret = -EFAULT;
  1277				if (copy_from_sockptr(&ufd, optval, sizeof(ufd)))
  1278					break;
  1279	
  1280				ret = sk_reuseport_attach_bpf(ufd, sk);
  1281			}
  1282			break;
  1283	
  1284		case SO_DETACH_REUSEPORT_BPF:
  1285			ret = reuseport_detach_prog(sk);
  1286			break;
  1287	
  1288		case SO_DETACH_FILTER:
  1289			ret = sk_detach_filter(sk);
  1290			break;
  1291	
  1292		case SO_LOCK_FILTER:
  1293			if (sock_flag(sk, SOCK_FILTER_LOCKED) && !valbool)
  1294				ret = -EPERM;
  1295			else
  1296				sock_valbool_flag(sk, SOCK_FILTER_LOCKED, valbool);
  1297			break;
  1298	
  1299		case SO_PASSSEC:
  1300			if (valbool)
  1301				set_bit(SOCK_PASSSEC, &sock->flags);
  1302			else
  1303				clear_bit(SOCK_PASSSEC, &sock->flags);
  1304			break;
  1305		case SO_MARK:
  1306			if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) &&
  1307			    !ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
  1308				ret = -EPERM;
  1309				break;
  1310			}
  1311	
  1312			__sock_set_mark(sk, val);
  1313			break;
> 1314		case SO_RCVMARK:
  1315			sock_valbool_flag(sk, SOCK_RCVMARK, valbool);
  1316			break;
  1317	
  1318		case SO_RXQ_OVFL:
  1319			sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
  1320			break;
  1321	
  1322		case SO_WIFI_STATUS:
  1323			sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
  1324			break;
  1325	
  1326		case SO_PEEK_OFF:
  1327			if (sock->ops->set_peek_off)
  1328				ret = sock->ops->set_peek_off(sk, val);
  1329			else
  1330				ret = -EOPNOTSUPP;
  1331			break;
  1332	
  1333		case SO_NOFCS:
  1334			sock_valbool_flag(sk, SOCK_NOFCS, valbool);
  1335			break;
  1336	
  1337		case SO_SELECT_ERR_QUEUE:
  1338			sock_valbool_flag(sk, SOCK_SELECT_ERR_QUEUE, valbool);
  1339			break;
  1340	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply

* [PATCH net-next v2] net: Add SO_RCVMARK socket option to provide SO_MARK with recvmsg().
From: Erin MacNeil @ 2022-04-27  3:21 UTC (permalink / raw)
  To: lnx.erin
  Cc: Richard Henderson, Ivan Kokshaysky, Matt Turner,
	Thomas Bogendoerfer, James E.J. Bottomley, Helge Deller,
	David S. Miller, Jakub Kicinski, Paolo Abeni, Arnd Bergmann,
	Marcel Holtmann, Johan Hedberg, Luiz Augusto von Dentz,
	Oliver Hartkopp, Marc Kleine-Budde, Robin van der Gracht,
	Oleksij Rempel, kernel, Alexander Aring, Stefan Schmidt,
	Hideaki YOSHIFUJI, David Ahern, Steffen Klassert, Herbert Xu,
	Jeremy Kerr, Matt Johnston, Vlad Yasevich, Neil Horman,
	Marcelo Ricardo Leitner, Eric Dumazet, Akhmat Karakotov,
	Stephen Rothwell, Martynas Pumputis, Pavel Tikhomirov,
	Lorenz Bauer, Wei Wang, Yangbo Lu, Florian Westphal,
	Thomas Gleixner, Richard Palethorpe, Hangbin Liu,
	Willem de Bruijn, Pablo Neira Ayuso, Richard Sanger, Yajun Deng,
	Jiapeng Chong, linux-alpha, linux-kernel, linux-mips,
	linux-parisc, sparclinux, netdev, linux-arch, linux-bluetooth,
	linux-can, linux-wpan, linux-sctp
In-Reply-To: <202204270907.nUUrw3dS-lkp@intel.com>

Adding a new socket option, SO_RCVMARK, to indicate that SO_MARK
should be included in the ancillary data returned by recvmsg().

Renamed the sock_recv_ts_and_drops() function to sock_recv_cmsgs().

Signed-off-by: Erin MacNeil <lnx.erin@gmail.com>
---
 arch/alpha/include/uapi/asm/socket.h    |  2 ++
 arch/mips/include/uapi/asm/socket.h     |  2 ++
 arch/parisc/include/uapi/asm/socket.h   |  2 ++
 arch/sparc/include/uapi/asm/socket.h    |  2 ++
 include/net/sock.h                      | 18 ++++++++++--------
 include/uapi/asm-generic/socket.h       |  2 ++
 net/atm/common.c                        |  2 +-
 net/bluetooth/af_bluetooth.c            |  4 ++--
 net/can/bcm.c                           |  2 +-
 net/can/j1939/socket.c                  |  2 +-
 net/can/raw.c                           |  2 +-
 net/core/sock.c                         |  7 +++++++
 net/ieee802154/socket.c                 |  4 ++--
 net/ipv4/raw.c                          |  2 +-
 net/ipv4/udp.c                          |  2 +-
 net/ipv6/raw.c                          |  2 +-
 net/ipv6/udp.c                          |  2 +-
 net/key/af_key.c                        |  2 +-
 net/mctp/af_mctp.c                      |  2 +-
 net/packet/af_packet.c                  |  2 +-
 net/sctp/socket.c                       |  2 +-
 net/socket.c                            | 15 ++++++++++++---
 tools/include/uapi/asm-generic/socket.h |  2 ++
 23 files changed, 57 insertions(+), 27 deletions(-)

diff --git a/arch/alpha/include/uapi/asm/socket.h b/arch/alpha/include/uapi/asm/socket.h
index 7d81535893af..739891b94136 100644
--- a/arch/alpha/include/uapi/asm/socket.h
+++ b/arch/alpha/include/uapi/asm/socket.h
@@ -135,6 +135,8 @@
 
 #define SO_TXREHASH		74
 
+#define SO_RCVMARK		75
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/arch/mips/include/uapi/asm/socket.h b/arch/mips/include/uapi/asm/socket.h
index 1d55e57b8466..18f3d95ecfec 100644
--- a/arch/mips/include/uapi/asm/socket.h
+++ b/arch/mips/include/uapi/asm/socket.h
@@ -146,6 +146,8 @@
 
 #define SO_TXREHASH		74
 
+#define SO_RCVMARK		75
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h
index 654061e0964e..f486d3dfb6bb 100644
--- a/arch/parisc/include/uapi/asm/socket.h
+++ b/arch/parisc/include/uapi/asm/socket.h
@@ -127,6 +127,8 @@
 
 #define SO_TXREHASH		0x4048
 
+#define SO_RCVMARK		0x4049
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64
diff --git a/arch/sparc/include/uapi/asm/socket.h b/arch/sparc/include/uapi/asm/socket.h
index 666f81e617ea..ff08038fc2b2 100644
--- a/arch/sparc/include/uapi/asm/socket.h
+++ b/arch/sparc/include/uapi/asm/socket.h
@@ -128,6 +128,8 @@
 
 #define SO_TXREHASH              0x0053
 
+#define SO_RCVMARK               0x0054
+
 
 #if !defined(__KERNEL__)
 
diff --git a/include/net/sock.h b/include/net/sock.h
index a01d6c421aa2..30e7cbad194c 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -895,6 +895,7 @@ enum sock_flags {
 	SOCK_TXTIME,
 	SOCK_XDP, /* XDP is attached */
 	SOCK_TSTAMP_NEW, /* Indicates 64 bit timestamps always */
+	SOCK_RCVMARK, /* Receive SO_MARK  ancillary data with packet */
 };
 
 #define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
@@ -2649,20 +2650,21 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
 		__sock_recv_wifi_status(msg, sk, skb);
 }
 
-void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
-			      struct sk_buff *skb);
+void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
+		       struct sk_buff *skb);
 
 #define SK_DEFAULT_STAMP (-1L * NSEC_PER_SEC)
-static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
-					  struct sk_buff *skb)
+static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
+				   struct sk_buff *skb)
 {
-#define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL)			| \
-			   (1UL << SOCK_RCVTSTAMP))
+#define FLAGS_RECV_CMSGS ((1UL << SOCK_RXQ_OVFL)			| \
+			   (1UL << SOCK_RCVTSTAMP)			| \
+			   (1UL << SOCK_RCVMARK))
 #define TSFLAGS_ANY	  (SOF_TIMESTAMPING_SOFTWARE			| \
 			   SOF_TIMESTAMPING_RAW_HARDWARE)
 
-	if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY)
-		__sock_recv_ts_and_drops(msg, sk, skb);
+	if (sk->sk_flags & FLAGS_RECV_CMSGS || sk->sk_tsflags & TSFLAGS_ANY)
+		__sock_recv_cmsgs(msg, sk, skb);
 	else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP)))
 		sock_write_timestamp(sk, skb->tstamp);
 	else if (unlikely(sk->sk_stamp == SK_DEFAULT_STAMP))
diff --git a/include/uapi/asm-generic/socket.h b/include/uapi/asm-generic/socket.h
index 467ca2f28760..638230899e98 100644
--- a/include/uapi/asm-generic/socket.h
+++ b/include/uapi/asm-generic/socket.h
@@ -130,6 +130,8 @@
 
 #define SO_TXREHASH		74
 
+#define SO_RCVMARK		75
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
diff --git a/net/atm/common.c b/net/atm/common.c
index d0c8ab7ff8f6..f7019df41c3e 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -553,7 +553,7 @@ int vcc_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 	error = skb_copy_datagram_msg(skb, 0, msg, copied);
 	if (error)
 		return error;
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	if (!(flags & MSG_PEEK)) {
 		pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc),
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 62705734343b..b506409bb498 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -280,7 +280,7 @@ int bt_sock_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	skb_reset_transport_header(skb);
 	err = skb_copy_datagram_msg(skb, 0, msg, copied);
 	if (err == 0) {
-		sock_recv_ts_and_drops(msg, sk, skb);
+		sock_recv_cmsgs(msg, sk, skb);
 
 		if (msg->msg_name && bt_sk(sk)->skb_msg_name)
 			bt_sk(sk)->skb_msg_name(skb, msg->msg_name,
@@ -384,7 +384,7 @@ int bt_sock_stream_recvmsg(struct socket *sock, struct msghdr *msg,
 		copied += chunk;
 		size   -= chunk;
 
-		sock_recv_ts_and_drops(msg, sk, skb);
+		sock_recv_cmsgs(msg, sk, skb);
 
 		if (!(flags & MSG_PEEK)) {
 			int skb_len = skb_headlen(skb);
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 64c07e650bb4..65ee1b784a30 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1647,7 +1647,7 @@ static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 		return err;
 	}
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	if (msg->msg_name) {
 		__sockaddr_check_size(BCM_MIN_NAMELEN);
diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c
index 0bb4fd3f6264..f5ecfdcf57b2 100644
--- a/net/can/j1939/socket.c
+++ b/net/can/j1939/socket.c
@@ -841,7 +841,7 @@ static int j1939_sk_recvmsg(struct socket *sock, struct msghdr *msg,
 		paddr->can_addr.j1939.pgn = skcb->addr.pgn;
 	}
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 	msg->msg_flags |= skcb->msg_flags;
 	skb_free_datagram(sk, skb);
 
diff --git a/net/can/raw.c b/net/can/raw.c
index 0cf728dcff36..b7dbb57557f3 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -866,7 +866,7 @@ static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
 		return err;
 	}
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	if (msg->msg_name) {
 		__sockaddr_check_size(RAW_MIN_NAMELEN);
diff --git a/net/core/sock.c b/net/core/sock.c
index 29abec3eabd8..673b6e49f109 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1311,6 +1311,9 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 
 		__sock_set_mark(sk, val);
 		break;
+	case SO_RCVMARK:
+		sock_valbool_flag(sk, SOCK_RCVMARK, valbool);
+		break;
 
 	case SO_RXQ_OVFL:
 		sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
@@ -1737,6 +1740,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
 		v.val = sk->sk_mark;
 		break;
 
+	case SO_RCVMARK:
+		v.val = sock_flag(sk, SOCK_RCVMARK);
+		break;
+
 	case SO_RXQ_OVFL:
 		v.val = sock_flag(sk, SOCK_RXQ_OVFL);
 		break;
diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index f24852814fa3..718fb77bb372 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -328,7 +328,7 @@ static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	if (err)
 		goto done;
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	if (flags & MSG_TRUNC)
 		copied = skb->len;
@@ -718,7 +718,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	if (err)
 		goto done;
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	if (saddr) {
 		/* Clear the implicit padding in struct sockaddr_ieee802154
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 4056b0da85ea..bbd717805b10 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -783,7 +783,7 @@ static int raw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	if (err)
 		goto done;
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	/* Copy the address. */
 	if (sin) {
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index aa8545ca6964..9d5071c79c95 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1909,7 +1909,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags,
 		UDP_INC_STATS(sock_net(sk),
 			      UDP_MIB_INDATAGRAMS, is_udplite);
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	/* Copy the address. */
 	if (sin) {
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 0d7c13d33d1a..3b7cbd522b54 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -512,7 +512,7 @@ static int rawv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		*addr_len = sizeof(*sin6);
 	}
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	if (np->rxopt.all)
 		ip6_datagram_recv_ctl(sk, msg, skb);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 688af6f809fe..3fc97d4621ac 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -391,7 +391,7 @@ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	if (!peeking)
 		SNMP_INC_STATS(mib, UDP_MIB_INDATAGRAMS);
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	/* Copy the address. */
 	if (msg->msg_name) {
diff --git a/net/key/af_key.c b/net/key/af_key.c
index d09ec26b1081..175a162eec58 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3711,7 +3711,7 @@ static int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	if (err)
 		goto out_free;
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	err = (flags & MSG_TRUNC) ? skb->len : copied;
 
diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c
index 221863afc4b1..c2fc2a7b2528 100644
--- a/net/mctp/af_mctp.c
+++ b/net/mctp/af_mctp.c
@@ -238,7 +238,7 @@ static int mctp_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	if (rc < 0)
 		goto out_free;
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	if (addr) {
 		struct mctp_skb_cb *cb = mctp_cb(skb);
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index fd31334cf688..677f9cfa9660 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3477,7 +3477,7 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 		sll->sll_protocol = skb->protocol;
 	}
 
-	sock_recv_ts_and_drops(msg, sk, skb);
+	sock_recv_cmsgs(msg, sk, skb);
 
 	if (msg->msg_name) {
 		const size_t max_len = min(sizeof(skb->cb),
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 3e3fe923bed5..6d37d2dfb3da 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2128,7 +2128,7 @@ static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		head_skb = event->chunk->head_skb;
 	else
 		head_skb = skb;
-	sock_recv_ts_and_drops(msg, sk, head_skb);
+	sock_recv_cmsgs(msg, sk, head_skb);
 	if (sctp_ulpevent_is_notification(event)) {
 		msg->msg_flags |= MSG_NOTIFICATION;
 		sp->pf->event_msgname(event, msg->msg_name, addr_len);
diff --git a/net/socket.c b/net/socket.c
index 6887840682bb..f0c39c874665 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -930,13 +930,22 @@ static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
 			sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount);
 }
 
-void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk,
-	struct sk_buff *skb)
+static void sock_recv_mark(struct msghdr *msg, struct sock *sk,
+			   struct sk_buff *skb)
+{
+	if (sock_flag(sk, SOCK_RCVMARK) && skb)
+		put_cmsg(msg, SOL_SOCKET, SO_MARK, sizeof(__u32),
+			 &skb->mark);
+}
+
+void __sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,
+		       struct sk_buff *skb)
 {
 	sock_recv_timestamp(msg, sk, skb);
 	sock_recv_drops(msg, sk, skb);
+	sock_recv_mark(msg, sk, skb);
 }
-EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops);
+EXPORT_SYMBOL_GPL(__sock_recv_cmsgs);
 
 INDIRECT_CALLABLE_DECLARE(int inet_recvmsg(struct socket *, struct msghdr *,
 					   size_t, int));
diff --git a/tools/include/uapi/asm-generic/socket.h b/tools/include/uapi/asm-generic/socket.h
index 77f7c1638eb1..8756df13be50 100644
--- a/tools/include/uapi/asm-generic/socket.h
+++ b/tools/include/uapi/asm-generic/socket.h
@@ -119,6 +119,8 @@
 
 #define SO_DETACH_REUSEPORT_BPF 68
 
+#define SO_RCVMARK		75
+
 #if !defined(__KERNEL__)
 
 #if __BITS_PER_LONG == 64 || (defined(__x86_64__) && defined(__ILP32__))
-- 
2.20.1


^ permalink raw reply related

* Re: [PATCH net 1/2] ptp: ptp_clockmatrix: Add PTP_CLK_REQ_EXTTS support
From: kernel test robot @ 2022-04-27  2:44 UTC (permalink / raw)
  To: Min Li, richardcochran, lee.jones
  Cc: kbuild-all, linux-kernel, netdev, Min Li
In-Reply-To: <1651001574-32457-1-git-send-email-min.li.xe@renesas.com>

Hi Min,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Min-Li/ptp-ptp_clockmatrix-Add-PTP_CLK_REQ_EXTTS-support/20220427-033506
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net.git acb16b395c3f3d7502443e0c799c2b42df645642
config: i386-randconfig-a012-20220425 (https://download.01.org/0day-ci/archive/20220427/202204271014.NroTeynI-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/afadc4edd1bf64b40cb61b38dedf67354baeb147
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Min-Li/ptp-ptp_clockmatrix-Add-PTP_CLK_REQ_EXTTS-support/20220427-033506
        git checkout afadc4edd1bf64b40cb61b38dedf67354baeb147
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=i386 SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: drivers/ptp/ptp_clockmatrix.o: in function `idtcm_get_dco_delay':
>> drivers/ptp/ptp_clockmatrix.c:2222: undefined reference to `__udivdi3'
>> ld: drivers/ptp/ptp_clockmatrix.c:2225: undefined reference to `__udivdi3'


vim +2222 drivers/ptp/ptp_clockmatrix.c

  2191	
  2192	/*
  2193	 * Compensate for the PTP DCO input-to-output delay.
  2194	 * This delay is 18 FOD cycles.
  2195	 */
  2196	static u32 idtcm_get_dco_delay(struct idtcm_channel *channel)
  2197	{
  2198		struct idtcm *idtcm = channel->idtcm;
  2199		u8 mbuf[8] = {0};
  2200		u8 nbuf[2] = {0};
  2201		u32 fodFreq;
  2202		int err;
  2203		u64 m;
  2204		u16 n;
  2205	
  2206		err = idtcm_read(idtcm, channel->dpll_ctrl_n,
  2207				 DPLL_CTRL_DPLL_FOD_FREQ, mbuf, 6);
  2208		if (err)
  2209			return 0;
  2210	
  2211		err = idtcm_read(idtcm, channel->dpll_ctrl_n,
  2212				 DPLL_CTRL_DPLL_FOD_FREQ + 6, nbuf, 2);
  2213		if (err)
  2214			return 0;
  2215	
  2216		m = get_unaligned_le64(mbuf);
  2217		n = get_unaligned_le16(nbuf);
  2218	
  2219		if (n == 0)
  2220			n = 1;
  2221	
> 2222		fodFreq = m / n;
  2223	
  2224		if (fodFreq >= 500000000)
> 2225			return 18 * (u64)NSEC_PER_SEC / fodFreq;
  2226	
  2227		return 0;
  2228	}
  2229	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply

* Re: [PATCH net-next] net: Add SO_RCVMARK socket option to provide SO_MARK with recvmsg().
From: kernel test robot @ 2022-04-27  1:43 UTC (permalink / raw)
  To: Erin MacNeil, netdev; +Cc: kbuild-all, Erin MacNeil
In-Reply-To: <20220426173805.2652-1-lnx.erin@gmail.com>

Hi Erin,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on net-next/master]

url:    https://github.com/intel-lab-lkp/linux/commits/Erin-MacNeil/net-Add-SO_RCVMARK-socket-option-to-provide-SO_MARK-with-recvmsg/20220427-014257
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 561215482cc69d1c758944d4463b3d5d96d37bd1
config: alpha-defconfig (https://download.01.org/0day-ci/archive/20220427/202204270907.nUUrw3dS-lkp@intel.com/config)
compiler: alpha-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/ba0c57c49e3f18b23fe626dd2e603cf4ed91ebf7
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Erin-MacNeil/net-Add-SO_RCVMARK-socket-option-to-provide-SO_MARK-with-recvmsg/20220427-014257
        git checkout ba0c57c49e3f18b23fe626dd2e603cf4ed91ebf7
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=alpha SHELL=/bin/bash

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   net/core/sock.c: In function 'sock_setsockopt':
>> net/core/sock.c:1314:14: error: 'SO_RCVMARK' undeclared (first use in this function); did you mean 'SOCK_RCVMARK'?
    1314 |         case SO_RCVMARK:
         |              ^~~~~~~~~~
         |              SOCK_RCVMARK
   net/core/sock.c:1314:14: note: each undeclared identifier is reported only once for each function it appears in
   net/core/sock.c: In function 'sock_getsockopt':
   net/core/sock.c:1743:14: error: 'SO_RCVMARK' undeclared (first use in this function); did you mean 'SOCK_RCVMARK'?
    1743 |         case SO_RCVMARK:
         |              ^~~~~~~~~~
         |              SOCK_RCVMARK


vim +1314 net/core/sock.c

  1031	
  1032	/*
  1033	 *	This is meant for all protocols to use and covers goings on
  1034	 *	at the socket level. Everything here is generic.
  1035	 */
  1036	
  1037	int sock_setsockopt(struct socket *sock, int level, int optname,
  1038			    sockptr_t optval, unsigned int optlen)
  1039	{
  1040		struct so_timestamping timestamping;
  1041		struct sock_txtime sk_txtime;
  1042		struct sock *sk = sock->sk;
  1043		int val;
  1044		int valbool;
  1045		struct linger ling;
  1046		int ret = 0;
  1047	
  1048		/*
  1049		 *	Options without arguments
  1050		 */
  1051	
  1052		if (optname == SO_BINDTODEVICE)
  1053			return sock_setbindtodevice(sk, optval, optlen);
  1054	
  1055		if (optlen < sizeof(int))
  1056			return -EINVAL;
  1057	
  1058		if (copy_from_sockptr(&val, optval, sizeof(val)))
  1059			return -EFAULT;
  1060	
  1061		valbool = val ? 1 : 0;
  1062	
  1063		lock_sock(sk);
  1064	
  1065		switch (optname) {
  1066		case SO_DEBUG:
  1067			if (val && !capable(CAP_NET_ADMIN))
  1068				ret = -EACCES;
  1069			else
  1070				sock_valbool_flag(sk, SOCK_DBG, valbool);
  1071			break;
  1072		case SO_REUSEADDR:
  1073			sk->sk_reuse = (valbool ? SK_CAN_REUSE : SK_NO_REUSE);
  1074			break;
  1075		case SO_REUSEPORT:
  1076			sk->sk_reuseport = valbool;
  1077			break;
  1078		case SO_TYPE:
  1079		case SO_PROTOCOL:
  1080		case SO_DOMAIN:
  1081		case SO_ERROR:
  1082			ret = -ENOPROTOOPT;
  1083			break;
  1084		case SO_DONTROUTE:
  1085			sock_valbool_flag(sk, SOCK_LOCALROUTE, valbool);
  1086			sk_dst_reset(sk);
  1087			break;
  1088		case SO_BROADCAST:
  1089			sock_valbool_flag(sk, SOCK_BROADCAST, valbool);
  1090			break;
  1091		case SO_SNDBUF:
  1092			/* Don't error on this BSD doesn't and if you think
  1093			 * about it this is right. Otherwise apps have to
  1094			 * play 'guess the biggest size' games. RCVBUF/SNDBUF
  1095			 * are treated in BSD as hints
  1096			 */
  1097			val = min_t(u32, val, sysctl_wmem_max);
  1098	set_sndbuf:
  1099			/* Ensure val * 2 fits into an int, to prevent max_t()
  1100			 * from treating it as a negative value.
  1101			 */
  1102			val = min_t(int, val, INT_MAX / 2);
  1103			sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
  1104			WRITE_ONCE(sk->sk_sndbuf,
  1105				   max_t(int, val * 2, SOCK_MIN_SNDBUF));
  1106			/* Wake up sending tasks if we upped the value. */
  1107			sk->sk_write_space(sk);
  1108			break;
  1109	
  1110		case SO_SNDBUFFORCE:
  1111			if (!capable(CAP_NET_ADMIN)) {
  1112				ret = -EPERM;
  1113				break;
  1114			}
  1115	
  1116			/* No negative values (to prevent underflow, as val will be
  1117			 * multiplied by 2).
  1118			 */
  1119			if (val < 0)
  1120				val = 0;
  1121			goto set_sndbuf;
  1122	
  1123		case SO_RCVBUF:
  1124			/* Don't error on this BSD doesn't and if you think
  1125			 * about it this is right. Otherwise apps have to
  1126			 * play 'guess the biggest size' games. RCVBUF/SNDBUF
  1127			 * are treated in BSD as hints
  1128			 */
  1129			__sock_set_rcvbuf(sk, min_t(u32, val, sysctl_rmem_max));
  1130			break;
  1131	
  1132		case SO_RCVBUFFORCE:
  1133			if (!capable(CAP_NET_ADMIN)) {
  1134				ret = -EPERM;
  1135				break;
  1136			}
  1137	
  1138			/* No negative values (to prevent underflow, as val will be
  1139			 * multiplied by 2).
  1140			 */
  1141			__sock_set_rcvbuf(sk, max(val, 0));
  1142			break;
  1143	
  1144		case SO_KEEPALIVE:
  1145			if (sk->sk_prot->keepalive)
  1146				sk->sk_prot->keepalive(sk, valbool);
  1147			sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
  1148			break;
  1149	
  1150		case SO_OOBINLINE:
  1151			sock_valbool_flag(sk, SOCK_URGINLINE, valbool);
  1152			break;
  1153	
  1154		case SO_NO_CHECK:
  1155			sk->sk_no_check_tx = valbool;
  1156			break;
  1157	
  1158		case SO_PRIORITY:
  1159			if ((val >= 0 && val <= 6) ||
  1160			    ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) ||
  1161			    ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
  1162				sk->sk_priority = val;
  1163			else
  1164				ret = -EPERM;
  1165			break;
  1166	
  1167		case SO_LINGER:
  1168			if (optlen < sizeof(ling)) {
  1169				ret = -EINVAL;	/* 1003.1g */
  1170				break;
  1171			}
  1172			if (copy_from_sockptr(&ling, optval, sizeof(ling))) {
  1173				ret = -EFAULT;
  1174				break;
  1175			}
  1176			if (!ling.l_onoff)
  1177				sock_reset_flag(sk, SOCK_LINGER);
  1178			else {
  1179	#if (BITS_PER_LONG == 32)
  1180				if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
  1181					sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;
  1182				else
  1183	#endif
  1184					sk->sk_lingertime = (unsigned int)ling.l_linger * HZ;
  1185				sock_set_flag(sk, SOCK_LINGER);
  1186			}
  1187			break;
  1188	
  1189		case SO_BSDCOMPAT:
  1190			break;
  1191	
  1192		case SO_PASSCRED:
  1193			if (valbool)
  1194				set_bit(SOCK_PASSCRED, &sock->flags);
  1195			else
  1196				clear_bit(SOCK_PASSCRED, &sock->flags);
  1197			break;
  1198	
  1199		case SO_TIMESTAMP_OLD:
  1200		case SO_TIMESTAMP_NEW:
  1201		case SO_TIMESTAMPNS_OLD:
  1202		case SO_TIMESTAMPNS_NEW:
  1203			sock_set_timestamp(sk, optname, valbool);
  1204			break;
  1205	
  1206		case SO_TIMESTAMPING_NEW:
  1207		case SO_TIMESTAMPING_OLD:
  1208			if (optlen == sizeof(timestamping)) {
  1209				if (copy_from_sockptr(&timestamping, optval,
  1210						      sizeof(timestamping))) {
  1211					ret = -EFAULT;
  1212					break;
  1213				}
  1214			} else {
  1215				memset(&timestamping, 0, sizeof(timestamping));
  1216				timestamping.flags = val;
  1217			}
  1218			ret = sock_set_timestamping(sk, optname, timestamping);
  1219			break;
  1220	
  1221		case SO_RCVLOWAT:
  1222			if (val < 0)
  1223				val = INT_MAX;
  1224			if (sock->ops->set_rcvlowat)
  1225				ret = sock->ops->set_rcvlowat(sk, val);
  1226			else
  1227				WRITE_ONCE(sk->sk_rcvlowat, val ? : 1);
  1228			break;
  1229	
  1230		case SO_RCVTIMEO_OLD:
  1231		case SO_RCVTIMEO_NEW:
  1232			ret = sock_set_timeout(&sk->sk_rcvtimeo, optval,
  1233					       optlen, optname == SO_RCVTIMEO_OLD);
  1234			break;
  1235	
  1236		case SO_SNDTIMEO_OLD:
  1237		case SO_SNDTIMEO_NEW:
  1238			ret = sock_set_timeout(&sk->sk_sndtimeo, optval,
  1239					       optlen, optname == SO_SNDTIMEO_OLD);
  1240			break;
  1241	
  1242		case SO_ATTACH_FILTER: {
  1243			struct sock_fprog fprog;
  1244	
  1245			ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
  1246			if (!ret)
  1247				ret = sk_attach_filter(&fprog, sk);
  1248			break;
  1249		}
  1250		case SO_ATTACH_BPF:
  1251			ret = -EINVAL;
  1252			if (optlen == sizeof(u32)) {
  1253				u32 ufd;
  1254	
  1255				ret = -EFAULT;
  1256				if (copy_from_sockptr(&ufd, optval, sizeof(ufd)))
  1257					break;
  1258	
  1259				ret = sk_attach_bpf(ufd, sk);
  1260			}
  1261			break;
  1262	
  1263		case SO_ATTACH_REUSEPORT_CBPF: {
  1264			struct sock_fprog fprog;
  1265	
  1266			ret = copy_bpf_fprog_from_user(&fprog, optval, optlen);
  1267			if (!ret)
  1268				ret = sk_reuseport_attach_filter(&fprog, sk);
  1269			break;
  1270		}
  1271		case SO_ATTACH_REUSEPORT_EBPF:
  1272			ret = -EINVAL;
  1273			if (optlen == sizeof(u32)) {
  1274				u32 ufd;
  1275	
  1276				ret = -EFAULT;
  1277				if (copy_from_sockptr(&ufd, optval, sizeof(ufd)))
  1278					break;
  1279	
  1280				ret = sk_reuseport_attach_bpf(ufd, sk);
  1281			}
  1282			break;
  1283	
  1284		case SO_DETACH_REUSEPORT_BPF:
  1285			ret = reuseport_detach_prog(sk);
  1286			break;
  1287	
  1288		case SO_DETACH_FILTER:
  1289			ret = sk_detach_filter(sk);
  1290			break;
  1291	
  1292		case SO_LOCK_FILTER:
  1293			if (sock_flag(sk, SOCK_FILTER_LOCKED) && !valbool)
  1294				ret = -EPERM;
  1295			else
  1296				sock_valbool_flag(sk, SOCK_FILTER_LOCKED, valbool);
  1297			break;
  1298	
  1299		case SO_PASSSEC:
  1300			if (valbool)
  1301				set_bit(SOCK_PASSSEC, &sock->flags);
  1302			else
  1303				clear_bit(SOCK_PASSSEC, &sock->flags);
  1304			break;
  1305		case SO_MARK:
  1306			if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) &&
  1307			    !ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
  1308				ret = -EPERM;
  1309				break;
  1310			}
  1311	
  1312			__sock_set_mark(sk, val);
  1313			break;
> 1314		case SO_RCVMARK:
  1315			sock_valbool_flag(sk, SOCK_RCVMARK, valbool);
  1316			break;
  1317	
  1318		case SO_RXQ_OVFL:
  1319			sock_valbool_flag(sk, SOCK_RXQ_OVFL, valbool);
  1320			break;
  1321	
  1322		case SO_WIFI_STATUS:
  1323			sock_valbool_flag(sk, SOCK_WIFI_STATUS, valbool);
  1324			break;
  1325	
  1326		case SO_PEEK_OFF:
  1327			if (sock->ops->set_peek_off)
  1328				ret = sock->ops->set_peek_off(sk, val);
  1329			else
  1330				ret = -EOPNOTSUPP;
  1331			break;
  1332	
  1333		case SO_NOFCS:
  1334			sock_valbool_flag(sk, SOCK_NOFCS, valbool);
  1335			break;
  1336	
  1337		case SO_SELECT_ERR_QUEUE:
  1338			sock_valbool_flag(sk, SOCK_SELECT_ERR_QUEUE, valbool);
  1339			break;
  1340	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply

* RE: [PATCH -next] rtw89: remove unneeded semicolon
From: Pkshih @ 2022-04-27  1:29 UTC (permalink / raw)
  To: Yang Li, davem@davemloft.net
  Cc: kuba@kernel.org, pabeni@redhat.com, kvalo@kernel.org,
	linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, Abaci Robot
In-Reply-To: <20220427003142.107916-1-yang.lee@linux.alibaba.com>



> -----Original Message-----
> From: Yang Li <yang.lee@linux.alibaba.com>
> Sent: Wednesday, April 27, 2022 8:32 AM
> To: davem@davemloft.net
> Cc: kuba@kernel.org; pabeni@redhat.com; kvalo@kernel.org; Pkshih <pkshih@realtek.com>;
> linux-wireless@vger.kernel.org; netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Yang Li
> <yang.lee@linux.alibaba.com>; Abaci Robot <abaci@linux.alibaba.com>
> Subject: [PATCH -next] rtw89: remove unneeded semicolon
> 
> Eliminate the following coccicheck warning:
> ./drivers/net/wireless/realtek/rtw89/rtw8852c.c:2556:2-3: Unneeded
> semicolon
> 
> Reported-by: Abaci Robot <abaci@linux.alibaba.com>
> Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>

Acked-by: Ping-Ke Shih <pkshih@realtek.com>

> ---
>  drivers/net/wireless/realtek/rtw89/rtw8852c.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> index 858611c64e6b..275568468212 100644
> --- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> +++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
> @@ -2553,7 +2553,7 @@ do {								\
>  	default:
>  		val = arg.gnt_bt.data;
>  		break;
> -	};
> +	}
> 
>  	__write_ctrl(R_AX_PWR_COEXT_CTRL, B_AX_TXAGC_BT_MASK, val,
>  		     B_AX_TXAGC_BT_EN, arg.ctrl_gnt_bt != 0xffff);
> --
> 2.20.1.7.g153144c


^ permalink raw reply

* Re: [PATCH net-next v6 04/13] net: wwan: t7xx: Add port proxy infrastructure
From: Sergey Ryazanov @ 2022-04-27  1:35 UTC (permalink / raw)
  To: Veleta, Moises
  Cc: Ricardo Martinez, netdev@vger.kernel.org,
	linux-wireless@vger.kernel.org, Jakub Kicinski, David Miller,
	Johannes Berg, Loic Poulain, Kumar, M Chetan,
	Devegowda, Chandrashekar, linuxwwan,
	chiranjeevi.rapolu@linux.intel.com, Liu, Haijun, Hanania, Amir,
	Andy Shevchenko, Sharma, Dinesh, Lee, Eliot,
	Jarvinen, Ilpo Johannes, Bossart, Pierre-louis,
	Sethuraman, Muralidharan, Mishra, Soumya Prakash,
	Kancharla, Sreehari, Sahu, Madhusmita
In-Reply-To: <MWHPR1101MB2319F7A27B51ECD998855494E0FA9@MWHPR1101MB2319.namprd11.prod.outlook.com>

On Wed, Apr 27, 2022 at 4:14 AM Veleta, Moises <moises.veleta@intel.com> wrote:
> From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
> Sent: Tuesday, April 26, 2022 4:06 PM
> To: Veleta, Moises <moises.veleta@intel.com>
> Cc: Ricardo Martinez <ricardo.martinez@linux.intel.com>; netdev@vger.kernel.org <netdev@vger.kernel.org>; linux-wireless@vger.kernel.org <linux-wireless@vger.kernel.org>; Jakub Kicinski <kuba@kernel.org>; David Miller <davem@davemloft.net>; Johannes Berg <johannes@sipsolutions.net>; Loic Poulain <loic.poulain@linaro.org>; Kumar, M Chetan <m.chetan.kumar@intel.com>; Devegowda, Chandrashekar <chandrashekar.devegowda@intel.com>; linuxwwan <linuxwwan@intel.com>; chiranjeevi.rapolu@linux.intel.com <chiranjeevi.rapolu@linux.intel.com>; Liu, Haijun <haijun.liu@mediatek.com>; Hanania, Amir <amir.hanania@intel.com>; Andy Shevchenko <andriy.shevchenko@linux.intel.com>; Sharma, Dinesh <dinesh.sharma@intel.com>; Lee, Eliot <eliot.lee@intel.com>; Jarvinen, Ilpo Johannes <ilpo.johannes.jarvinen@intel.com>; Bossart, Pierre-louis <pierre-louis.bossart@intel.com>; Sethuraman, Muralidharan <muralidharan.sethuraman@intel.com>; Mishra, Soumya Prakash <soumya.prakash.mishra@intel.com>; Kancharla, Sreehari <sreehari.kancharla@intel.com>; Sahu, Madhusmita <madhusmita.sahu@intel.com>
> Subject: Re: [PATCH net-next v6 04/13] net: wwan: t7xx: Add port proxy infrastructure
>
> Hello Moises,
>
> On Tue, Apr 26, 2022 at 10:46 PM Veleta, Moises <moises.veleta@intel.com> wrote:
>> From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
>> Sent: Monday, April 25, 2022 4:53 PM
>> To: Ricardo Martinez <ricardo.martinez@linux.intel.com>
>> Cc: netdev@vger.kernel.org <netdev@vger.kernel.org>; linux-wireless@vger.kernel.org <linux-wireless@vger.kernel.org>; Jakub Kicinski <kuba@kernel.org>; David Miller <davem@davemloft.net>; Johannes Berg <johannes@sipsolutions.net>; Loic Poulain <loic.poulain@linaro.org>; Kumar, M Chetan <m.chetan.kumar@intel.com>; Devegowda, Chandrashekar <chandrashekar.devegowda@intel.com>; linuxwwan <linuxwwan@intel.com>; chiranjeevi.rapolu@linux.intel.com <chiranjeevi.rapolu@linux.intel.com>; Liu, Haijun <haijun.liu@mediatek.com>; Hanania, Amir <amir.hanania@intel.com>; Andy Shevchenko <andriy.shevchenko@linux.intel.com>; Sharma, Dinesh <dinesh.sharma@intel.com>; Lee, Eliot <eliot.lee@intel.com>; Jarvinen, Ilpo Johannes <ilpo.johannes.jarvinen@intel.com>; Veleta, Moises <moises.veleta@intel.com>; Bossart, Pierre-louis <pierre-louis.bossart@intel.com>; Sethuraman, Muralidharan <muralidharan.sethuraman@intel.com>; Mishra, Soumya Prakash <soumya.prakash.mishra@intel.com>; Kancharla, Sreehari <sreehari.kancharla@intel.com>; Sahu, Madhusmita <madhusmita.sahu@intel.com>
>> Subject: Re: [PATCH net-next v6 04/13] net: wwan: t7xx: Add port proxy infrastructure
>>
>> On Fri, Apr 8, 2022 at 1:37 AM Ricardo Martinez
>> <ricardo.martinez@linux.intel.com> wrote:
>>> Port-proxy provides a common interface to interact with different types
>>> of ports. Ports export their configuration via `struct t7xx_port` and
>>> operate as defined by `struct port_ops`.
>>>
>>> Signed-off-by: Haijun Liu <haijun.liu@mediatek.com>
>>> Co-developed-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
>>> Signed-off-by: Chandrashekar Devegowda <chandrashekar.devegowda@intel.com>
>>> Co-developed-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
>>> Signed-off-by: Ricardo Martinez <ricardo.martinez@linux.intel.com>
>>>
>>> From a WWAN framework perspective:
>>> Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
>>
>> [skipped]
>>
>>> +int t7xx_port_enqueue_skb(struct t7xx_port *port, struct sk_buff *skb)
>>> +{
>>> +       unsigned long flags;
>>> +
>>> +       spin_lock_irqsave(&port->rx_wq.lock, flags);
>>> +       if (port->rx_skb_list.qlen >= port->rx_length_th) {
>>> +               spin_unlock_irqrestore(&port->rx_wq.lock, flags);
>>
>> Probably skb should be freed here before returning. The caller assumes
>> that skb will be consumed even in case of error.
>>
>> [MV] We do not drop port ctrl messages. We keep them and try again later.
>> Whereas WWAN skbs are dropped if conditions are met.
>
> I missed that the WWAN port returns no error when it drops the skb.
> And then I concluded that any failure to process the CCCI message
> should be accomplished with the skb freeing. Now the handling of CCCI
> messages is more clear to me. Thank you for the clarifications!
>
> To avoid similar misinterpretation in the future, I thought that the
> skb freeing in the WWAN port worth a comment. Something to describe
> that despite dropping the message, the return code is zero, indicating
> skb consumption. Similarly in this (t7xx_port_enqueue_skb) function.
> Something like: "return an error here, the caller will try again
> later". And maybe in t7xx_cldma_gpd_rx_from_q() near the loop break
> after the .skb_recv() failure test. Something like: "break message
> processing for now will try this message later".
>
> What do you think?
>
> Yes, that would remove the unintended obfuscation . Unless, you think this approach is inappropriate
> and should be refactored.  Otherwise, I will proceed with adding those clarifying comments.
> Thank you.

I am Ok with the current approach. It does not contain obvious errors.
It might look puzzled, but proper comments should solve this.

-- 
Sergey

^ permalink raw reply

* Re: [PATCH] net: dsa: mv88e6xxx: Single chip mode detection for MV88E6*41
From: Andrew Lunn @ 2022-04-27  1:30 UTC (permalink / raw)
  To: Nathan Rossi
  Cc: netdev, linux-kernel, Vivien Didelot, Florian Fainelli,
	Vladimir Oltean, David S. Miller, Jakub Kicinski, Paolo Abeni
In-Reply-To: <20220424125451.295435-1-nathan@nathanrossi.com>

On Sun, Apr 24, 2022 at 12:54:51PM +0000, Nathan Rossi wrote:
> The mv88e6xxx driver expects switches that are configured in single chip
> addressing mode to have the MDIO address configured as 0. This is due to
> the switch ADDR pins representing the single chip addressing mode as 0.
> However depending on the device (e.g. MV88E6*41) the switch does not
> respond on address 0 or any other address below 16 (the first port
> address) in single chip addressing mode. This allows for other devices
> to be on the same shared MDIO bus despite the switch being in single
> chip addressing mode.
> 
> When using a switch that works this way it is not possible to configure
> switch driver as single chip addressing via device tree, along with
> another MDIO device on the same bus with address 0, as both devices
> would have the same address of 0 resulting in mdiobus_register_device
> -EBUSY errors for one of the devices with address 0.
> 
> In order to support this configuration the switch node can have its MDIO
> address configured as 16 (the first address that the device responds
> to). During initialization the driver will treat this address similar to
> how address 0 is, however because this address is also a valid
> multi-chip address (in certain switch models, but not all) the driver
> will configure the SMI in single chip addressing mode and attempt to
> detect the switch model. If the device is configured in single chip
> addressing mode this will succeed and the initialization process can
> continue. If it fails to detect a valid model this is because the switch
> model register is not a valid register when in multi-chip mode, it will
> then fall back to the existing SMI initialization process using the MDIO
> address as the multi-chip mode address.
> 
> This detection method is safe if the device is in either mode because
> the single chip addressing mode read is a direct SMI/MDIO read operation
> and has no side effects compared to the SMI writes required for the
> multi-chip addressing mode.

Thanks for rewording the commit message. This makes it a lot clearer
what is going on and how it is fixed.

> @@ -6971,9 +6993,18 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
>  	if (chip->reset)
>  		usleep_range(1000, 2000);
>  
> -	err = mv88e6xxx_detect(chip);
> -	if (err)
> -		goto out;
> +	/* Detect if the device is configured in single chip addressing mode,
> +	 * otherwise continue with address specific smi init/detection.
> +	 */
> +	if (mv88e6xxx_single_chip_detect(chip, mdiodev)) {
> +		err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
> +		if (err)
> +			goto out;
> +

This is confusing. Then name mv88e6xxx_single_chip_detect() suggests
it will return true if it detects a single chip device. When it fact
is return 0 == False if it does find such a device.

So i think this would be better coded as

	err = mv88e6xxx_single_chip_detect(chip, mdiodev);
	if (err) {
		err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
		if (err)
			goto out;

I did however test this code on my 370rd, and it does work. So once we
get this sorted out, it is good to go.

	Andrew			

^ permalink raw reply

* [PATCH net v4] nfc: nfcmrvl: main: reorder destructive operations in nfcmrvl_nci_unregister_dev to avoid bugs
From: Duoming Zhou @ 2022-04-27  1:14 UTC (permalink / raw)
  To: krzysztof.kozlowski, pabeni, linux-kernel
  Cc: davem, gregkh, alexander.deucher, akpm, broonie, netdev, kuba,
	linma, Duoming Zhou

There are destructive operations such as nfcmrvl_fw_dnld_abort and
gpio_free in nfcmrvl_nci_unregister_dev. The resources such as firmware,
gpio and so on could be destructed while the upper layer functions such as
nfcmrvl_fw_dnld_start and nfcmrvl_nci_recv_frame is executing, which leads
to double-free, use-after-free and null-ptr-deref bugs.

There are three situations that could lead to double-free bugs.

The first situation is shown below:

   (Thread 1)                 |      (Thread 2)
nfcmrvl_fw_dnld_start         |
 ...                          |  nfcmrvl_nci_unregister_dev
 release_firmware()           |   nfcmrvl_fw_dnld_abort
  kfree(fw) //(1)             |    fw_dnld_over
                              |     release_firmware
  ...                         |      kfree(fw) //(2)
                              |     ...

The second situation is shown below:

   (Thread 1)                 |      (Thread 2)
nfcmrvl_fw_dnld_start         |
 ...                          |
 mod_timer                    |
 (wait a time)                |
 fw_dnld_timeout              |  nfcmrvl_nci_unregister_dev
   fw_dnld_over               |   nfcmrvl_fw_dnld_abort
    release_firmware          |    fw_dnld_over
     kfree(fw) //(1)          |     release_firmware
     ...                      |      kfree(fw) //(2)

The third situation is shown below:

       (Thread 1)               |       (Thread 2)
nfcmrvl_nci_recv_frame          |
 if(..->fw_download_in_progress)|
  nfcmrvl_fw_dnld_recv_frame    |
   queue_work                   |
                                |
fw_dnld_rx_work                 | nfcmrvl_nci_unregister_dev
 fw_dnld_over                   |  nfcmrvl_fw_dnld_abort
  release_firmware              |   fw_dnld_over
   kfree(fw) //(1)              |    release_firmware
                                |     kfree(fw) //(2)

The firmware struct is deallocated in position (1) and deallocated
in position (2) again.

The crash trace triggered by POC is like below:

[  122.640457] BUG: KASAN: double-free or invalid-free in fw_dnld_over+0x28/0xf0
[  122.640457] Call Trace:
[  122.640457]  <TASK>
[  122.640457]  kfree+0xb0/0x330
[  122.640457]  fw_dnld_over+0x28/0xf0
[  122.640457]  nfcmrvl_nci_unregister_dev+0x61/0x70
[  122.640457]  nci_uart_tty_close+0x87/0xd0
[  122.640457]  tty_ldisc_kill+0x3e/0x80
[  122.640457]  tty_ldisc_hangup+0x1b2/0x2c0
[  122.640457]  __tty_hangup.part.0+0x316/0x520
[  122.640457]  tty_release+0x200/0x670
[  122.640457]  __fput+0x110/0x410
[  122.640457]  task_work_run+0x86/0xd0
[  122.640457]  exit_to_user_mode_prepare+0x1aa/0x1b0
[  122.640457]  syscall_exit_to_user_mode+0x19/0x50
[  122.640457]  do_syscall_64+0x48/0x90
[  122.640457]  entry_SYSCALL_64_after_hwframe+0x44/0xae
[  122.640457] RIP: 0033:0x7f68433f6beb

What's more, there are also use-after-free and null-ptr-deref bugs
in nfcmrvl_fw_dnld_start. If we deallocate firmware struct, gpio or
set null to the members of priv->fw_dnld in nfcmrvl_nci_unregister_dev,
then, we dereference firmware, gpio or the members of priv->fw_dnld in
nfcmrvl_fw_dnld_start, the UAF or NPD bugs will happen.

This patch reorders destructive operations after nci_unregister_device
and adds bool variable protected by device_lock to synchronize between
cleanup routine and firmware download routine. The process is shown below.

       (Thread 1)               |       (Thread 2)
nfcmrvl_nci_unregister_dev      |
  nci_unregister_device         |
    nfc_unregister_device       | nfc_fw_download
      device_lock()             |
      ...                       |
      nfc_download = false;     |   ...
      device_unlock()           |
  ...                           |   device_lock()
  (destructive operations)      |   if(.. || !nfc_download)
                                |     goto error;
                                | error:
                                |   device_unlock()

If the device is detaching, the download function will goto error.
If the download function is executing, nci_unregister_device will
wait until download function is finished.

Fixes: 3194c6870158 ("NFC: nfcmrvl: add firmware download support")
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
---
Changes in v4:
  - Change bool variable nfc_download to static.

 drivers/nfc/nfcmrvl/main.c | 2 +-
 net/nfc/core.c             | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c
index 2fcf545012b..1a5284de434 100644
--- a/drivers/nfc/nfcmrvl/main.c
+++ b/drivers/nfc/nfcmrvl/main.c
@@ -183,6 +183,7 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
 {
 	struct nci_dev *ndev = priv->ndev;
 
+	nci_unregister_device(ndev);
 	if (priv->ndev->nfc_dev->fw_download_in_progress)
 		nfcmrvl_fw_dnld_abort(priv);
 
@@ -191,7 +192,6 @@ void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)
 	if (gpio_is_valid(priv->config.reset_n_io))
 		gpio_free(priv->config.reset_n_io);
 
-	nci_unregister_device(ndev);
 	nci_free_device(ndev);
 	kfree(priv);
 }
diff --git a/net/nfc/core.c b/net/nfc/core.c
index dc7a2404efd..1d91334ee86 100644
--- a/net/nfc/core.c
+++ b/net/nfc/core.c
@@ -25,6 +25,8 @@
 #define NFC_CHECK_PRES_FREQ_MS	2000
 
 int nfc_devlist_generation;
+/* nfc_download: used to judge whether nfc firmware download could start */
+static bool nfc_download;
 DEFINE_MUTEX(nfc_devlist_mutex);
 
 /* NFC device ID bitmap */
@@ -38,7 +40,7 @@ int nfc_fw_download(struct nfc_dev *dev, const char *firmware_name)
 
 	device_lock(&dev->dev);
 
-	if (!device_is_registered(&dev->dev)) {
+	if (!device_is_registered(&dev->dev) || !nfc_download) {
 		rc = -ENODEV;
 		goto error;
 	}
@@ -1134,6 +1136,7 @@ int nfc_register_device(struct nfc_dev *dev)
 			dev->rfkill = NULL;
 		}
 	}
+	nfc_download = true;
 	device_unlock(&dev->dev);
 
 	rc = nfc_genl_device_added(dev);
@@ -1166,6 +1169,7 @@ void nfc_unregister_device(struct nfc_dev *dev)
 		rfkill_unregister(dev->rfkill);
 		rfkill_destroy(dev->rfkill);
 	}
+	nfc_download = false;
 	device_unlock(&dev->dev);
 
 	if (dev->ops->check_presence) {
-- 
2.17.1


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox