Re: [PATCH v9 12/32] virtio_ring: packed: extract the logic of alloc queue

2022-04-12 Thread Xuan Zhuo
On Tue, 12 Apr 2022 14:28:24 +0800, Jason Wang  wrote:
>
> 在 2022/4/6 上午11:43, Xuan Zhuo 写道:
> > Separate the logic of packed to create vring queue.
> >
> > For the convenience of passing parameters, add a structure
> > vring_packed.
> >
> > This feature is required for subsequent virtuqueue reset vring.
> >
> > Signed-off-by: Xuan Zhuo 
> > ---
> >   drivers/virtio/virtio_ring.c | 70 
> >   1 file changed, 56 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
> > index 33864134a744..ea451ae2aaef 100644
> > --- a/drivers/virtio/virtio_ring.c
> > +++ b/drivers/virtio/virtio_ring.c
> > @@ -1817,19 +1817,17 @@ static struct vring_desc_extra 
> > *vring_alloc_desc_extra(unsigned int num)
> > return desc_extra;
> >   }
> >
> > -static struct virtqueue *vring_create_virtqueue_packed(
> > -   unsigned int index,
> > -   unsigned int num,
> > -   unsigned int vring_align,
> > -   struct virtio_device *vdev,
> > -   bool weak_barriers,
> > -   bool may_reduce_num,
> > -   bool context,
> > -   bool (*notify)(struct virtqueue *),
> > -   void (*callback)(struct virtqueue *),
> > -   const char *name)
> > +static int vring_alloc_queue_packed(struct virtio_device *vdev,
> > +   u32 num,
> > +   struct vring_packed_desc **_ring,
> > +   struct vring_packed_desc_event **_driver,
> > +   struct vring_packed_desc_event **_device,
> > +   dma_addr_t *_ring_dma_addr,
> > +   dma_addr_t *_driver_event_dma_addr,
> > +   dma_addr_t *_device_event_dma_addr,
> > +   size_t *_ring_size_in_bytes,
> > +   size_t *_event_size_in_bytes)
> >   {
> > -   struct vring_virtqueue *vq;
> > struct vring_packed_desc *ring;
> > struct vring_packed_desc_event *driver, *device;
> > dma_addr_t ring_dma_addr, driver_event_dma_addr, device_event_dma_addr;
> > @@ -1857,6 +1855,52 @@ static struct virtqueue 
> > *vring_create_virtqueue_packed(
> > if (!device)
> > goto err_device;
> >
> > +   *_ring   = ring;
> > +   *_driver = driver;
> > +   *_device = device;
> > +   *_ring_dma_addr  = ring_dma_addr;
> > +   *_driver_event_dma_addr  = driver_event_dma_addr;
> > +   *_device_event_dma_addr  = device_event_dma_addr;
> > +   *_ring_size_in_bytes = ring_size_in_bytes;
> > +   *_event_size_in_bytes= event_size_in_bytes;
>
>
> I wonder if we can simply factor out split and packed from struct
> vring_virtqueue:
>
> struct vring_virtqueue {
>      union {
>          struct {} split;
>          struct {} packed;
>      };
> };
>
> to
>
> struct vring_virtqueue_split {};
> struct vring_virtqueue_packed {};
>
> Then we can do things like:
>
> vring_create_virtqueue_packed(struct virtio_device *vdev, u32 num,
> struct vring_virtqueue_packed *packed);
>
> and
>
> vring_vritqueue_attach_packed(struct vring_virtqueue *vq, struct
> vring_virtqueue_packed packed);

This idea is very similar to my previous idea, just without introducing a new
structure.

I'd be more than happy to revise this.

Thanks.


>
> Thanks
>
>
> > +
> > +   return 0;
> > +
> > +err_device:
> > +   vring_free_queue(vdev, event_size_in_bytes, driver, 
> > driver_event_dma_addr);
> > +
> > +err_driver:
> > +   vring_free_queue(vdev, ring_size_in_bytes, ring, ring_dma_addr);
> > +
> > +err_ring:
> > +   return -ENOMEM;
> > +}
> > +
> > +static struct virtqueue *vring_create_virtqueue_packed(
> > +   unsigned int index,
> > +   unsigned int num,
> > +   unsigned int vring_align,
> > +   struct virtio_device *vdev,
> > +   bool weak_barriers,
> > +   bool may_reduce_num,
> > +   bool context,
> > +   bool (*notify)(struct virtqueue *),
> > +   void (*callback)(struct virtqueue *),
> > +   const char *name)
> > +{
> > +   dma_addr_t ring_dma_addr, driver_event_dma_addr, device_event_dma_addr;
> > +   struct vring_packed_desc_event *driver, *device;
> > +   size_t ring_size_in_bytes, event_size_in_bytes;
> > +   struct vring_packed_desc *ring;
> > +   struct vring_virtqueue *vq;
> > +
> > +   if (vring_alloc_queue_packed(vdev, num, , , ,
> > +_dma_addr, _event_dma_addr,
> > +_event_dma_addr,
> > +_size_in_bytes,
> > +_size_in_bytes))
> > +   goto err_ring;
> > +
> > vq = kmalloc(sizeof(*vq), GFP_KERNEL);
> > if (!vq)
> > goto err_vq;
> > @@ -1939,9 +1983,7 @@ static struct virtqueue 
> > *vring_create_virtqueue_packed(
> > kfree(vq);
> >   err_vq:
> > vring_free_queue(vdev, event_size_in_bytes, device, 
> > device_event_dma_addr);
> > -err_device:
> > vring_free_queue(vdev, event_size_in_bytes, 

Re: [PATCH v9 23/32] virtio_pci: queue_reset: support VIRTIO_F_RING_RESET

2022-04-12 Thread Xuan Zhuo
On Tue, 12 Apr 2022 15:07:58 +0800, Jason Wang  wrote:
>
> 在 2022/4/6 上午11:43, Xuan Zhuo 写道:
> > This patch implements virtio pci support for QUEUE RESET.
> >
> > Performing reset on a queue is divided into these steps:
> >
> >   1. notify the device to reset the queue
> >   2. recycle the buffer submitted
> >   3. reset the vring (may re-alloc)
> >   4. mmap vring to device, and enable the queue
> >
> > This patch implements virtio_reset_vq(), virtio_enable_resetq() in the
> > pci scenario.
> >
> > Signed-off-by: Xuan Zhuo 
> > ---
> >   drivers/virtio/virtio_pci_common.c |  8 +--
> >   drivers/virtio/virtio_pci_modern.c | 84 ++
> >   drivers/virtio/virtio_ring.c   |  2 +
> >   include/linux/virtio.h |  1 +
> >   4 files changed, 92 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/virtio/virtio_pci_common.c 
> > b/drivers/virtio/virtio_pci_common.c
> > index fdbde1db5ec5..863d3a8a0956 100644
> > --- a/drivers/virtio/virtio_pci_common.c
> > +++ b/drivers/virtio/virtio_pci_common.c
> > @@ -248,9 +248,11 @@ static void vp_del_vq(struct virtqueue *vq)
> > struct virtio_pci_vq_info *info = vp_dev->vqs[vq->index];
> > unsigned long flags;
> >
> > -   spin_lock_irqsave(_dev->lock, flags);
> > -   list_del(>node);
> > -   spin_unlock_irqrestore(_dev->lock, flags);
> > +   if (!vq->reset) {
>
>
> On which condition that we may hit this path?
>
>
> > +   spin_lock_irqsave(_dev->lock, flags);
> > +   list_del(>node);
> > +   spin_unlock_irqrestore(_dev->lock, flags);
> > +   }
> >
> > vp_dev->del_vq(info);
> > kfree(info);
> > diff --git a/drivers/virtio/virtio_pci_modern.c 
> > b/drivers/virtio/virtio_pci_modern.c
> > index 49a4493732cf..cb5d38f1c9c8 100644
> > --- a/drivers/virtio/virtio_pci_modern.c
> > +++ b/drivers/virtio/virtio_pci_modern.c
> > @@ -34,6 +34,9 @@ static void vp_transport_features(struct virtio_device 
> > *vdev, u64 features)
> > if ((features & BIT_ULL(VIRTIO_F_SR_IOV)) &&
> > pci_find_ext_capability(pci_dev, PCI_EXT_CAP_ID_SRIOV))
> > __virtio_set_bit(vdev, VIRTIO_F_SR_IOV);
> > +
> > +   if (features & BIT_ULL(VIRTIO_F_RING_RESET))
> > +   __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);
> >   }
> >
> >   /* virtio config->finalize_features() implementation */
> > @@ -199,6 +202,83 @@ static int vp_active_vq(struct virtqueue *vq, u16 
> > msix_vec)
> > return 0;
> >   }
> >
> > +static int vp_modern_reset_vq(struct virtqueue *vq)
> > +{
> > +   struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
> > +   struct virtio_pci_modern_device *mdev = _dev->mdev;
> > +   struct virtio_pci_vq_info *info;
> > +   unsigned long flags;
> > +
> > +   if (!virtio_has_feature(vq->vdev, VIRTIO_F_RING_RESET))
> > +   return -ENOENT;
> > +
> > +   vp_modern_set_queue_reset(mdev, vq->index);
> > +
> > +   info = vp_dev->vqs[vq->index];
> > +
> > +   /* delete vq from irq handler */
> > +   spin_lock_irqsave(_dev->lock, flags);
> > +   list_del(>node);
> > +   spin_unlock_irqrestore(_dev->lock, flags);
> > +
> > +   INIT_LIST_HEAD(>node);
> > +
> > +   /* For the case where vq has an exclusive irq, to prevent the irq from
> > +* being received again and the pending irq, call disable_irq().
> > +*
> > +* In the scenario based on shared interrupts, vq will be searched from
> > +* the queue virtqueues. Since the previous list_del() has been deleted
> > +* from the queue, it is impossible for vq to be called in this case.
> > +* There is no need to close the corresponding interrupt.
> > +*/
> > +   if (vp_dev->per_vq_vectors && info->msix_vector != VIRTIO_MSI_NO_VECTOR)
> > +   disable_irq(pci_irq_vector(vp_dev->pci_dev, info->msix_vector));
>
>
> See the previous discussion and the revert of the first try to harden
> the interrupt. We probably can't use disable_irq() since it conflicts
> with the affinity managed IRQ that is used by some drivers.
>
> We need to use synchonize_irq() and per virtqueue flag instead. As
> mentioned in previous patches, this could be done on top of my rework on
> the IRQ hardening .

OK, the next version will contain hardened features by per virtqueue flag.

Thanks.

>
>
> > +
> > +   vq->reset = true;
> > +
> > +   return 0;
> > +}
> > +
> > +static int vp_modern_enable_reset_vq(struct virtqueue *vq)
> > +{
> > +   struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
> > +   struct virtio_pci_modern_device *mdev = _dev->mdev;
> > +   struct virtio_pci_vq_info *info;
> > +   unsigned long flags, index;
> > +   int err;
> > +
> > +   if (!vq->reset)
> > +   return -EBUSY;
> > +
> > +   index = vq->index;
> > +   info = vp_dev->vqs[index];
> > +
> > +   /* check queue reset status */
> > +   if (vp_modern_get_queue_reset(mdev, index) != 1)
> > +   return -EBUSY;
> > +
> > +   err = vp_active_vq(vq, info->msix_vector);
> > +   if (err)
> > +   return err;
> > +
> > +   if 

Re: [PATCH] fuse: avoid unnecessary spinlock bump

2022-04-12 Thread JeffleXu



On 4/11/22 10:00 PM, Vivek Goyal wrote:
> On Mon, Apr 11, 2022 at 03:20:05PM +0200, Bernd Schubert wrote:
> 
> So for testing DAX, I have to rely on out of tree patches from qemu
> here if any changes in virtiofs client happen.
> 
> https://gitlab.com/virtio-fs/qemu/-/tree/virtio-fs-dev
> 
> Jeffle is probably relying on their own virtiofsd implementation for DAX
> testing.
> 

Actually I also use the C version virtiofsd in the above described
repository for testing :)

-- 
Thanks,
Jeffle
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH V2 4/5] virtio-pci: implement synchronize_vqs()

2022-04-12 Thread Jason Wang
On Wed, Apr 13, 2022 at 12:49 AM Cornelia Huck  wrote:
>
> On Tue, Apr 12 2022, Halil Pasic  wrote:
>
> > On Mon, 11 Apr 2022 16:27:41 +0200
> > Cornelia Huck  wrote:
>
> >> My main concern is that we would need to synchronize against a single
> >> interrupt that covers all kinds of I/O interrupts, not just a single
> >> device...
> >>
> >
> > Could we synchronize on struct airq_info's lock member? If we were
> > to grab all of these that might be involved...
>
> Hm, that could possibly narrow the sync down to a subset, which seems
> better. For devices still using classic interrupts, per-device sync
> would be easy.
>
> >
> > AFAIU for the synchronize implementation we need a lock or a set of locks
> > that contain all the possible vring_interrupt() calls with the queuues
> > that belong to the given device as a critical section. That way, one
> > has the acquire's and release's in place so that the vrign_interrupt()
> > either guaranteed to finish before the change of driver_ready is
> > guaranteed to be complete, or it is guaranteed to see the change.
> >
> > In any case, I guess we should first get clear on the first part. I.e.
> > when do we want to allow host->guest notifications.
>
> Also, whether we just care about vring interrupts, or general device
> interrupts (not sure if a config change interrupt may also trigger
> things we do not want to trigger?)

I think only vring interrupts, since the config interrupt hardening is
done via 22b7050a024d7 ("virtio: defer config changed notifications")

Thanks

>

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v9 01/32] virtio: add helper virtqueue_get_vring_max_size()

2022-04-12 Thread Xuan Zhuo
On Tue, 12 Apr 2022 10:41:03 +0800, Jason Wang  wrote:
>
> 在 2022/4/6 上午11:43, Xuan Zhuo 写道:
> > Record the maximum queue num supported by the device.
> >
> > virtio-net can display the maximum (supported by hardware) ring size in
> > ethtool -g eth0.
> >
> > When the subsequent patch implements vring reset, it can judge whether
> > the ring size passed by the driver is legal based on this.
> >
> > Signed-off-by: Xuan Zhuo 
> > ---
> >   arch/um/drivers/virtio_uml.c |  1 +
> >   drivers/platform/mellanox/mlxbf-tmfifo.c |  2 ++
> >   drivers/remoteproc/remoteproc_virtio.c   |  2 ++
> >   drivers/s390/virtio/virtio_ccw.c |  3 +++
> >   drivers/virtio/virtio_mmio.c |  2 ++
> >   drivers/virtio/virtio_pci_legacy.c   |  2 ++
> >   drivers/virtio/virtio_pci_modern.c   |  2 ++
> >   drivers/virtio/virtio_ring.c | 14 ++
> >   drivers/virtio/virtio_vdpa.c |  2 ++
> >   include/linux/virtio.h   |  2 ++
> >   10 files changed, 32 insertions(+)
> >
> > diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
> > index ba562d68dc04..904993d15a85 100644
> > --- a/arch/um/drivers/virtio_uml.c
> > +++ b/arch/um/drivers/virtio_uml.c
> > @@ -945,6 +945,7 @@ static struct virtqueue *vu_setup_vq(struct 
> > virtio_device *vdev,
> > goto error_create;
> > }
> > vq->priv = info;
> > +   vq->num_max = num;
> > num = virtqueue_get_vring_size(vq);
> >
> > if (vu_dev->protocol_features &
> > diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c 
> > b/drivers/platform/mellanox/mlxbf-tmfifo.c
> > index 38800e86ed8a..1ae3c56b66b0 100644
> > --- a/drivers/platform/mellanox/mlxbf-tmfifo.c
> > +++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
> > @@ -959,6 +959,8 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct 
> > virtio_device *vdev,
> > goto error;
> > }
> >
> > +   vq->num_max = vring->num;
> > +
> > vqs[i] = vq;
> > vring->vq = vq;
> > vq->priv = vring;
> > diff --git a/drivers/remoteproc/remoteproc_virtio.c 
> > b/drivers/remoteproc/remoteproc_virtio.c
> > index 70ab496d0431..7611755d0ae2 100644
> > --- a/drivers/remoteproc/remoteproc_virtio.c
> > +++ b/drivers/remoteproc/remoteproc_virtio.c
> > @@ -125,6 +125,8 @@ static struct virtqueue *rp_find_vq(struct 
> > virtio_device *vdev,
> > return ERR_PTR(-ENOMEM);
> > }
> >
> > +   vq->num_max = len;
>
>
> I wonder if this is correct.
>
> It looks to me len is counted in bytes:
>
> /**
>   * struct rproc_vring - remoteproc vring state
>   * @va: virtual address
>   * @len: length, in bytes
>   * @da: device address
>   * @align: vring alignment
>   * @notifyid: rproc-specific unique vring index
>   * @rvdev: remote vdev
>   * @vq: the virtqueue of this vring
>   */
> struct rproc_vring {
>      void *va;
>      int len;
>      u32 da;
>      u32 align;
>      int notifyid;
>      struct rproc_vdev *rvdev;
>      struct virtqueue *vq;
> };
>

I think this comment is incorrect because here len is passed as num to
vring_new_virtqueue().

There is also this usage:

/* actual size of vring (in bytes) */
size = PAGE_ALIGN(vring_size(rvring->len, rvring->align));


And this value comes from here:

static int
rproc_parse_vring(struct rproc_vdev *rvdev, struct fw_rsc_vdev *rsc, 
int i)
{
struct rproc *rproc = rvdev->rproc;
struct device *dev = >dev;
struct fw_rsc_vdev_vring *vring = >vring[i];
struct rproc_vring *rvring = >vring[i];

dev_dbg(dev, "vdev rsc: vring%d: da 0x%x, qsz %d, align %d\n",
i, vring->da, vring->num, vring->align);

/* verify queue size and vring alignment are sane */
if (!vring->num || !vring->align) {
dev_err(dev, "invalid qsz (%d) or alignment (%d)\n",
vring->num, vring->align);
return -EINVAL;
}

   >rvring->len = vring->num;
rvring->align = vring->align;
rvring->rvdev = rvdev;

return 0;
}

/**
 * struct fw_rsc_vdev_vring - vring descriptor entry
 * @da: device address
 * @align: the alignment between the consumer and producer parts of the vring
 * @num: num of buffers supported by this vring (must be power of two)
 * @notifyid: a unique rproc-wide notify index for this vring. This notify
 * index is used when kicking a remote processor, to let it know that this
 * vring is triggered.
 * @pa: physical address
 *
 * This descriptor is not a resource entry by itself; it is part of the
 * vdev resource type (see below).
 *
 * Note that @da should either contain the device address where
 * the remote processor is expecting the vring, or indicate that
 * dynamically allocation of the 

Re: [PATCH V2 4/5] virtio-pci: implement synchronize_vqs()

2022-04-12 Thread Cornelia Huck
On Tue, Apr 12 2022, Halil Pasic  wrote:

> On Mon, 11 Apr 2022 16:27:41 +0200
> Cornelia Huck  wrote:

>> My main concern is that we would need to synchronize against a single
>> interrupt that covers all kinds of I/O interrupts, not just a single
>> device...
>> 
>
> Could we synchronize on struct airq_info's lock member? If we were
> to grab all of these that might be involved...

Hm, that could possibly narrow the sync down to a subset, which seems
better. For devices still using classic interrupts, per-device sync
would be easy.

>
> AFAIU for the synchronize implementation we need a lock or a set of locks
> that contain all the possible vring_interrupt() calls with the queuues
> that belong to the given device as a critical section. That way, one
> has the acquire's and release's in place so that the vrign_interrupt()
> either guaranteed to finish before the change of driver_ready is
> guaranteed to be complete, or it is guaranteed to see the change.
>
> In any case, I guess we should first get clear on the first part. I.e.
> when do we want to allow host->guest notifications.

Also, whether we just care about vring interrupts, or general device
interrupts (not sure if a config change interrupt may also trigger
things we do not want to trigger?)

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v2 1/2] vdpa: Add support for querying vendor statistics

2022-04-12 Thread kernel test robot
Hi Eli,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.18-rc2 next-20220412]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/intel-lab-lkp/linux/commits/Eli-Cohen/Show-statistics-for-a-vdpa-device/20220412-212129
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 
ce522ba9ef7e2d9fb22a39eb3371c0c64e2a433e
config: i386-randconfig-a004-20220411 
(https://download.01.org/0day-ci/archive/20220413/202204130003.froyiuxa-...@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 
fe2478d44e4f7f191c43fef629ac7a23d0251e72)
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/813a1bf827634a8d7e148b133e2849fac37819cd
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Eli-Cohen/Show-statistics-for-a-vdpa-device/20220412-212129
git checkout 813a1bf827634a8d7e148b133e2849fac37819cd
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=i386 SHELL=/bin/bash drivers/usb/typec/ drivers/vdpa/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/vdpa/vdpa.c:1122:61: warning: implicit conversion from 'int' to 
>> 's16' (aka 'short') changes value from 65535 to -1 [-Wconstant-conversion]
   [VDPA_ATTR_DEV_QUEUE_INDEX] = NLA_POLICY_RANGE(NLA_U32, 0, 65535),
 ~^~
   include/net/netlink.h:396:9: note: expanded from macro 'NLA_POLICY_RANGE'
   .max = _max \
  ^~~~
   1 warning generated.


vim +1122 drivers/vdpa/vdpa.c

  1114  
  1115  static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = {
  1116  [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING },
  1117  [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING },
  1118  [VDPA_ATTR_DEV_NAME] = { .type = NLA_STRING },
  1119  [VDPA_ATTR_DEV_NET_CFG_MACADDR] = NLA_POLICY_ETH_ADDR,
  1120  /* virtio spec 1.1 section 5.1.4.1 for valid MTU range */
  1121  [VDPA_ATTR_DEV_NET_CFG_MTU] = NLA_POLICY_MIN(NLA_U16, 68),
> 1122  [VDPA_ATTR_DEV_QUEUE_INDEX] = NLA_POLICY_RANGE(NLA_U32, 0, 
> 65535),
  1123  };
  1124  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v10 2/5] mm: page_isolation: check specified range for unmovable pages

2022-04-12 Thread David Hildenbrand
On 12.04.22 17:01, Zi Yan wrote:
> On 12 Apr 2022, at 10:49, David Hildenbrand wrote:
> 
>> On 12.04.22 16:07, Zi Yan wrote:
>>> On 12 Apr 2022, at 9:10, David Hildenbrand wrote:
>>>
 On 06.04.22 17:18, Zi Yan wrote:
> From: Zi Yan 
>
> Enable set_migratetype_isolate() to check specified sub-range for
> unmovable pages during isolation. Page isolation is done
> at MAX_ORDER_NR_PAEGS granularity, but not all pages within that
> granularity are intended to be isolated. For example,
> alloc_contig_range(), which uses page isolation, allows ranges without
> alignment. This commit makes unmovable page check only look for
> interesting pages, so that page isolation can succeed for any
> non-overlapping ranges.
>
> Signed-off-by: Zi Yan 
> ---

 [...]

>  /*
> - * This function checks whether pageblock includes unmovable pages or 
> not.
> + * This function checks whether the range [start_pfn, end_pfn) includes
> + * unmovable pages or not. The range must fall into a single pageblock 
> and
> + * consequently belong to a single zone.
>   *
>   * PageLRU check without isolation or lru_lock could race so that
>   * MIGRATE_MOVABLE block might include unmovable pages. And __PageMovable
> @@ -28,12 +30,14 @@
>   * cannot get removed (e.g., via memory unplug) concurrently.
>   *
>   */
> -static struct page *has_unmovable_pages(struct zone *zone, struct page 
> *page,
> -  int migratetype, int flags)
> +static struct page *has_unmovable_pages(unsigned long start_pfn, 
> unsigned long end_pfn,
> + int migratetype, int flags)
>  {
> - unsigned long iter = 0;
> - unsigned long pfn = page_to_pfn(page);
> - unsigned long offset = pfn % pageblock_nr_pages;
> + unsigned long pfn = start_pfn;
> + struct page *page = pfn_to_page(pfn);


 Just do

 struct page *page = pfn_to_page(start_pfn);
 struct zone *zone = page_zone(page);

 here. No need to lookup the zone again in the loop because, as you
 document "must ... belong to a single zone.".

 Then, there is also no need to initialize "pfn" here. In the loop header
 is sufficient.

>>>
>>> Sure.
>>>
> +
> + VM_BUG_ON(ALIGN_DOWN(start_pfn, pageblock_nr_pages) !=
> +   ALIGN_DOWN(end_pfn - 1, pageblock_nr_pages));
>
>   if (is_migrate_cma_page(page)) {
>   /*
> @@ -47,8 +51,11 @@ static struct page *has_unmovable_pages(struct zone 
> *zone, struct page *page,
>   return page;
>   }
>
> - for (; iter < pageblock_nr_pages - offset; iter++) {
> - page = pfn_to_page(pfn + iter);
> + for (pfn = start_pfn; pfn < end_pfn; pfn++) {
> + struct zone *zone;
> +
> + page = pfn_to_page(pfn);
> + zone = page_zone(page);
>
>   /*
>* Both, bootmem allocations and memory holes are marked
> @@ -85,7 +92,7 @@ static struct page *has_unmovable_pages(struct zone 
> *zone, struct page *page,
>   }
>
>   skip_pages = compound_nr(head) - (page - head);
> - iter += skip_pages - 1;
> + pfn += skip_pages - 1;
>   continue;
>   }
>
> @@ -97,7 +104,7 @@ static struct page *has_unmovable_pages(struct zone 
> *zone, struct page *page,
>*/
>   if (!page_ref_count(page)) {
>   if (PageBuddy(page))
> - iter += (1 << buddy_order(page)) - 1;
> + pfn += (1 << buddy_order(page)) - 1;
>   continue;
>   }
>
> @@ -134,11 +141,18 @@ static struct page *has_unmovable_pages(struct zone 
> *zone, struct page *page,
>   return NULL;
>  }
>
> -static int set_migratetype_isolate(struct page *page, int migratetype, 
> int isol_flags)
> +/*
> + * This function set pageblock migratetype to isolate if no unmovable 
> page is
> + * present in [start_pfn, end_pfn). The pageblock must intersect with
> + * [start_pfn, end_pfn).
> + */
> +static int set_migratetype_isolate(struct page *page, int migratetype, 
> int isol_flags,
> + unsigned long start_pfn, unsigned long end_pfn)

 I think we might be able do better, eventually not passing start_pfn at
 all. Hmm.
>>>
>>> IMHO, having start_pfn and end_pfn in the parameter list would make the
>>> interface easier to understand. Otherwise if we remove start_pfn,
>>> the caller needs to adjust @page to be within the range of [start_pfn,
>>> end_pfn)
>>>

 I think we want to pull out the
 start_isolate_page_range()/undo_isolate_page_range() interface change
 into a separate patch.
>>>
>>> 

Re: [PATCH v10 2/5] mm: page_isolation: check specified range for unmovable pages

2022-04-12 Thread David Hildenbrand
On 12.04.22 16:07, Zi Yan wrote:
> On 12 Apr 2022, at 9:10, David Hildenbrand wrote:
> 
>> On 06.04.22 17:18, Zi Yan wrote:
>>> From: Zi Yan 
>>>
>>> Enable set_migratetype_isolate() to check specified sub-range for
>>> unmovable pages during isolation. Page isolation is done
>>> at MAX_ORDER_NR_PAEGS granularity, but not all pages within that
>>> granularity are intended to be isolated. For example,
>>> alloc_contig_range(), which uses page isolation, allows ranges without
>>> alignment. This commit makes unmovable page check only look for
>>> interesting pages, so that page isolation can succeed for any
>>> non-overlapping ranges.
>>>
>>> Signed-off-by: Zi Yan 
>>> ---
>>
>> [...]
>>
>>>  /*
>>> - * This function checks whether pageblock includes unmovable pages or not.
>>> + * This function checks whether the range [start_pfn, end_pfn) includes
>>> + * unmovable pages or not. The range must fall into a single pageblock and
>>> + * consequently belong to a single zone.
>>>   *
>>>   * PageLRU check without isolation or lru_lock could race so that
>>>   * MIGRATE_MOVABLE block might include unmovable pages. And __PageMovable
>>> @@ -28,12 +30,14 @@
>>>   * cannot get removed (e.g., via memory unplug) concurrently.
>>>   *
>>>   */
>>> -static struct page *has_unmovable_pages(struct zone *zone, struct page 
>>> *page,
>>> -int migratetype, int flags)
>>> +static struct page *has_unmovable_pages(unsigned long start_pfn, unsigned 
>>> long end_pfn,
>>> +   int migratetype, int flags)
>>>  {
>>> -   unsigned long iter = 0;
>>> -   unsigned long pfn = page_to_pfn(page);
>>> -   unsigned long offset = pfn % pageblock_nr_pages;
>>> +   unsigned long pfn = start_pfn;
>>> +   struct page *page = pfn_to_page(pfn);
>>
>>
>> Just do
>>
>> struct page *page = pfn_to_page(start_pfn);
>> struct zone *zone = page_zone(page);
>>
>> here. No need to lookup the zone again in the loop because, as you
>> document "must ... belong to a single zone.".
>>
>> Then, there is also no need to initialize "pfn" here. In the loop header
>> is sufficient.
>>
> 
> Sure.
> 
>>> +
>>> +   VM_BUG_ON(ALIGN_DOWN(start_pfn, pageblock_nr_pages) !=
>>> + ALIGN_DOWN(end_pfn - 1, pageblock_nr_pages));
>>>
>>> if (is_migrate_cma_page(page)) {
>>> /*
>>> @@ -47,8 +51,11 @@ static struct page *has_unmovable_pages(struct zone 
>>> *zone, struct page *page,
>>> return page;
>>> }
>>>
>>> -   for (; iter < pageblock_nr_pages - offset; iter++) {
>>> -   page = pfn_to_page(pfn + iter);
>>> +   for (pfn = start_pfn; pfn < end_pfn; pfn++) {
>>> +   struct zone *zone;
>>> +
>>> +   page = pfn_to_page(pfn);
>>> +   zone = page_zone(page);
>>>
>>> /*
>>>  * Both, bootmem allocations and memory holes are marked
>>> @@ -85,7 +92,7 @@ static struct page *has_unmovable_pages(struct zone 
>>> *zone, struct page *page,
>>> }
>>>
>>> skip_pages = compound_nr(head) - (page - head);
>>> -   iter += skip_pages - 1;
>>> +   pfn += skip_pages - 1;
>>> continue;
>>> }
>>>
>>> @@ -97,7 +104,7 @@ static struct page *has_unmovable_pages(struct zone 
>>> *zone, struct page *page,
>>>  */
>>> if (!page_ref_count(page)) {
>>> if (PageBuddy(page))
>>> -   iter += (1 << buddy_order(page)) - 1;
>>> +   pfn += (1 << buddy_order(page)) - 1;
>>> continue;
>>> }
>>>
>>> @@ -134,11 +141,18 @@ static struct page *has_unmovable_pages(struct zone 
>>> *zone, struct page *page,
>>> return NULL;
>>>  }
>>>
>>> -static int set_migratetype_isolate(struct page *page, int migratetype, int 
>>> isol_flags)
>>> +/*
>>> + * This function set pageblock migratetype to isolate if no unmovable page 
>>> is
>>> + * present in [start_pfn, end_pfn). The pageblock must intersect with
>>> + * [start_pfn, end_pfn).
>>> + */
>>> +static int set_migratetype_isolate(struct page *page, int migratetype, int 
>>> isol_flags,
>>> +   unsigned long start_pfn, unsigned long end_pfn)
>>
>> I think we might be able do better, eventually not passing start_pfn at
>> all. Hmm.
> 
> IMHO, having start_pfn and end_pfn in the parameter list would make the
> interface easier to understand. Otherwise if we remove start_pfn,
> the caller needs to adjust @page to be within the range of [start_pfn,
> end_pfn)
> 
>>
>> I think we want to pull out the
>> start_isolate_page_range()/undo_isolate_page_range() interface change
>> into a separate patch.
> 
> You mean a patch just adding
> 
> unsigned long isolate_start = pfn_max_align_down(start_pfn);
> unsigned long isolate_end = pfn_max_align_up(end_pfn);
> 
> in start_isolate_page_range()/undo_isolate_page_range()?
> 
> Yes I can do that.

I think we have to be careful with memory 

Re: [PATCH v10 2/5] mm: page_isolation: check specified range for unmovable pages

2022-04-12 Thread David Hildenbrand
On 06.04.22 17:18, Zi Yan wrote:
> From: Zi Yan 
> 
> Enable set_migratetype_isolate() to check specified sub-range for
> unmovable pages during isolation. Page isolation is done
> at MAX_ORDER_NR_PAEGS granularity, but not all pages within that
> granularity are intended to be isolated. For example,
> alloc_contig_range(), which uses page isolation, allows ranges without
> alignment. This commit makes unmovable page check only look for
> interesting pages, so that page isolation can succeed for any
> non-overlapping ranges.
> 
> Signed-off-by: Zi Yan 
> ---

[...]

>  /*
> - * This function checks whether pageblock includes unmovable pages or not.
> + * This function checks whether the range [start_pfn, end_pfn) includes
> + * unmovable pages or not. The range must fall into a single pageblock and
> + * consequently belong to a single zone.
>   *
>   * PageLRU check without isolation or lru_lock could race so that
>   * MIGRATE_MOVABLE block might include unmovable pages. And __PageMovable
> @@ -28,12 +30,14 @@
>   * cannot get removed (e.g., via memory unplug) concurrently.
>   *
>   */
> -static struct page *has_unmovable_pages(struct zone *zone, struct page *page,
> -  int migratetype, int flags)
> +static struct page *has_unmovable_pages(unsigned long start_pfn, unsigned 
> long end_pfn,
> + int migratetype, int flags)
>  {
> - unsigned long iter = 0;
> - unsigned long pfn = page_to_pfn(page);
> - unsigned long offset = pfn % pageblock_nr_pages;
> + unsigned long pfn = start_pfn;
> + struct page *page = pfn_to_page(pfn);


Just do

struct page *page = pfn_to_page(start_pfn);
struct zone *zone = page_zone(page);

here. No need to lookup the zone again in the loop because, as you
document "must ... belong to a single zone.".

Then, there is also no need to initialize "pfn" here. In the loop header
is sufficient.

> +
> + VM_BUG_ON(ALIGN_DOWN(start_pfn, pageblock_nr_pages) !=
> +   ALIGN_DOWN(end_pfn - 1, pageblock_nr_pages));
>  
>   if (is_migrate_cma_page(page)) {
>   /*
> @@ -47,8 +51,11 @@ static struct page *has_unmovable_pages(struct zone *zone, 
> struct page *page,
>   return page;
>   }
>  
> - for (; iter < pageblock_nr_pages - offset; iter++) {
> - page = pfn_to_page(pfn + iter);
> + for (pfn = start_pfn; pfn < end_pfn; pfn++) {
> + struct zone *zone;
> +
> + page = pfn_to_page(pfn);
> + zone = page_zone(page);
>  
>   /*
>* Both, bootmem allocations and memory holes are marked
> @@ -85,7 +92,7 @@ static struct page *has_unmovable_pages(struct zone *zone, 
> struct page *page,
>   }
>  
>   skip_pages = compound_nr(head) - (page - head);
> - iter += skip_pages - 1;
> + pfn += skip_pages - 1;
>   continue;
>   }
>  
> @@ -97,7 +104,7 @@ static struct page *has_unmovable_pages(struct zone *zone, 
> struct page *page,
>*/
>   if (!page_ref_count(page)) {
>   if (PageBuddy(page))
> - iter += (1 << buddy_order(page)) - 1;
> + pfn += (1 << buddy_order(page)) - 1;
>   continue;
>   }
>  
> @@ -134,11 +141,18 @@ static struct page *has_unmovable_pages(struct zone 
> *zone, struct page *page,
>   return NULL;
>  }
>  
> -static int set_migratetype_isolate(struct page *page, int migratetype, int 
> isol_flags)
> +/*
> + * This function set pageblock migratetype to isolate if no unmovable page is
> + * present in [start_pfn, end_pfn). The pageblock must intersect with
> + * [start_pfn, end_pfn).
> + */
> +static int set_migratetype_isolate(struct page *page, int migratetype, int 
> isol_flags,
> + unsigned long start_pfn, unsigned long end_pfn)

I think we might be able do better, eventually not passing start_pfn at
all. Hmm.

I think we want to pull out the
start_isolate_page_range()/undo_isolate_page_range() interface change
into a separate patch.

Let me try to give it a shot, I'll try hacking something up real quick
to see if we can do better.

-- 
Thanks,

David / dhildenb

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v10 0/5] Use pageblock_order for cma and alloc_contig_range alignment.

2022-04-12 Thread David Hildenbrand
On 06.04.22 17:18, Zi Yan wrote:
> From: Zi Yan 
> 
> Hi David,

Hi!

> 
> This patchset tries to remove the MAX_ORDER-1 alignment requirement for CMA
> and alloc_contig_range(). It prepares for my upcoming changes to make
> MAX_ORDER adjustable at boot time[1]. It is on top of mmotm-2022-04-05-15-54.

Sorry for the late reply, I've got way too many irons in the fire right now.

> 
> I also added "Content-Type: text/plain; charset=UTF-8" to all email bodies
> explicitly, please let me know if you still cannot see the emails in a
> proper format.

Oh, thanks! But no need to work around Mimecast mailing issues on your
side. This just has to be fixed for good on the RH side ...


I yet heave to give #3 a thorough review, sorry for not commenting on
that earlier. It's a bit more involved, especially, with all the
possible corner cases :)

-- 
Thanks,

David / dhildenb

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: Re: [PATCH v4 0/8] Introduce akcipher service for virtio-crypto

2022-04-12 Thread zhenwei pi



On 4/12/22 17:47, Paolo Bonzini wrote:



In our plan, the feature is designed for HTTPS offloading case and
other applications which use kernel RSA/ecdsa by keyctl syscall.


Hi Zhenwei,

what is the % of time spent doing asymmetric key operations in your
benchmark?  I am not very familiar with crypto acceleration but my
understanding has always been that most time is spent doing either
hashing (for signing) or symmetric key operations (for encryption).

If I understand correctly, without support for acceleration these 
patches are more of a demonstration of virtio-crypto, or usable for 
testing purposes.




Hi, Paolo

This is the perf result of nginx+openssl CPU calculation, the heavy load 
from openssl uses the most time(as same as you mentioned).
27.37%26.00%  nginxlibcrypto.so.1.1  [.] 
__bn_sqrx8x_reduction
20.58%19.52%  nginxlibcrypto.so.1.1  [.] 
mulx4x_internal
16.73%15.89%  nginxlibcrypto.so.1.1  [.] 
bn_sqrx8x_internal
 8.79% 0.00%  nginx[unknown] [k] 

 7.26% 0.00%  nginx[unknown] [.] 
0x89388669992a0cbc
 7.00% 0.00%  nginx[unknown] [k] 
0x45f0e480d5f2a58e
 6.76% 0.02%  nginx[kernel.kallsyms] [k] 
entry_SYSCALL_64_after_hwframe
 6.74% 0.02%  nginx[kernel.kallsyms] [k] 
do_syscall_64
 6.61% 0.00%  nginx[unknown] [.] 
0xa75a60d7820f9ffb
 6.47% 0.00%  nginx[unknown] [k] 
0xe91223f6da36254c
 5.51% 0.01%  nginx[kernel.kallsyms] [k] 
asm_common_interrupt
 5.46% 0.01%  nginx[kernel.kallsyms] [k] 
common_interrupt
 5.16% 0.04%  nginx[kernel.kallsyms] [k] 
__softirqentry_text_start
 4.92% 0.01%  nginx[kernel.kallsyms] [k] 
irq_exit_rcu
 4.91% 0.04%  nginx[kernel.kallsyms] [k] 
net_rx_action



This is the result of nginx+openssl keyctl offload(virtio crypto + host 
keyctl + Intel QAT):
30.38% 0.08%  nginx[kernel.kallsyms] [k] 
entry_SYSCALL_64_after_hwframe
30.29% 0.07%  nginx[kernel.kallsyms] [k] 
do_syscall_64
23.84% 0.00%  nginx[unknown] [k] 

14.24% 0.03%  nginx[kernel.kallsyms] [k] 
asm_common_interrupt
14.06% 0.05%  nginx[kernel.kallsyms] [k] 
common_interrupt
12.99% 0.11%  nginx[kernel.kallsyms] [k] 
__softirqentry_text_start
12.27% 0.12%  nginx[kernel.kallsyms] [k] 
net_rx_action

12.13% 0.03%  nginx[kernel.kallsyms] [k] __napi_poll
12.06% 0.06%  nginx[kernel.kallsyms] [k] 
irq_exit_rcu
10.49% 0.14%  nginxlibssl.so.1.1 [.] 
tls_process_client_key_exchange
10.21% 0.12%  nginx[virtio_net]  [k] 
virtnet_poll

10.13% 0.04%  nginxlibc-2.28.so  [.] syscall
10.12% 0.03%  nginxkctl-engine.so[.] 
kctl_rsa_priv_dec
10.02% 0.02%  nginxkctl-engine.so[.] 
kctl_hw_rsa_priv_func
 9.98% 0.01%  nginxlibkeyutils.so.1.10   [.] 
keyctl_pkey_decrypt

 9.95% 0.02%  nginxlibkeyutils.so.1.10   [.] keyctl
 9.77% 0.03%  nginx[kernel.kallsyms] [k] 
keyctl_pkey_e_d_s
 8.97% 0.00%  nginx[unknown] [k] 
0x7f4adbb81f0b
 8.78% 0.08%  nginxlibpthread-2.28.so[.] 
__libc_write
 8.49% 0.05%  nginx[kernel.kallsyms] [k] 
netif_receive_skb_list_internal


The RSA part gets reduced, and the QPS of https improves to ~200%.

Something may be ignored in this cover letter:
[4] Currently RSA is supported only in builtin driver. This driver is 
supposed to test the full feature without other software(Ex vhost 
process) and hardware dependence.

-> Yes, this patch is a demonstration of virtio-crypto.

[5] keyctl backend is in development, we will post this feature in 
Q2-2022. keyctl backend can use hardware acceleration(Ex, Intel QAT).

-> This is our plan. Currently it's still in developing.



Would it be possible to extend virtio-crypto to use keys already in the
host keyctl, or in a PKCS#11 smartcard, so that virtio-crypto could also
provide the functionality of an HSM?  Or does the standard require that
the keys are provided by the guest?

Paolo


I'm very interested in this, I'll try in Q3-2022 or later.

--
zhenwei pi
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v4 0/8] Introduce akcipher service for virtio-crypto

2022-04-12 Thread Paolo Bonzini




In our plan, the feature is designed for HTTPS offloading case and
other applications which use kernel RSA/ecdsa by keyctl syscall.


Hi Zhenwei,

what is the % of time spent doing asymmetric key operations in your
benchmark?  I am not very familiar with crypto acceleration but my
understanding has always been that most time is spent doing either
hashing (for signing) or symmetric key operations (for encryption).

If I understand correctly, without support for acceleration these 
patches are more of a demonstration of virtio-crypto, or usable for 
testing purposes.


Would it be possible to extend virtio-crypto to use keys already in the
host keyctl, or in a PKCS#11 smartcard, so that virtio-crypto could also
provide the functionality of an HSM?  Or does the standard require that
the keys are provided by the guest?

Paolo
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH V2 4/5] virtio-pci: implement synchronize_vqs()

2022-04-12 Thread Halil Pasic
On Tue, 12 Apr 2022 10:24:35 +0800
Jason Wang  wrote:

> > Regarding the question "are we safe against notifications before
> > indicators have been registered" I think we really need to think about
> > something like Secure Execution. We don't have, and we are unlikely
> > to have in hardware virtio-ccw implementations, and for a malicious 
> > hypervisor
> > that has full access to the guest memory hardening makes no sense.  
> 
> Does s390 have something like memory encryption? (I guess yes). In the
> case of x86 VM encryption, the I/O buffers were now done via software
> IOTLB, that's why hardening of the virtio driver is needed to prevent
> the hypervisor to poke the swiotlb etc.

Yep! Secure Execution is a confidential computing solution which is much
like encrypted guest memory, except for one gets exceptions when trying
to access private memory instead of ending up with garbage  because of
the encryption. These improvements are IMHO relevant to us!

Regards,
Halil
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v3 11/15] drm/shmem-helper: Add generic memory shrinker

2022-04-12 Thread kernel test robot
Hi Dmitry,

I love your patch! Perhaps something to improve:

[auto build test WARNING on next-20220411]
[cannot apply to drm/drm-next v5.18-rc2 v5.18-rc1 v5.17 v5.18-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/intel-lab-lkp/linux/commits/Dmitry-Osipenko/Add-generic-memory-shrinker-to-VirtIO-GPU-and-Panfrost-DRM-drivers/20220412-060325
base:d12d7e1cfe38e0c36d28c7a9fbbc436ad0d17c14
config: hexagon-randconfig-r045-20220411 
(https://download.01.org/0day-ci/archive/20220412/202204121504.glr3fhqe-...@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 
fe2478d44e4f7f191c43fef629ac7a23d0251e72)
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/683ba8a9d72ba7770a61a9266a2b33949f3874f2
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Dmitry-Osipenko/Add-generic-memory-shrinker-to-VirtIO-GPU-and-Panfrost-DRM-drivers/20220412-060325
git checkout 683ba8a9d72ba7770a61a9266a2b33949f3874f2
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=hexagon SHELL=/bin/bash drivers/gpu/drm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/drm_gem_shmem_helper.c:289:11: warning: variable 'new_state' 
>> is used uninitialized whenever 'if' condition is false 
>> [-Wsometimes-uninitialized]
   else if (shmem->madv < 0)
^~~
   drivers/gpu/drm/drm_gem_shmem_helper.c:292:46: note: uninitialized use 
occurs here
   drm_gem_shmem_set_pages_state_locked(shmem, new_state);
   ^
   drivers/gpu/drm/drm_gem_shmem_helper.c:289:7: note: remove the 'if' if its 
condition is always true
   else if (shmem->madv < 0)
^~~~
   drivers/gpu/drm/drm_gem_shmem_helper.c:278:2: note: variable 'new_state' is 
declared here
   enum drm_gem_shmem_pages_state new_state;
   ^
   1 warning generated.


vim +289 drivers/gpu/drm/drm_gem_shmem_helper.c

   273  
   274  static void drm_gem_shmem_update_pages_state_locked(struct 
drm_gem_shmem_object *shmem)
   275  {
   276  struct drm_gem_object *obj = >base;
   277  struct drm_gem_shmem_shrinker *gem_shrinker = 
obj->dev->shmem_shrinker;
   278  enum drm_gem_shmem_pages_state new_state;
   279  
   280  if (!gem_shrinker || obj->import_attach)
   281  return;
   282  
   283  mutex_lock(_shrinker->lock);
   284  
   285  if (!shmem->madv)
   286  new_state = DRM_GEM_SHMEM_PAGES_STATE_ACTIVE;
   287  else if (shmem->madv > 0)
   288  new_state = DRM_GEM_SHMEM_PAGES_STATE_PURGEABLE;
 > 289  else if (shmem->madv < 0)
   290  new_state = DRM_GEM_SHMEM_PAGES_STATE_PURGED;
   291  
   292  drm_gem_shmem_set_pages_state_locked(shmem, new_state);
   293  
   294  mutex_unlock(_shrinker->lock);
   295  }
   296  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v3 11/15] drm/shmem-helper: Add generic memory shrinker

2022-04-12 Thread kernel test robot
Hi Dmitry,

I love your patch! Perhaps something to improve:

[auto build test WARNING on next-20220411]
[cannot apply to drm/drm-next v5.18-rc2 v5.18-rc1 v5.17 v5.18-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:
https://github.com/intel-lab-lkp/linux/commits/Dmitry-Osipenko/Add-generic-memory-shrinker-to-VirtIO-GPU-and-Panfrost-DRM-drivers/20220412-060325
base:d12d7e1cfe38e0c36d28c7a9fbbc436ad0d17c14
config: i386-randconfig-a005-20220411 
(https://download.01.org/0day-ci/archive/20220412/202204121523.qvmxovzg-...@intel.com/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project 
fe2478d44e4f7f191c43fef629ac7a23d0251e72)
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/683ba8a9d72ba7770a61a9266a2b33949f3874f2
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review 
Dmitry-Osipenko/Add-generic-memory-shrinker-to-VirtIO-GPU-and-Panfrost-DRM-drivers/20220412-060325
git checkout 683ba8a9d72ba7770a61a9266a2b33949f3874f2
# save the config file to linux build tree
mkdir build_dir
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 
O=build_dir ARCH=i386 SHELL=/bin/bash drivers/gpu/drm/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot 

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/drm_gem_shmem_helper.c:289:11: warning: variable 'new_state' 
>> is used uninitialized whenever 'if' condition is false 
>> [-Wsometimes-uninitialized]
   else if (shmem->madv < 0)
^~~
   drivers/gpu/drm/drm_gem_shmem_helper.c:292:46: note: uninitialized use 
occurs here
   drm_gem_shmem_set_pages_state_locked(shmem, new_state);
   ^
   drivers/gpu/drm/drm_gem_shmem_helper.c:289:7: note: remove the 'if' if its 
condition is always true
   else if (shmem->madv < 0)
^~~~
   drivers/gpu/drm/drm_gem_shmem_helper.c:278:2: note: variable 'new_state' is 
declared here
   enum drm_gem_shmem_pages_state new_state;
   ^
   1 warning generated.


vim +289 drivers/gpu/drm/drm_gem_shmem_helper.c

   273  
   274  static void drm_gem_shmem_update_pages_state_locked(struct 
drm_gem_shmem_object *shmem)
   275  {
   276  struct drm_gem_object *obj = >base;
   277  struct drm_gem_shmem_shrinker *gem_shrinker = 
obj->dev->shmem_shrinker;
   278  enum drm_gem_shmem_pages_state new_state;
   279  
   280  if (!gem_shrinker || obj->import_attach)
   281  return;
   282  
   283  mutex_lock(_shrinker->lock);
   284  
   285  if (!shmem->madv)
   286  new_state = DRM_GEM_SHMEM_PAGES_STATE_ACTIVE;
   287  else if (shmem->madv > 0)
   288  new_state = DRM_GEM_SHMEM_PAGES_STATE_PURGEABLE;
 > 289  else if (shmem->madv < 0)
   290  new_state = DRM_GEM_SHMEM_PAGES_STATE_PURGED;
   291  
   292  drm_gem_shmem_set_pages_state_locked(shmem, new_state);
   293  
   294  mutex_unlock(_shrinker->lock);
   295  }
   296  

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp
___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v9 29/32] virtio_net: get ringparam by virtqueue_get_vring_max_size()

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Use virtqueue_get_vring_max_size() in virtnet_get_ringparam() to set
tx,rx_max_pending.

Signed-off-by: Xuan Zhuo 
---



Acked-by: Jason Wang 



  drivers/net/virtio_net.c | 8 
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index dad497a47b3a..96d96c666c8c 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2177,10 +2177,10 @@ static void virtnet_get_ringparam(struct net_device 
*dev,
  {
struct virtnet_info *vi = netdev_priv(dev);
  
-	ring->rx_max_pending = virtqueue_get_vring_size(vi->rq[0].vq);

-   ring->tx_max_pending = virtqueue_get_vring_size(vi->sq[0].vq);
-   ring->rx_pending = ring->rx_max_pending;
-   ring->tx_pending = ring->tx_max_pending;
+   ring->rx_max_pending = virtqueue_get_vring_max_size(vi->rq[0].vq);
+   ring->tx_max_pending = virtqueue_get_vring_max_size(vi->sq[0].vq);
+   ring->rx_pending = virtqueue_get_vring_size(vi->rq[0].vq);
+   ring->tx_pending = virtqueue_get_vring_size(vi->sq[0].vq);
  }
  
  


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v9 28/32] virtio_net: set the default max ring size by find_vqs()

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Use virtio_find_vqs_ctx_size() to specify the maximum ring size of tx,
rx at the same time.

  | rx/tx ring size
---
speed == UNKNOWN or < 10G| 1024
speed < 40G  | 4096
speed >= 40G | 8192

Call virtnet_update_settings() once before calling init_vqs() to update
speed.

Signed-off-by: Xuan Zhuo 
---



Acked-by: Jason Wang 



  drivers/net/virtio_net.c | 42 
  1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index a801ea40908f..dad497a47b3a 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2861,6 +2861,29 @@ static unsigned int mergeable_min_buf_len(struct 
virtnet_info *vi, struct virtqu
   (unsigned int)GOOD_PACKET_LEN);
  }
  
+static void virtnet_config_sizes(struct virtnet_info *vi, u32 *sizes)

+{
+   u32 i, rx_size, tx_size;
+
+   if (vi->speed == SPEED_UNKNOWN || vi->speed < SPEED_1) {
+   rx_size = 1024;
+   tx_size = 1024;
+
+   } else if (vi->speed < SPEED_4) {
+   rx_size = 1024 * 4;
+   tx_size = 1024 * 4;
+
+   } else {
+   rx_size = 1024 * 8;
+   tx_size = 1024 * 8;
+   }
+
+   for (i = 0; i < vi->max_queue_pairs; i++) {
+   sizes[rxq2vq(i)] = rx_size;
+   sizes[txq2vq(i)] = tx_size;
+   }
+}
+
  static int virtnet_find_vqs(struct virtnet_info *vi)
  {
vq_callback_t **callbacks;
@@ -2868,6 +2891,7 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
int ret = -ENOMEM;
int i, total_vqs;
const char **names;
+   u32 *sizes;
bool *ctx;
  
  	/* We expect 1 RX virtqueue followed by 1 TX virtqueue, followed by

@@ -2895,10 +2919,15 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
ctx = NULL;
}
  
+	sizes = kmalloc_array(total_vqs, sizeof(*sizes), GFP_KERNEL);

+   if (!sizes)
+   goto err_sizes;
+
/* Parameters for control virtqueue, if any */
if (vi->has_cvq) {
callbacks[total_vqs - 1] = NULL;
names[total_vqs - 1] = "control";
+   sizes[total_vqs - 1] = 64;
}
  
  	/* Allocate/initialize parameters for send/receive virtqueues */

@@ -2913,8 +2942,10 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
ctx[rxq2vq(i)] = true;
}
  
-	ret = virtio_find_vqs_ctx(vi->vdev, total_vqs, vqs, callbacks,

- names, ctx, NULL);
+   virtnet_config_sizes(vi, sizes);
+
+   ret = virtio_find_vqs_ctx_size(vi->vdev, total_vqs, vqs, callbacks,
+  names, sizes, ctx, NULL);
if (ret)
goto err_find;
  
@@ -2934,6 +2965,8 @@ static int virtnet_find_vqs(struct virtnet_info *vi)
  
  
  err_find:

+   kfree(sizes);
+err_sizes:
kfree(ctx);
  err_ctx:
kfree(names);
@@ -3252,6 +3285,9 @@ static int virtnet_probe(struct virtio_device *vdev)
vi->curr_queue_pairs = num_online_cpus();
vi->max_queue_pairs = max_queue_pairs;
  
+	virtnet_init_settings(dev);

+   virtnet_update_settings(vi);
+
/* Allocate/initialize the rx/tx queues, and invoke find_vqs */
err = init_vqs(vi);
if (err)
@@ -3264,8 +3300,6 @@ static int virtnet_probe(struct virtio_device *vdev)
netif_set_real_num_tx_queues(dev, vi->curr_queue_pairs);
netif_set_real_num_rx_queues(dev, vi->curr_queue_pairs);
  
-	virtnet_init_settings(dev);

-
if (virtio_has_feature(vdev, VIRTIO_NET_F_STANDBY)) {
vi->failover = net_failover_create(vi->dev);
if (IS_ERR(vi->failover)) {


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v9 27/32] virtio: add helper virtio_find_vqs_ctx_size()

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Introduce helper virtio_find_vqs_ctx_size() to call find_vqs and specify
the maximum size of each vq ring.

Signed-off-by: Xuan Zhuo 



Acked-by: Jason Wang 



---
  include/linux/virtio_config.h | 12 
  1 file changed, 12 insertions(+)

diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h
index 0f7def7ddfd2..22e29c926946 100644
--- a/include/linux/virtio_config.h
+++ b/include/linux/virtio_config.h
@@ -235,6 +235,18 @@ int virtio_find_vqs_ctx(struct virtio_device *vdev, 
unsigned nvqs,
  ctx, desc);
  }
  
+static inline

+int virtio_find_vqs_ctx_size(struct virtio_device *vdev, u32 nvqs,
+struct virtqueue *vqs[],
+vq_callback_t *callbacks[],
+const char * const names[],
+u32 sizes[],
+const bool *ctx, struct irq_affinity *desc)
+{
+   return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, sizes,
+ ctx, desc);
+}
+
  /**
   * virtio_device_ready - enable vq use in probe function
   * @vdev: the device


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 5.17 184/343] virtio_console: eliminate anonymous module_init & module_exit

2022-04-12 Thread Greg Kroah-Hartman
From: Randy Dunlap 

[ Upstream commit fefb8a2a941338d871e2d83fbd65fbfa068857bd ]

Eliminate anonymous module_init() and module_exit(), which can lead to
confusion or ambiguity when reading System.map, crashes/oops/bugs,
or an initcall_debug log.

Give each of these init and exit functions unique driver-specific
names to eliminate the anonymous names.

Example 1: (System.map)
 832fc78c t init
 832fc79e t init
 832fc8f8 t init

Example 2: (initcall_debug log)
 calling  init+0x0/0x12 @ 1
 initcall init+0x0/0x12 returned 0 after 15 usecs
 calling  init+0x0/0x60 @ 1
 initcall init+0x0/0x60 returned 0 after 2 usecs
 calling  init+0x0/0x9a @ 1
 initcall init+0x0/0x9a returned 0 after 74 usecs

Signed-off-by: Randy Dunlap 
Reviewed-by: Amit Shah 
Cc: virtualization@lists.linux-foundation.org
Cc: Arnd Bergmann 
Link: https://lore.kernel.org/r/20220316192010.19001-3-rdun...@infradead.org
Signed-off-by: Greg Kroah-Hartman 
Signed-off-by: Sasha Levin 
---
 drivers/char/virtio_console.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index e3c430539a17..9fa3c76a267f 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -2245,7 +2245,7 @@ static struct virtio_driver virtio_rproc_serial = {
.remove =   virtcons_remove,
 };
 
-static int __init init(void)
+static int __init virtio_console_init(void)
 {
int err;
 
@@ -2280,7 +2280,7 @@ static int __init init(void)
return err;
 }
 
-static void __exit fini(void)
+static void __exit virtio_console_fini(void)
 {
reclaim_dma_bufs();
 
@@ -2290,8 +2290,8 @@ static void __exit fini(void)
class_destroy(pdrvdata.class);
debugfs_remove_recursive(pdrvdata.debugfs_dir);
 }
-module_init(init);
-module_exit(fini);
+module_init(virtio_console_init);
+module_exit(virtio_console_fini);
 
 MODULE_DESCRIPTION("Virtio console driver");
 MODULE_LICENSE("GPL");
-- 
2.35.1



___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v9 26/32] virtio_mmio: support the arg sizes of find_vqs()

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Virtio MMIO support the new parameter sizes of find_vqs().

Signed-off-by: Xuan Zhuo 
---



Acked-by: Jason Wang 



  drivers/virtio/virtio_mmio.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index 9d5a674bdeec..51cf51764a92 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -347,7 +347,7 @@ static void vm_del_vqs(struct virtio_device *vdev)
  
  static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,

  void (*callback)(struct virtqueue *vq),
- const char *name, bool ctx)
+ const char *name, u32 size, bool ctx)
  {
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
struct virtio_mmio_vq_info *info;
@@ -382,8 +382,11 @@ static struct virtqueue *vm_setup_vq(struct virtio_device 
*vdev, unsigned index,
goto error_new_virtqueue;
}
  
+	if (!size || size > num)

+   size = num;
+
/* Create the vring */
-   vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev,
+   vq = vring_create_virtqueue(index, size, VIRTIO_MMIO_VRING_ALIGN, vdev,
 true, true, ctx, vm_notify, callback, name);
if (!vq) {
err = -ENOMEM;
@@ -484,6 +487,7 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned 
nvqs,
}
  
  		vqs[i] = vm_setup_vq(vdev, queue_idx++, callbacks[i], names[i],

+sizes ? sizes[i] : 0,
 ctx ? ctx[i] : false);
if (IS_ERR(vqs[i])) {
vm_del_vqs(vdev);


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v9 25/32] virtio_pci: support the arg sizes of find_vqs()

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Virtio PCI supports new parameter sizes of find_vqs().

Signed-off-by: Xuan Zhuo 



Acked-by: Jason Wang 



---
  drivers/virtio/virtio_pci_common.c | 18 ++
  drivers/virtio/virtio_pci_common.h |  1 +
  drivers/virtio/virtio_pci_legacy.c |  6 +-
  drivers/virtio/virtio_pci_modern.c | 10 +++---
  4 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/drivers/virtio/virtio_pci_common.c 
b/drivers/virtio/virtio_pci_common.c
index 826ea2e35d54..23976c61583f 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -208,6 +208,7 @@ static int vp_request_msix_vectors(struct virtio_device 
*vdev, int nvectors,
  static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned 
index,
 void (*callback)(struct virtqueue *vq),
 const char *name,
+u32 size,
 bool ctx,
 u16 msix_vec)
  {
@@ -220,7 +221,7 @@ static struct virtqueue *vp_setup_vq(struct virtio_device 
*vdev, unsigned index,
if (!info)
return ERR_PTR(-ENOMEM);
  
-	vq = vp_dev->setup_vq(vp_dev, info, index, callback, name, ctx,

+   vq = vp_dev->setup_vq(vp_dev, info, index, callback, name, size, ctx,
  msix_vec);
if (IS_ERR(vq))
goto out_info;
@@ -314,7 +315,7 @@ void vp_del_vqs(struct virtio_device *vdev)
  
  static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,

struct virtqueue *vqs[], vq_callback_t *callbacks[],
-   const char * const names[], bool per_vq_vectors,
+   const char * const names[], u32 sizes[], bool per_vq_vectors,
const bool *ctx,
struct irq_affinity *desc)
  {
@@ -357,8 +358,8 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, 
unsigned nvqs,
else
msix_vec = VP_MSIX_VQ_VECTOR;
vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
-ctx ? ctx[i] : false,
-msix_vec);
+sizes ? sizes[i] : 0,
+ctx ? ctx[i] : false, msix_vec);
if (IS_ERR(vqs[i])) {
err = PTR_ERR(vqs[i]);
goto error_find;
@@ -388,7 +389,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, 
unsigned nvqs,
  
  static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned nvqs,

struct virtqueue *vqs[], vq_callback_t *callbacks[],
-   const char * const names[], const bool *ctx)
+   const char * const names[], u32 sizes[], const bool *ctx)
  {
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
int i, err, queue_idx = 0;
@@ -410,6 +411,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, 
unsigned nvqs,
continue;
}
vqs[i] = vp_setup_vq(vdev, queue_idx++, callbacks[i], names[i],
+sizes ? sizes[i] : 0,
 ctx ? ctx[i] : false,
 VIRTIO_MSI_NO_VECTOR);
if (IS_ERR(vqs[i])) {
@@ -433,15 +435,15 @@ int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
int err;
  
  	/* Try MSI-X with one vector per queue. */

-   err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, true, ctx, 
desc);
+   err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, sizes, true, 
ctx, desc);
if (!err)
return 0;
/* Fallback: MSI-X with one vector for config, one shared for queues. */
-   err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, false, ctx, 
desc);
+   err = vp_find_vqs_msix(vdev, nvqs, vqs, callbacks, names, sizes, false, 
ctx, desc);
if (!err)
return 0;
/* Finally fall back to regular interrupts. */
-   return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names, ctx);
+   return vp_find_vqs_intx(vdev, nvqs, vqs, callbacks, names, sizes, ctx);
  }
  
  const char *vp_bus_name(struct virtio_device *vdev)

diff --git a/drivers/virtio/virtio_pci_common.h 
b/drivers/virtio/virtio_pci_common.h
index 859eed559e10..fbf5a6d4b164 100644
--- a/drivers/virtio/virtio_pci_common.h
+++ b/drivers/virtio/virtio_pci_common.h
@@ -81,6 +81,7 @@ struct virtio_pci_device {
  unsigned idx,
  void (*callback)(struct virtqueue *vq),
  const char *name,
+ u32 size,
  bool ctx,
  u16 msix_vec);
void 

Re: [PATCH v9 24/32] virtio: find_vqs() add arg sizes

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

find_vqs() adds a new parameter sizes to specify the size of each vq
vring.

0 means use the maximum size supported by the backend.



Does this mean driver still need to prepare a array of 0 or it can 
simply pass NULL to find_vqs()?


Thanks




In the split scenario, the meaning of size is the largest size, because
it may be limited by memory, the virtio core will try a smaller size.
And the size is power of 2.

Signed-off-by: Xuan Zhuo 
Acked-by: Hans de Goede 
Reviewed-by: Mathieu Poirier 
---
  arch/um/drivers/virtio_uml.c |  2 +-
  drivers/platform/mellanox/mlxbf-tmfifo.c |  1 +
  drivers/remoteproc/remoteproc_virtio.c   |  1 +
  drivers/s390/virtio/virtio_ccw.c |  1 +
  drivers/virtio/virtio_mmio.c |  1 +
  drivers/virtio/virtio_pci_common.c   |  2 +-
  drivers/virtio/virtio_pci_common.h   |  2 +-
  drivers/virtio/virtio_pci_modern.c   |  7 +--
  drivers/virtio/virtio_vdpa.c |  1 +
  include/linux/virtio_config.h| 14 +-
  10 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c
index 904993d15a85..6af98d130840 100644
--- a/arch/um/drivers/virtio_uml.c
+++ b/arch/um/drivers/virtio_uml.c
@@ -998,7 +998,7 @@ static struct virtqueue *vu_setup_vq(struct virtio_device 
*vdev,
  
  static int vu_find_vqs(struct virtio_device *vdev, unsigned nvqs,

   struct virtqueue *vqs[], vq_callback_t *callbacks[],
-  const char * const names[], const bool *ctx,
+  const char * const names[], u32 sizes[], const bool *ctx,
   struct irq_affinity *desc)
  {
struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev);
diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c 
b/drivers/platform/mellanox/mlxbf-tmfifo.c
index 1ae3c56b66b0..8be13d416f48 100644
--- a/drivers/platform/mellanox/mlxbf-tmfifo.c
+++ b/drivers/platform/mellanox/mlxbf-tmfifo.c
@@ -928,6 +928,7 @@ static int mlxbf_tmfifo_virtio_find_vqs(struct 
virtio_device *vdev,
struct virtqueue *vqs[],
vq_callback_t *callbacks[],
const char * const names[],
+   u32 sizes[],
const bool *ctx,
struct irq_affinity *desc)
  {
diff --git a/drivers/remoteproc/remoteproc_virtio.c 
b/drivers/remoteproc/remoteproc_virtio.c
index 7611755d0ae2..baad31c9da45 100644
--- a/drivers/remoteproc/remoteproc_virtio.c
+++ b/drivers/remoteproc/remoteproc_virtio.c
@@ -158,6 +158,7 @@ static int rproc_virtio_find_vqs(struct virtio_device 
*vdev, unsigned int nvqs,
 struct virtqueue *vqs[],
 vq_callback_t *callbacks[],
 const char * const names[],
+u32 sizes[],
 const bool * ctx,
 struct irq_affinity *desc)
  {
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index 468da60b56c5..f0c814a54e78 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -634,6 +634,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, 
unsigned nvqs,
   struct virtqueue *vqs[],
   vq_callback_t *callbacks[],
   const char * const names[],
+  u32 sizes[],
   const bool *ctx,
   struct irq_affinity *desc)
  {
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c
index a41abc8051b9..9d5a674bdeec 100644
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -461,6 +461,7 @@ static int vm_find_vqs(struct virtio_device *vdev, unsigned 
nvqs,
   struct virtqueue *vqs[],
   vq_callback_t *callbacks[],
   const char * const names[],
+  u32 sizes[],
   const bool *ctx,
   struct irq_affinity *desc)
  {
diff --git a/drivers/virtio/virtio_pci_common.c 
b/drivers/virtio/virtio_pci_common.c
index 863d3a8a0956..826ea2e35d54 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -427,7 +427,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, 
unsigned nvqs,
  /* the config->find_vqs() implementation */
  int vp_find_vqs(struct virtio_device *vdev, unsigned nvqs,
struct virtqueue *vqs[], vq_callback_t *callbacks[],
-   const char * const names[], const bool *ctx,
+   const char * const names[], u32 sizes[], const bool *ctx,
struct irq_affinity 

Re: [PATCH v9 23/32] virtio_pci: queue_reset: support VIRTIO_F_RING_RESET

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

This patch implements virtio pci support for QUEUE RESET.

Performing reset on a queue is divided into these steps:

  1. notify the device to reset the queue
  2. recycle the buffer submitted
  3. reset the vring (may re-alloc)
  4. mmap vring to device, and enable the queue

This patch implements virtio_reset_vq(), virtio_enable_resetq() in the
pci scenario.

Signed-off-by: Xuan Zhuo 
---
  drivers/virtio/virtio_pci_common.c |  8 +--
  drivers/virtio/virtio_pci_modern.c | 84 ++
  drivers/virtio/virtio_ring.c   |  2 +
  include/linux/virtio.h |  1 +
  4 files changed, 92 insertions(+), 3 deletions(-)

diff --git a/drivers/virtio/virtio_pci_common.c 
b/drivers/virtio/virtio_pci_common.c
index fdbde1db5ec5..863d3a8a0956 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -248,9 +248,11 @@ static void vp_del_vq(struct virtqueue *vq)
struct virtio_pci_vq_info *info = vp_dev->vqs[vq->index];
unsigned long flags;
  
-	spin_lock_irqsave(_dev->lock, flags);

-   list_del(>node);
-   spin_unlock_irqrestore(_dev->lock, flags);
+   if (!vq->reset) {



On which condition that we may hit this path?



+   spin_lock_irqsave(_dev->lock, flags);
+   list_del(>node);
+   spin_unlock_irqrestore(_dev->lock, flags);
+   }
  
  	vp_dev->del_vq(info);

kfree(info);
diff --git a/drivers/virtio/virtio_pci_modern.c 
b/drivers/virtio/virtio_pci_modern.c
index 49a4493732cf..cb5d38f1c9c8 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -34,6 +34,9 @@ static void vp_transport_features(struct virtio_device *vdev, 
u64 features)
if ((features & BIT_ULL(VIRTIO_F_SR_IOV)) &&
pci_find_ext_capability(pci_dev, PCI_EXT_CAP_ID_SRIOV))
__virtio_set_bit(vdev, VIRTIO_F_SR_IOV);
+
+   if (features & BIT_ULL(VIRTIO_F_RING_RESET))
+   __virtio_set_bit(vdev, VIRTIO_F_RING_RESET);
  }
  
  /* virtio config->finalize_features() implementation */

@@ -199,6 +202,83 @@ static int vp_active_vq(struct virtqueue *vq, u16 msix_vec)
return 0;
  }
  
+static int vp_modern_reset_vq(struct virtqueue *vq)

+{
+   struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
+   struct virtio_pci_modern_device *mdev = _dev->mdev;
+   struct virtio_pci_vq_info *info;
+   unsigned long flags;
+
+   if (!virtio_has_feature(vq->vdev, VIRTIO_F_RING_RESET))
+   return -ENOENT;
+
+   vp_modern_set_queue_reset(mdev, vq->index);
+
+   info = vp_dev->vqs[vq->index];
+
+   /* delete vq from irq handler */
+   spin_lock_irqsave(_dev->lock, flags);
+   list_del(>node);
+   spin_unlock_irqrestore(_dev->lock, flags);
+
+   INIT_LIST_HEAD(>node);
+
+   /* For the case where vq has an exclusive irq, to prevent the irq from
+* being received again and the pending irq, call disable_irq().
+*
+* In the scenario based on shared interrupts, vq will be searched from
+* the queue virtqueues. Since the previous list_del() has been deleted
+* from the queue, it is impossible for vq to be called in this case.
+* There is no need to close the corresponding interrupt.
+*/
+   if (vp_dev->per_vq_vectors && info->msix_vector != VIRTIO_MSI_NO_VECTOR)
+   disable_irq(pci_irq_vector(vp_dev->pci_dev, info->msix_vector));



See the previous discussion and the revert of the first try to harden 
the interrupt. We probably can't use disable_irq() since it conflicts 
with the affinity managed IRQ that is used by some drivers.


We need to use synchonize_irq() and per virtqueue flag instead. As 
mentioned in previous patches, this could be done on top of my rework on 
the IRQ hardening .




+
+   vq->reset = true;
+
+   return 0;
+}
+
+static int vp_modern_enable_reset_vq(struct virtqueue *vq)
+{
+   struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
+   struct virtio_pci_modern_device *mdev = _dev->mdev;
+   struct virtio_pci_vq_info *info;
+   unsigned long flags, index;
+   int err;
+
+   if (!vq->reset)
+   return -EBUSY;
+
+   index = vq->index;
+   info = vp_dev->vqs[index];
+
+   /* check queue reset status */
+   if (vp_modern_get_queue_reset(mdev, index) != 1)
+   return -EBUSY;
+
+   err = vp_active_vq(vq, info->msix_vector);
+   if (err)
+   return err;
+
+   if (vq->callback) {
+   spin_lock_irqsave(_dev->lock, flags);
+   list_add(>node, _dev->virtqueues);
+   spin_unlock_irqrestore(_dev->lock, flags);
+   } else {
+   INIT_LIST_HEAD(>node);
+   }
+
+   vp_modern_set_queue_enable(_dev->mdev, index, true);
+
+   if (vp_dev->per_vq_vectors && info->msix_vector != VIRTIO_MSI_NO_VECTOR)
+  

[PATCH 5.16 140/285] virtio_console: eliminate anonymous module_init & module_exit

2022-04-12 Thread Greg Kroah-Hartman
From: Randy Dunlap 

[ Upstream commit fefb8a2a941338d871e2d83fbd65fbfa068857bd ]

Eliminate anonymous module_init() and module_exit(), which can lead to
confusion or ambiguity when reading System.map, crashes/oops/bugs,
or an initcall_debug log.

Give each of these init and exit functions unique driver-specific
names to eliminate the anonymous names.

Example 1: (System.map)
 832fc78c t init
 832fc79e t init
 832fc8f8 t init

Example 2: (initcall_debug log)
 calling  init+0x0/0x12 @ 1
 initcall init+0x0/0x12 returned 0 after 15 usecs
 calling  init+0x0/0x60 @ 1
 initcall init+0x0/0x60 returned 0 after 2 usecs
 calling  init+0x0/0x9a @ 1
 initcall init+0x0/0x9a returned 0 after 74 usecs

Signed-off-by: Randy Dunlap 
Reviewed-by: Amit Shah 
Cc: virtualization@lists.linux-foundation.org
Cc: Arnd Bergmann 
Link: https://lore.kernel.org/r/20220316192010.19001-3-rdun...@infradead.org
Signed-off-by: Greg Kroah-Hartman 
Signed-off-by: Sasha Levin 
---
 drivers/char/virtio_console.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index f864b17be7e3..35025f283bf6 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -2245,7 +2245,7 @@ static struct virtio_driver virtio_rproc_serial = {
.remove =   virtcons_remove,
 };
 
-static int __init init(void)
+static int __init virtio_console_init(void)
 {
int err;
 
@@ -2280,7 +2280,7 @@ static int __init init(void)
return err;
 }
 
-static void __exit fini(void)
+static void __exit virtio_console_fini(void)
 {
reclaim_dma_bufs();
 
@@ -2290,8 +2290,8 @@ static void __exit fini(void)
class_destroy(pdrvdata.class);
debugfs_remove_recursive(pdrvdata.debugfs_dir);
 }
-module_init(init);
-module_exit(fini);
+module_init(virtio_console_init);
+module_exit(virtio_console_fini);
 
 MODULE_DESCRIPTION("Virtio console driver");
 MODULE_LICENSE("GPL");
-- 
2.35.1



___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v9 22/32] virtio_pci: queue_reset: extract the logic of active vq for modern pci

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Introduce vp_active_vq() to configure vring to backend after vq attach
vring. And configure vq vector if necessary.

Signed-off-by: Xuan Zhuo 
---
  drivers/virtio/virtio_pci_modern.c | 46 ++
  1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/drivers/virtio/virtio_pci_modern.c 
b/drivers/virtio/virtio_pci_modern.c
index 86d301f272b8..49a4493732cf 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -176,6 +176,29 @@ static void vp_reset(struct virtio_device *vdev)
vp_disable_cbs(vdev);
  }
  
+static int vp_active_vq(struct virtqueue *vq, u16 msix_vec)

+{
+   struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
+   struct virtio_pci_modern_device *mdev = _dev->mdev;
+   unsigned long index;
+
+   index = vq->index;
+
+   /* activate the queue */
+   vp_modern_set_queue_size(mdev, index, virtqueue_get_vring_size(vq));
+   vp_modern_queue_address(mdev, index, virtqueue_get_desc_addr(vq),
+   virtqueue_get_avail_addr(vq),
+   virtqueue_get_used_addr(vq));
+
+   if (msix_vec != VIRTIO_MSI_NO_VECTOR) {
+   msix_vec = vp_modern_queue_vector(mdev, index, msix_vec);
+   if (msix_vec == VIRTIO_MSI_NO_VECTOR)
+   return -EBUSY;
+   }
+
+   return 0;
+}
+
  static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector)
  {
return vp_modern_config_vector(_dev->mdev, vector);
@@ -220,32 +243,19 @@ static struct virtqueue *setup_vq(struct 
virtio_pci_device *vp_dev,
  
  	vq->num_max = num;
  
-	/* activate the queue */

-   vp_modern_set_queue_size(mdev, index, virtqueue_get_vring_size(vq));
-   vp_modern_queue_address(mdev, index, virtqueue_get_desc_addr(vq),
-   virtqueue_get_avail_addr(vq),
-   virtqueue_get_used_addr(vq));
+   err = vp_active_vq(vq, msix_vec);
+   if (err)
+   goto err;
  
  	vq->priv = (void __force *)vp_modern_map_vq_notify(mdev, index, NULL);

if (!vq->priv) {
err = -ENOMEM;
-   goto err_map_notify;
-   }
-
-   if (msix_vec != VIRTIO_MSI_NO_VECTOR) {
-   msix_vec = vp_modern_queue_vector(mdev, index, msix_vec);
-   if (msix_vec == VIRTIO_MSI_NO_VECTOR) {
-   err = -EBUSY;
-   goto err_assign_vector;
-   }
+   goto err;
}
  
  	return vq;
  
-err_assign_vector:

-   if (!mdev->notify_base)
-   pci_iounmap(mdev->pci_dev, (void __iomem __force *)vq->priv);



We need keep this or anything I missed?

Thanks



-err_map_notify:
+err:
vring_del_virtqueue(vq);
return ERR_PTR(err);
  }


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re:

2022-04-12 Thread Michael S. Tsirkin
On Tue, Mar 29, 2022 at 10:35:21AM +0200, Thomas Gleixner wrote:
> On Mon, Mar 28 2022 at 06:40, Michael S. Tsirkin wrote:
> > On Mon, Mar 28, 2022 at 02:18:22PM +0800, Jason Wang wrote:
> >> > > So I think we might talk different issues:
> >> > >
> >> > > 1) Whether request_irq() commits the previous setups, I think the
> >> > > answer is yes, since the spin_unlock of desc->lock (release) can
> >> > > guarantee this though there seems no documentation around
> >> > > request_irq() to say this.
> >> > >
> >> > > And I can see at least drivers/video/fbdev/omap2/omapfb/dss/dispc.c is
> >> > > using smp_wmb() before the request_irq().
> 
> That's a complete bogus example especially as there is not a single
> smp_rmb() which pairs with the smp_wmb().
> 
> >> > > And even if write is ordered we still need read to be ordered to be
> >> > > paired with that.
> >
> > IMO it synchronizes with the CPU to which irq is
> > delivered. Otherwise basically all drivers would be broken,
> > wouldn't they be?
> > I don't know whether it's correct on all platforms, but if not
> > we need to fix request_irq.
> 
> There is nothing to fix:
> 
> request_irq()
>raw_spin_lock_irq(desc->lock);   // ACQUIRE
>
>raw_spin_unlock_irq(desc->lock); // RELEASE
> 
> interrupt()
>raw_spin_lock(desc->lock);   // ACQUIRE
>set status to IN_PROGRESS
>raw_spin_unlock(desc->lock); // RELEASE
>invoke handler()
> 
> So anything which the driver set up _before_ request_irq() is visible to
> the interrupt handler. No?
> 
> >> What happens if an interrupt is raised in the middle like:
> >> 
> >> smp_store_release(dev->irq_soft_enabled, true)
> >> IRQ handler
> >> synchornize_irq()
> 
> This is bogus. The obvious order of things is:
> 
> dev->ok = false;
> request_irq();
> 
> moar_setup();
> synchronize_irq();  // ACQUIRE + RELEASE
> dev->ok = true;
> 
> The reverse operation on teardown:
> 
> dev->ok = false;
> synchronize_irq();  // ACQUIRE + RELEASE
> 
> teardown();
> 
> So in both cases a simple check in the handler is sufficient:
> 
> handler()
> if (!dev->ok)
>   return;

Does this need to be if (!READ_ONCE(dev->ok)) ?



> I'm not understanding what you folks are trying to "fix" here. If any
> driver does this in the wrong order, then the driver is broken.
> 
> Sure, you can do the same with:
> 
> dev->ok = false;
> request_irq();
> moar_setup();
> smp_wmb();
> dev->ok = true;
> 
> for the price of a smp_rmb() in the interrupt handler:
> 
> handler()
> if (!dev->ok)
>   return;
> smp_rmb();
> 
> but that's only working for the setup case correctly and not for
> teardown.
> 
> Thanks,
> 
> tglx

___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


[PATCH 5.15 135/277] virtio_console: eliminate anonymous module_init & module_exit

2022-04-12 Thread Greg Kroah-Hartman
From: Randy Dunlap 

[ Upstream commit fefb8a2a941338d871e2d83fbd65fbfa068857bd ]

Eliminate anonymous module_init() and module_exit(), which can lead to
confusion or ambiguity when reading System.map, crashes/oops/bugs,
or an initcall_debug log.

Give each of these init and exit functions unique driver-specific
names to eliminate the anonymous names.

Example 1: (System.map)
 832fc78c t init
 832fc79e t init
 832fc8f8 t init

Example 2: (initcall_debug log)
 calling  init+0x0/0x12 @ 1
 initcall init+0x0/0x12 returned 0 after 15 usecs
 calling  init+0x0/0x60 @ 1
 initcall init+0x0/0x60 returned 0 after 2 usecs
 calling  init+0x0/0x9a @ 1
 initcall init+0x0/0x9a returned 0 after 74 usecs

Signed-off-by: Randy Dunlap 
Reviewed-by: Amit Shah 
Cc: virtualization@lists.linux-foundation.org
Cc: Arnd Bergmann 
Link: https://lore.kernel.org/r/20220316192010.19001-3-rdun...@infradead.org
Signed-off-by: Greg Kroah-Hartman 
Signed-off-by: Sasha Levin 
---
 drivers/char/virtio_console.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 3adf04766e98..77bc993d7513 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -2236,7 +2236,7 @@ static struct virtio_driver virtio_rproc_serial = {
.remove =   virtcons_remove,
 };
 
-static int __init init(void)
+static int __init virtio_console_init(void)
 {
int err;
 
@@ -2271,7 +2271,7 @@ static int __init init(void)
return err;
 }
 
-static void __exit fini(void)
+static void __exit virtio_console_fini(void)
 {
reclaim_dma_bufs();
 
@@ -2281,8 +2281,8 @@ static void __exit fini(void)
class_destroy(pdrvdata.class);
debugfs_remove_recursive(pdrvdata.debugfs_dir);
 }
-module_init(init);
-module_exit(fini);
+module_init(virtio_console_init);
+module_exit(virtio_console_fini);
 
 MODULE_DESCRIPTION("Virtio console driver");
 MODULE_LICENSE("GPL");
-- 
2.35.1



___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v9 21/32] virtio_pci: queue_reset: update struct virtio_pci_common_cfg and option functions

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Add queue_reset in virtio_pci_common_cfg, and add related operation
functions.

For not breaks uABI, add a new struct virtio_pci_common_cfg_reset.

Signed-off-by: Xuan Zhuo 
---
  drivers/virtio/virtio_pci_modern_dev.c | 36 ++
  include/linux/virtio_pci_modern.h  |  2 ++
  include/uapi/linux/virtio_pci.h|  7 +
  3 files changed, 45 insertions(+)

diff --git a/drivers/virtio/virtio_pci_modern_dev.c 
b/drivers/virtio/virtio_pci_modern_dev.c
index e8b3ff2b9fbc..8c74b00bc511 100644
--- a/drivers/virtio/virtio_pci_modern_dev.c
+++ b/drivers/virtio/virtio_pci_modern_dev.c
@@ -3,6 +3,7 @@
  #include 
  #include 
  #include 
+#include 
  
  /*

   * vp_modern_map_capability - map a part of virtio pci capability
@@ -463,6 +464,41 @@ void vp_modern_set_status(struct virtio_pci_modern_device 
*mdev,
  }
  EXPORT_SYMBOL_GPL(vp_modern_set_status);
  
+/*

+ * vp_modern_get_queue_reset - get the queue reset status
+ * @mdev: the modern virtio-pci device
+ * @index: queue index
+ */
+int vp_modern_get_queue_reset(struct virtio_pci_modern_device *mdev, u16 index)
+{
+   struct virtio_pci_common_cfg_reset __iomem *cfg;
+
+   cfg = (struct virtio_pci_common_cfg_reset __iomem *)mdev->common;
+
+   vp_iowrite16(index, >cfg.queue_select);
+   return vp_ioread16(>queue_reset);
+}
+EXPORT_SYMBOL_GPL(vp_modern_get_queue_reset);
+
+/*
+ * vp_modern_set_queue_reset - reset the queue
+ * @mdev: the modern virtio-pci device
+ * @index: queue index
+ */
+void vp_modern_set_queue_reset(struct virtio_pci_modern_device *mdev, u16 
index)
+{
+   struct virtio_pci_common_cfg_reset __iomem *cfg;
+
+   cfg = (struct virtio_pci_common_cfg_reset __iomem *)mdev->common;
+
+   vp_iowrite16(index, >cfg.queue_select);
+   vp_iowrite16(1, >queue_reset);
+
+   while (vp_ioread16(>queue_reset) != 1)
+   msleep(1);
+}
+EXPORT_SYMBOL_GPL(vp_modern_set_queue_reset);
+
  /*
   * vp_modern_queue_vector - set the MSIX vector for a specific virtqueue
   * @mdev: the modern virtio-pci device
diff --git a/include/linux/virtio_pci_modern.h 
b/include/linux/virtio_pci_modern.h
index eb2bd9b4077d..cc4154dd7b28 100644
--- a/include/linux/virtio_pci_modern.h
+++ b/include/linux/virtio_pci_modern.h
@@ -106,4 +106,6 @@ void __iomem * vp_modern_map_vq_notify(struct 
virtio_pci_modern_device *mdev,
   u16 index, resource_size_t *pa);
  int vp_modern_probe(struct virtio_pci_modern_device *mdev);
  void vp_modern_remove(struct virtio_pci_modern_device *mdev);
+int vp_modern_get_queue_reset(struct virtio_pci_modern_device *mdev, u16 
index);
+void vp_modern_set_queue_reset(struct virtio_pci_modern_device *mdev, u16 
index);
  #endif
diff --git a/include/uapi/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h
index 22bec9bd0dfc..d9462efd6ce8 100644
--- a/include/uapi/linux/virtio_pci.h
+++ b/include/uapi/linux/virtio_pci.h
@@ -173,6 +173,13 @@ struct virtio_pci_common_cfg_notify {
__le16 padding;
  };
  
+struct virtio_pci_common_cfg_reset {

+   struct virtio_pci_common_cfg cfg;
+
+   __le16 queue_notify_data;   /* read-write */
+   __le16 queue_reset; /* read-write */
+};



I prefer to use a separate patch for the uAPI change.

Other looks good.

Thanks



+
  /* Fields in VIRTIO_PCI_CAP_PCI_CFG: */
  struct virtio_pci_cfg_cap {
struct virtio_pci_cap cap;


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

Re: [PATCH v9 18/32] virtio_ring: introduce virtqueue_resize()

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Introduce virtqueue_resize() to implement the resize of vring.
Based on these, the driver can dynamically adjust the size of the vring.
For example: ethtool -G.

virtqueue_resize() implements resize based on the vq reset function. In
case of failure to allocate a new vring, it will give up resize and use
the original vring.

During this process, if the re-enable reset vq fails, the vq can no
longer be used. Although the probability of this situation is not high.

The parameter recycle is used to recycle the buffer that is no longer
used.

Signed-off-by: Xuan Zhuo 
---
  drivers/virtio/virtio_ring.c | 69 
  include/linux/virtio.h   |  3 ++
  2 files changed, 72 insertions(+)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 06f66b15c86c..6250e19fc5bf 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -2554,6 +2554,75 @@ struct virtqueue *vring_create_virtqueue(
  }
  EXPORT_SYMBOL_GPL(vring_create_virtqueue);
  
+/**

+ * virtqueue_resize - resize the vring of vq
+ * @_vq: the struct virtqueue we're talking about.
+ * @num: new ring num
+ * @recycle: callback for recycle the useless buffer
+ *
+ * When it is really necessary to create a new vring, it will set the current 
vq
+ * into the reset state. Then call the passed callback to recycle the buffer
+ * that is no longer used. Only after the new vring is successfully created, 
the
+ * old vring will be released.
+ *
+ * Caller must ensure we don't call this with other virtqueue operations
+ * at the same time (except where noted).
+ *
+ * Returns zero or a negative error.



Should we document that the virtqueue is kept unchanged (still 
available) on (specific) failure?




+ */
+int virtqueue_resize(struct virtqueue *_vq, u32 num,
+void (*recycle)(struct virtqueue *vq, void *buf))
+{
+   struct vring_virtqueue *vq = to_vvq(_vq);
+   struct virtio_device *vdev = vq->vq.vdev;
+   bool packed;
+   void *buf;
+   int err;
+
+   if (!vq->we_own_ring)
+   return -EINVAL;
+
+   if (num > vq->vq.num_max)
+   return -E2BIG;
+
+   if (!num)
+   return -EINVAL;
+
+   packed = virtio_has_feature(vdev, VIRTIO_F_RING_PACKED) ? true : false;
+
+   if ((packed ? vq->packed.vring.num : vq->split.vring.num) == num)
+   return 0;
+
+   if (!vdev->config->reset_vq)
+   return -ENOENT;
+
+   if (!vdev->config->enable_reset_vq)
+   return -ENOENT;
+
+   err = vdev->config->reset_vq(_vq);
+   if (err)
+   return err;
+
+   while ((buf = virtqueue_detach_unused_buf(_vq)) != NULL)
+   recycle(_vq, buf);
+
+   if (packed) {
+   err = virtqueue_resize_packed(_vq, num);
+   if (err)
+   virtqueue_reinit_packed(vq);



Calling reinit here seems a little bit odd, it looks more like a reset 
of the virtqueue. Consider we may re-use virtqueue reset for more 
purpose, I wonder if we need a helper like:


virtqueue_resize() {
    vdev->config->reset_vq(_vq);
    if (packed)
        virtqueue_reinit_packed(_vq)
    else
    virtqueue_reinit_split(_vq)
}

Thanks



+   } else {
+   err = virtqueue_resize_split(_vq, num);
+   if (err)
+   virtqueue_reinit_split(vq);
+   }
+
+   if (vdev->config->enable_reset_vq(_vq))
+   return -EBUSY;
+
+   return err;
+}
+EXPORT_SYMBOL_GPL(virtqueue_resize);
+
  /* Only available for split ring */
  struct virtqueue *vring_new_virtqueue(unsigned int index,
  unsigned int num,
diff --git a/include/linux/virtio.h b/include/linux/virtio.h
index d59adc4be068..c86ff02e0ca0 100644
--- a/include/linux/virtio.h
+++ b/include/linux/virtio.h
@@ -91,6 +91,9 @@ dma_addr_t virtqueue_get_desc_addr(struct virtqueue *vq);
  dma_addr_t virtqueue_get_avail_addr(struct virtqueue *vq);
  dma_addr_t virtqueue_get_used_addr(struct virtqueue *vq);
  
+int virtqueue_resize(struct virtqueue *vq, u32 num,

+void (*recycle)(struct virtqueue *vq, void *buf));
+
  /**
   * virtio_device - representation of a device using virtio
   * @index: unique position on the virtio bus


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

[PATCH 5.10 089/171] virtio_console: eliminate anonymous module_init & module_exit

2022-04-12 Thread Greg Kroah-Hartman
From: Randy Dunlap 

[ Upstream commit fefb8a2a941338d871e2d83fbd65fbfa068857bd ]

Eliminate anonymous module_init() and module_exit(), which can lead to
confusion or ambiguity when reading System.map, crashes/oops/bugs,
or an initcall_debug log.

Give each of these init and exit functions unique driver-specific
names to eliminate the anonymous names.

Example 1: (System.map)
 832fc78c t init
 832fc79e t init
 832fc8f8 t init

Example 2: (initcall_debug log)
 calling  init+0x0/0x12 @ 1
 initcall init+0x0/0x12 returned 0 after 15 usecs
 calling  init+0x0/0x60 @ 1
 initcall init+0x0/0x60 returned 0 after 2 usecs
 calling  init+0x0/0x9a @ 1
 initcall init+0x0/0x9a returned 0 after 74 usecs

Signed-off-by: Randy Dunlap 
Reviewed-by: Amit Shah 
Cc: virtualization@lists.linux-foundation.org
Cc: Arnd Bergmann 
Link: https://lore.kernel.org/r/20220316192010.19001-3-rdun...@infradead.org
Signed-off-by: Greg Kroah-Hartman 
Signed-off-by: Sasha Levin 
---
 drivers/char/virtio_console.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 3dd4deb60adb..6d361420ffe8 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -2239,7 +2239,7 @@ static struct virtio_driver virtio_rproc_serial = {
.remove =   virtcons_remove,
 };
 
-static int __init init(void)
+static int __init virtio_console_init(void)
 {
int err;
 
@@ -2276,7 +2276,7 @@ static int __init init(void)
return err;
 }
 
-static void __exit fini(void)
+static void __exit virtio_console_fini(void)
 {
reclaim_dma_bufs();
 
@@ -2286,8 +2286,8 @@ static void __exit fini(void)
class_destroy(pdrvdata.class);
debugfs_remove_recursive(pdrvdata.debugfs_dir);
 }
-module_init(init);
-module_exit(fini);
+module_init(virtio_console_init);
+module_exit(virtio_console_fini);
 
 MODULE_DESCRIPTION("Virtio console driver");
 MODULE_LICENSE("GPL");
-- 
2.35.1



___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization


Re: [PATCH v9 12/32] virtio_ring: packed: extract the logic of alloc queue

2022-04-12 Thread Jason Wang


在 2022/4/6 上午11:43, Xuan Zhuo 写道:

Separate the logic of packed to create vring queue.

For the convenience of passing parameters, add a structure
vring_packed.

This feature is required for subsequent virtuqueue reset vring.

Signed-off-by: Xuan Zhuo 
---
  drivers/virtio/virtio_ring.c | 70 
  1 file changed, 56 insertions(+), 14 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 33864134a744..ea451ae2aaef 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1817,19 +1817,17 @@ static struct vring_desc_extra 
*vring_alloc_desc_extra(unsigned int num)
return desc_extra;
  }
  
-static struct virtqueue *vring_create_virtqueue_packed(

-   unsigned int index,
-   unsigned int num,
-   unsigned int vring_align,
-   struct virtio_device *vdev,
-   bool weak_barriers,
-   bool may_reduce_num,
-   bool context,
-   bool (*notify)(struct virtqueue *),
-   void (*callback)(struct virtqueue *),
-   const char *name)
+static int vring_alloc_queue_packed(struct virtio_device *vdev,
+   u32 num,
+   struct vring_packed_desc **_ring,
+   struct vring_packed_desc_event **_driver,
+   struct vring_packed_desc_event **_device,
+   dma_addr_t *_ring_dma_addr,
+   dma_addr_t *_driver_event_dma_addr,
+   dma_addr_t *_device_event_dma_addr,
+   size_t *_ring_size_in_bytes,
+   size_t *_event_size_in_bytes)
  {
-   struct vring_virtqueue *vq;
struct vring_packed_desc *ring;
struct vring_packed_desc_event *driver, *device;
dma_addr_t ring_dma_addr, driver_event_dma_addr, device_event_dma_addr;
@@ -1857,6 +1855,52 @@ static struct virtqueue *vring_create_virtqueue_packed(
if (!device)
goto err_device;
  
+	*_ring   = ring;

+   *_driver = driver;
+   *_device = device;
+   *_ring_dma_addr  = ring_dma_addr;
+   *_driver_event_dma_addr  = driver_event_dma_addr;
+   *_device_event_dma_addr  = device_event_dma_addr;
+   *_ring_size_in_bytes = ring_size_in_bytes;
+   *_event_size_in_bytes= event_size_in_bytes;



I wonder if we can simply factor out split and packed from struct 
vring_virtqueue:


struct vring_virtqueue {
    union {
        struct {} split;
        struct {} packed;
    };
};

to

struct vring_virtqueue_split {};
struct vring_virtqueue_packed {};

Then we can do things like:

vring_create_virtqueue_packed(struct virtio_device *vdev, u32 num, 
struct vring_virtqueue_packed *packed);


and

vring_vritqueue_attach_packed(struct vring_virtqueue *vq, struct 
vring_virtqueue_packed packed);


Thanks



+
+   return 0;
+
+err_device:
+   vring_free_queue(vdev, event_size_in_bytes, driver, 
driver_event_dma_addr);
+
+err_driver:
+   vring_free_queue(vdev, ring_size_in_bytes, ring, ring_dma_addr);
+
+err_ring:
+   return -ENOMEM;
+}
+
+static struct virtqueue *vring_create_virtqueue_packed(
+   unsigned int index,
+   unsigned int num,
+   unsigned int vring_align,
+   struct virtio_device *vdev,
+   bool weak_barriers,
+   bool may_reduce_num,
+   bool context,
+   bool (*notify)(struct virtqueue *),
+   void (*callback)(struct virtqueue *),
+   const char *name)
+{
+   dma_addr_t ring_dma_addr, driver_event_dma_addr, device_event_dma_addr;
+   struct vring_packed_desc_event *driver, *device;
+   size_t ring_size_in_bytes, event_size_in_bytes;
+   struct vring_packed_desc *ring;
+   struct vring_virtqueue *vq;
+
+   if (vring_alloc_queue_packed(vdev, num, , , ,
+_dma_addr, _event_dma_addr,
+_event_dma_addr,
+_size_in_bytes,
+_size_in_bytes))
+   goto err_ring;
+
vq = kmalloc(sizeof(*vq), GFP_KERNEL);
if (!vq)
goto err_vq;
@@ -1939,9 +1983,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
kfree(vq);
  err_vq:
vring_free_queue(vdev, event_size_in_bytes, device, 
device_event_dma_addr);
-err_device:
vring_free_queue(vdev, event_size_in_bytes, driver, 
driver_event_dma_addr);
-err_driver:
vring_free_queue(vdev, ring_size_in_bytes, ring, ring_dma_addr);
  err_ring:
return NULL;


___
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization