* Re: [PATCH V4 5/5] vdpasim: vDPA device simulator
From: Jason Gunthorpe @ 2020-02-20 15:12 UTC (permalink / raw)
To: Jason Wang
Cc: mst@redhat.com, linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
virtualization@lists.linux-foundation.org, netdev@vger.kernel.org,
tiwei.bie@intel.com, maxime.coquelin@redhat.com,
cunming.liang@intel.com, zhihong.wang@intel.com,
rob.miller@broadcom.com, xiao.w.wang@intel.com,
haotian.wang@sifive.com, lingshan.zhu@intel.com,
eperezma@redhat.com, lulu@redhat.com, Parav Pandit,
kevin.tian@intel.com, stefanha@redhat.com, rdunlap@infradead.org,
hch@infradead.org, aadam@redhat.com, Jiri Pirko, Shahaf Shuler,
hanand@xilinx.com, mhabets@solarflare.com
In-Reply-To: <20200220061141.29390-6-jasowang@redhat.com>
On Thu, Feb 20, 2020 at 02:11:41PM +0800, Jason Wang wrote:
> +static void vdpasim_device_release(struct device *dev)
> +{
> + struct vdpasim *vdpasim = dev_to_sim(dev);
> +
> + cancel_work_sync(&vdpasim->work);
> + kfree(vdpasim->buffer);
> + vhost_iotlb_free(vdpasim->iommu);
> + kfree(vdpasim);
> +}
> +
> +static struct vdpasim *vdpasim_create(void)
> +{
> + struct virtio_net_config *config;
> + struct vhost_iotlb *iommu;
> + struct vdpasim *vdpasim;
> + struct device *dev;
> + void *buffer;
> + int ret = -ENOMEM;
> +
> + iommu = vhost_iotlb_alloc(2048, 0);
> + if (!iommu)
> + goto err;
> +
> + buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
> + if (!buffer)
> + goto err_buffer;
> +
> + vdpasim = kzalloc(sizeof(*vdpasim), GFP_KERNEL);
> + if (!vdpasim)
> + goto err_alloc;
> +
> + vdpasim->buffer = buffer;
> + vdpasim->iommu = iommu;
> +
> + config = &vdpasim->config;
> + config->mtu = 1500;
> + config->status = VIRTIO_NET_S_LINK_UP;
> + eth_random_addr(config->mac);
> +
> + INIT_WORK(&vdpasim->work, vdpasim_work);
> + spin_lock_init(&vdpasim->lock);
> +
> + vringh_set_iotlb(&vdpasim->vqs[0].vring, vdpasim->iommu);
> + vringh_set_iotlb(&vdpasim->vqs[1].vring, vdpasim->iommu);
> +
> + dev = &vdpasim->dev;
> + dev->release = vdpasim_device_release;
> + dev->coherent_dma_mask = DMA_BIT_MASK(64);
> + set_dma_ops(dev, &vdpasim_dma_ops);
> + dev_set_name(dev, "%s", VDPASIM_NAME);
> +
> + ret = device_register(&vdpasim->dev);
> + if (ret)
> + goto err_init;
It is a bit weird to be creating this dummy parent, couldn't this be
done by just passing a NULL parent to vdpa_alloc_device, doing
set_dma_ops() on the vdpasim->vdpa->dev and setting dma_device to
vdpasim->vdpa->dev ?
> + vdpasim->vdpa = vdpa_alloc_device(dev, dev, &vdpasim_net_config_ops);
> + if (ret)
> + goto err_vdpa;
> + ret = vdpa_register_device(vdpasim->vdpa);
> + if (ret)
> + goto err_register;
> +
> + return vdpasim;
> +
> +err_register:
> + put_device(&vdpasim->vdpa->dev);
> +err_vdpa:
> + device_del(&vdpasim->dev);
> + goto err;
> +err_init:
> + put_device(&vdpasim->dev);
> + goto err;
If you do the vdmasim alloc first, and immediately do
device_initialize() then all the failure paths can do put_device
instead of having this ugly goto unwind split. Just check for
vdpasim->iommu == NULL during release.
> +static int __init vdpasim_dev_init(void)
> +{
> + vdpasim_dev = vdpasim_create();
> +
> + if (!IS_ERR(vdpasim_dev))
> + return 0;
> +
> + return PTR_ERR(vdpasim_dev);
> +}
> +
> +static int vdpasim_device_remove_cb(struct device *dev, void *data)
> +{
> + struct vdpa_device *vdpa = dev_to_vdpa(dev);
> +
> + vdpa_unregister_device(vdpa);
> +
> + return 0;
> +}
> +
> +static void __exit vdpasim_dev_exit(void)
> +{
> + device_for_each_child(&vdpasim_dev->dev, NULL,
> + vdpasim_device_remove_cb);
Why the loop? There is only one device, and it is in the global
varaible vdmasim_dev ?
Jason
^ permalink raw reply
* Re: 回复: [PATCH] drm/amdgpu: fix a bug NULL pointer dereference
From: Nirmoy @ 2020-02-20 15:15 UTC (permalink / raw)
To: amd-gfx
In-Reply-To: <DM6PR12MB39317F37CBE569725C00ABD284130@DM6PR12MB3931.namprd12.prod.outlook.com>
On 2/20/20 2:35 PM, Liu, Monk wrote:
> Sorry, my previous idea still leave RQ null, please check if below method works:
>
> 29 static struct drm_sched_rq *
> 130 drm_sched_entity_get_free_sched(struct drm_sched_entity *entity)
> 131 {
> 132 struct drm_sched_rq *rq = NULL;
> 133 unsigned int min_jobs = UINT_MAX, num_jobs;
> 134 int i;
>
> 135
> While (!mutex_trylock(....))
> Sleep()
We can't do that drm_sched_entity_get_free_sched is in another
module(drm scheduler) independent of amdgpu
> 136 for (i = 0; i < entity->num_rq_list; ++i) {
> 137 struct drm_gpu_scheduler *sched = entity->rq_list[i]->sched;
> 138
> 139 if (!entity->rq_list[i]->sched->ready) { //we take the gpu reset mutex lock, so now sched->ready won't be set to "not ready"
> 140 DRM_WARN("sched%s is not ready, skipping", sched->name);
> 141 continue;
> 142 }
> 143
> 144 num_jobs = atomic_read(&sched->num_jobs);
> 145 if (num_jobs < min_jobs) {
> 146 min_jobs = num_jobs;
> 147 rq = entity->rq_list[i];
> 148 }
> 149 }
>
> Mutex_unlock(...)
>
> 150
> 151 return rq;
> 152 }
>
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply
* Re: 5.4-stable request: 52e29e331070cd ('btrfs: don't set path->leave_spinning for truncate')
From: Holger Hoffstätte @ 2020-02-20 15:12 UTC (permalink / raw)
To: Sasha Levin; +Cc: stable@vger.kernel.org
In-Reply-To: <20200218161426.GM1734@sasha-vm>
Hi Sasha,
On 2/18/20 5:14 PM, Sasha Levin wrote:
> On Tue, Feb 18, 2020 at 01:01:40PM +0100, Holger Hoffstätte wrote:
>> Hi,
>>
>> I was just looking throught the current 5.4-stable queue and saw that
>> 28553fa992cb28 ('Btrfs: fix race between shrinking truncate and fiemap')
>> is queued. Upstream has a follow-up fix for this: 52e29e331070cd aka
>> 'btrfs: don't set path->leave_spinning for truncate'.
>>
>> Would be nice to get those in together. I only looked at 5.4, don't
>> know about other queues.
>
> Since that fix just hit upstream, I'm going to remove 28553fa992cb28
> from the queue now and work on getting both patches in the next release.
Thanks, but maybe wait until [1] has also hit mainline? It's another fix
for 28553fa992cb28.
thanks,
Holger
[1] https://patchwork.kernel.org/patch/11394171/
^ permalink raw reply
* Re: Questions about logic_pio
From: Jiaxun Yang @ 2020-02-20 15:12 UTC (permalink / raw)
To: John Garry
Cc: Wei Xu, bhelgaas, andyshevchenko, Arnd Bergmann, linux-kernel,
Linux Mips
In-Reply-To: <1ebf4461-eb37-ff58-1faf-dd24d83f85cf@huawei.com>
---- 在 星期四, 2020-02-20 22:23:57 John Garry <john.garry@huawei.com> 撰写 ----
> > Also Cc MIPS list to check other's opinions.
> >
> > Hi John.
> >
>
> Hi Jiaxun Yang,
>
> > Thanks for your kind explanation, however, I think this way is
> > violating how I/O ports supposed to work, at least in MIPS world.
>
> For a bit more history, please understand that the core PCI code was
> managing non-native IO port space in the same way before we added the
> logic PIO framework. The only real functional change here was that we
> introduced the indirect-io region within the IO port space, under
> CONFIG_INDIRECT_PIO.
I'm going to do more investigation. Thanks.
>
> >
> > > >>
> > > >> After dig into logic pio logic, I found that logic pio is trying to "allocate" an io_start
> > > >> for MMIO ranges, the allocation starts from 0x0. And later the io_start is used to calculate
> > > >> cpu_address. In my opinion, for direct MMIO access, logic_pio address should always
> > > >> equal to hw address,
> > >
> > > I'm not sure what you mean by simply the hw address.
> > >
> >
> > I meant hw_start should always equal to io_start.
> >
> >
> > MIPS have their own wrapped inl/outl functions,
>
> Can you please point me to these? I could not find them in arch/mips
They are built by __BUILD_IOPORT_PFX(bus, bwlq, type) macro.
Just using mips_io_port_base + offset to handle inl/outl, the same way PCI_IOBASE.
>
> I will also note that arch/mips/include/asm/io.h does not include
> asm-generic io.h today
Yes, and I'm attempting to take advantage of asm-generic.
>
> doing the samething with
> > PCI_IOBASE enabled one. I was just trying to use PCI_IOBASE instead.
> >
> > Originally, the I/O ports layout seems like this:
> >
> > 00000020-00000021 : pic1
> > 00000060-0000006f : i8042
> > 00000070-00000077 : rtc0
> > 000000a0-000000a1 : pic2
> > 00000170-00000177 : pata_atiixp
> > 000001f0-000001f7 : pata_atiixp
> > 00000376-00000376 : pata_atiixp
> > 000003f6-000003f6 : pata_atiixp
> > 00000800-000008ff : acpi
> > 00001000-00001008 : piix4_smbus
> > 00004000-0003ffff : pci io space
> > 00004000-00004fff : PCI Bus 0000:01
> > 00004000-000040ff : 0000:01:05.0
> > 00005000-00005fff : PCI Bus 0000:03
> > 00005000-0000501f : 0000:03:00.0
> >
> > But with PCI_IOBASE defined, I got this:
> >
> > host bridge /bus@10000000/pci@10000000 ranges:
> > MEM 0x0040000000..0x007fffffff -> 0x0040000000
> > IO 0x0000004000..0x0000007fff -> 0x0000004000
> > resource collision: [io 0x0000-0x3fff] conflicts with pic1 [io 0x0020-0x0021]
> >
> > Because io_start was allocated to 0x0 by Logic PIO.
> >
> > There are a lot of devices that have fixed ioports thanks to x86's legacy.
>
> Well, yes, I'm not so surprised.
>
> So if MIPS does not have native IO port access, then surely you need
> some host bridge to translate host CPU MMIO accesses to port I/O
> accesses, right? Where are these CPU addresses defined?
It is defined by the variable mips_io_port_base.
>
> > For example, in my hardware, ioports for RTC, PIC, I8042 are unmoveable,
> > and they can't be managed by logic pio subsystem. > Also, the PCI Hostbridge got implied by DeviceTree that it's I/O range
> > started from 0x4000 in bus side
>
> which bus is this?
They're all located under "ISA Range". Just an MMIO range that will resend
the request to ISA I/O. --ioports for both PCI and some legacy devices.
In that range, base + 0x0000 to 0x4000 is preserved for PIO devices (e.g.) I8259
and base + 0x4000 to MMIO_LIMIT are for PCI devices under host bridge.
For the host bridge, ioports it can decode starts from 0x4000.
My intentional behavior is that when I'm specifying in dts that the IO Range of PCI host
bridge is 0x4000 to 0x7fff, it would request the IO_RESOURCE start from 0x4000
to 0x7fff, also tell the host driver to decode 0x4000 to 0x7fff in IO BAR, And let the drivers
access 0x4000 to 0x7fff via inl/outl, rather than allocate from PIO 0x0 to 0x3fff.
>
> , but then, Logic PIO remapped to PCI_IOBASE + 0x0.
> > The real address should be PCI_IOBASE + 0x4000,
>
> You seem to be using two methods to manage IO port space, and they seem
> to be conflicting.
So... Are there any way to handle these unmoveable devices in logic pio world?
>
> > hardware never got correctly informed about that. And there is still no way to
> > transform to correct address as it's inside the MMIO_LIMIT.
> >
> > So the question comes to why we're allocating io_start for MMIO PCI_IOBASE
> > rather than just check the range provided doesn't overlap each other or exceed
> > the MMIO_LIMIT.
>
> When PCI_IOBASE is defined, we work on the basis that any IO port range
> in the system is registered for a logical PIO region, which manages the
> actual IO port addresses - see logic_pio_trans_cpuaddr().
The port is not the actual port.. It makes me confusing about what it's actually doing..
Sorry but probably I'm still thinking in a vintage way -- need some hints about how to
deal with these legacy cases in a modern way.
Thanks.
>
> Thanks,
> John
>
^ permalink raw reply
* [PATCH v2 1/3] Adding functions _send_fds and _recv_fds
From: Oksana Vohchana @ 2020-02-20 15:10 UTC (permalink / raw)
To: qemu-devel; +Cc: ovoshcha, philmd, ehabkost, wainersm, crosa
In-Reply-To: <20200220151039.20552-1-ovoshcha@redhat.com>
It provides new possibilities to send or receive data through the Unix domain
socket file descriptor.
This is useful for obtaining a socket that belongs to a different network
namespace.
Signed-off-by: Oksana Vohchana <ovoshcha@redhat.com>
---
python/qemu/machine.py | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 183d8f3d38..976316e5f5 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -24,6 +24,7 @@ import subprocess
import shutil
import socket
import tempfile
+import array
from . import qmp
@@ -155,6 +156,29 @@ class QEMUMachine(object):
self._args.append(','.join(options))
return self
+ def _recv_fds(self, sock, msglen=8192, maxfds=4096):
+ """
+ Function from:
+ https://docs.python.org/3/library/socket.html#socket.socket.recvmsg
+ """
+ fds = array.array("i")
+ msg, ancdata, flags, addr = sock.recvmsg(msglen, socket.CMSG_LEN(
+ maxfds * fds.itemsize))
+ for cmsg_level, cmsg_type, cmsg_data in ancdata:
+ if (cmsg_level == socket.SOL_SOCKET and
+ cmsg_type == socket.SCM_RIGHTS):
+ fds.frombytes(cmsg_data[:len(cmsg_data) - (len(cmsg_data)
+ % fds.itemsize)])
+ return msg, list(fds)
+
+ def _send_fds(self, sock, msg, fds):
+ """
+ Function from:
+ https://docs.python.org/3/library/socket.html#socket.socket.sendmsg
+ """
+ return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS,
+ array.array("i", fds))])
+
def send_fd_scm(self, fd=None, file_path=None):
"""
Send an fd or file_path to socket_scm_helper.
--
2.21.1
^ permalink raw reply related
* Re: [PATCH 2/4] Btrfs: simplify inline extent handling when doing reflinks
From: Josef Bacik @ 2020-02-20 15:13 UTC (permalink / raw)
To: fdmanana, linux-btrfs
In-Reply-To: <20200219140556.1641567-1-fdmanana@kernel.org>
On 2/19/20 9:05 AM, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> We can not reflink parts of an inline extent, we must always reflink the
> whole inline extent. We know that inline extents always start at file
> offset 0 and that can never represent an amount of data larger then the
> filesystem's sector size (both compressed and uncompressed). We also have
> had the constraints that reflink operations must have a start offset that
> is aligned to the sector size and an end offset that is also aligned or
> it ends the inode's i_size, so there's no way for user space to be able
> to do a reflink operation that will refer to only a part of an inline
> extent.
>
> Initially there was a bug in the inlining code that could allow compressed
> inline extents that encoded more than 1 page, but that was fixed in 2008
> by commit 70b99e6959a4c2 ("Btrfs: Compression corner fixes") since that
> was problematic.
>
> So remove all the extent cloning code that deals with the possibility
> of cloning only partial inline extents.
>
> Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Thanks,
Josef
^ permalink raw reply
* [PATCH v2 2/3] Updates send_fd_scm function
From: Oksana Vohchana @ 2020-02-20 15:10 UTC (permalink / raw)
To: qemu-devel; +Cc: ovoshcha, philmd, ehabkost, wainersm, crosa
In-Reply-To: <20200220151039.20552-1-ovoshcha@redhat.com>
A qemu-iotest uses for FD-migration test a helper program "socket_scm_helper".
And it makes some problems if you didn't build it with a QEMU. And now we can
use new methods for the socket that allow us to send a file/socket descriptor
(with access and permissions) from one process to another.
Signed-off-by: Oksana Vohchana <ovoshcha@redhat.com>
---
python/qemu/machine.py | 64 ++++++++++++++++++++++++++----------------
1 file changed, 40 insertions(+), 24 deletions(-)
diff --git a/python/qemu/machine.py b/python/qemu/machine.py
index 976316e5f5..906ca118db 100644
--- a/python/qemu/machine.py
+++ b/python/qemu/machine.py
@@ -179,20 +179,27 @@ class QEMUMachine(object):
return sock.sendmsg([msg], [(socket.SOL_SOCKET, socket.SCM_RIGHTS,
array.array("i", fds))])
- def send_fd_scm(self, fd=None, file_path=None):
+ def send_fd_scm(self, fd=None, file_path=None, data=None):
"""
- Send an fd or file_path to socket_scm_helper.
+ Can be used in two different cases.
+ Send an fd or file_path to socket_scm_helper or
+ provide data and fd to send it to the socket.
- Exactly one of fd and file_path must be given.
- If it is file_path, the helper will open that file and pass its own fd.
+ Exactly one of fd and file_path must be given to the case of
+ socket_scm_helper. If it is file_path, the helper will open that file
+ and pass its own fd.
+
+ To second case need adds data that include a QMP request and fd
"""
# In iotest.py, the qmp should always use unix socket.
assert self._qmp.is_scm_available()
- if self._socket_scm_helper is None:
- raise QEMUMachineError("No path to socket_scm_helper set")
- if not os.path.exists(self._socket_scm_helper):
- raise QEMUMachineError("%s does not exist" %
- self._socket_scm_helper)
+ if data is None:
+ if self._socket_scm_helper is None:
+ raise QEMUMachineError(
+ "No path to socket_scm_helper set or data provided")
+ if not os.path.exists(self._socket_scm_helper):
+ raise QEMUMachineError("%s does not exist" %
+ self._socket_scm_helper)
# This did not exist before 3.4, but since then it is
# mandatory for our purpose
@@ -201,24 +208,33 @@ class QEMUMachine(object):
if fd is not None:
os.set_inheritable(fd, True)
- fd_param = ["%s" % self._socket_scm_helper,
- "%d" % self._qmp.get_sock_fd()]
+ if data is None:
+ fd_param = ["%s" % self._socket_scm_helper,
+ "%d" % self._qmp.get_sock_fd()]
+ if file_path is not None:
+ assert fd is None
+ fd_param.append(file_path)
+ else:
+ assert fd is not None
+ fd_param.append(str(fd))
- if file_path is not None:
- assert fd is None
- fd_param.append(file_path)
- else:
- assert fd is not None
- fd_param.append(str(fd))
+ devnull = open(os.path.devnull, 'rb')
+ proc = subprocess.Popen(fd_param, stdin=devnull,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT, close_fds=False)
+ output = proc.communicate()[0]
+ if output:
+ LOG.debug(output)
- devnull = open(os.path.devnull, 'rb')
- proc = subprocess.Popen(fd_param, stdin=devnull, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT, close_fds=False)
- output = proc.communicate()[0]
- if output:
- LOG.debug(output)
+ return proc.returncode
- return proc.returncode
+ else:
+ sock_fd = socket.fromfd(self._qmp.get_sock_fd(), socket.AF_UNIX,
+ socket.SOCK_STREAM)
+ fds_param = [fd, self._qmp.get_sock_fd()]
+ self._send_fds(sock_fd, data, fds_param)
+ self._recv_fds(sock_fd)
+ return self
@staticmethod
def _remove_if_exists(path):
--
2.21.1
^ permalink raw reply related
* [PATCH 1/2] net: mdio: add ipq8064 mdio driver
From: Ansuel Smith @ 2020-02-20 15:12 UTC (permalink / raw)
Cc: Ansuel Smith, Andy Gross, Bjorn Andersson, David S. Miller,
Rob Herring, Mark Rutland, Andrew Lunn, Florian Fainelli,
Heiner Kallweit, Russell King, linux-arm-msm, netdev, devicetree,
linux-kernel
Currently ipq806x soc use generi bitbang driver to
comunicate with the gmac ethernet interface.
Add a dedicated driver created by chunkeey to fix this.
Christian Lamparter <chunkeey@gmail.com>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/phy/Kconfig | 8 ++
drivers/net/phy/Makefile | 1 +
drivers/net/phy/mdio-ipq8064.c | 163 +++++++++++++++++++++++++++++++++
3 files changed, 172 insertions(+)
create mode 100644 drivers/net/phy/mdio-ipq8064.c
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 9dabe03a668c..ec2a5493a7e8 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -157,6 +157,14 @@ config MDIO_I2C
This is library mode.
+config MDIO_IPQ8064
+ tristate "Qualcomm IPQ8064 MDIO interface support"
+ depends on HAS_IOMEM && OF_MDIO
+ depends on MFD_SYSCON
+ help
+ This driver supports the MDIO interface found in the network
+ interface units of the IPQ8064 SoC
+
config MDIO_MOXART
tristate "MOXA ART MDIO interface support"
depends on ARCH_MOXART || COMPILE_TEST
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index fe5badf13b65..8f02bd2089f3 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_MDIO_CAVIUM) += mdio-cavium.o
obj-$(CONFIG_MDIO_GPIO) += mdio-gpio.o
obj-$(CONFIG_MDIO_HISI_FEMAC) += mdio-hisi-femac.o
obj-$(CONFIG_MDIO_I2C) += mdio-i2c.o
+obj-$(CONFIG_MDIO_IPQ8064) += mdio-ipq8064.o
obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
diff --git a/drivers/net/phy/mdio-ipq8064.c b/drivers/net/phy/mdio-ipq8064.c
new file mode 100644
index 000000000000..c76e6a647787
--- /dev/null
+++ b/drivers/net/phy/mdio-ipq8064.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Qualcomm IPQ8064 MDIO interface driver
+//
+// Copyright (C) 2019 Christian Lamparter <chunkeey@gmail.com>
+
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/syscon.h>
+
+/* MII address register definitions */
+#define MII_ADDR_REG_ADDR 0x10
+#define MII_BUSY BIT(0)
+#define MII_WRITE BIT(1)
+#define MII_CLKRANGE_60_100M (0 << 2)
+#define MII_CLKRANGE_100_150M (1 << 2)
+#define MII_CLKRANGE_20_35M (2 << 2)
+#define MII_CLKRANGE_35_60M (3 << 2)
+#define MII_CLKRANGE_150_250M (4 << 2)
+#define MII_CLKRANGE_250_300M (5 << 2)
+#define MII_CLKRANGE_MASK GENMASK(4, 2)
+#define MII_REG_SHIFT 6
+#define MII_REG_MASK GENMASK(10, 6)
+#define MII_ADDR_SHIFT 11
+#define MII_ADDR_MASK GENMASK(15, 11)
+
+#define MII_DATA_REG_ADDR 0x14
+
+#define MII_MDIO_DELAY (1000)
+#define MII_MDIO_RETRY (10)
+
+struct ipq8064_mdio {
+ struct regmap *base; /* NSS_GMAC0_BASE */
+};
+
+static int
+ipq8064_mdio_wait_busy(struct ipq8064_mdio *priv)
+{
+ int i;
+
+ for (i = 0; i < MII_MDIO_RETRY; i++) {
+ unsigned int busy;
+
+ regmap_read(priv->base, MII_ADDR_REG_ADDR, &busy);
+ if (!(busy & MII_BUSY))
+ return 0;
+
+ udelay(MII_MDIO_DELAY);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int
+ipq8064_mdio_read(struct mii_bus *bus, int phy_addr, int reg_offset)
+{
+ struct ipq8064_mdio *priv = bus->priv;
+ u32 miiaddr = MII_BUSY | MII_CLKRANGE_250_300M;
+ u32 ret_val;
+ int err;
+
+ miiaddr |= ((phy_addr << MII_ADDR_SHIFT) & MII_ADDR_MASK) |
+ ((reg_offset << MII_REG_SHIFT) & MII_REG_MASK);
+
+ regmap_write(priv->base, MII_ADDR_REG_ADDR, miiaddr);
+ usleep_range(10, 20);
+
+ err = ipq8064_mdio_wait_busy(priv);
+ if (err)
+ return err;
+
+ regmap_read(priv->base, MII_DATA_REG_ADDR, &ret_val);
+ return (int)ret_val;
+}
+
+static int
+ipq8064_mdio_write(struct mii_bus *bus, int phy_addr, int reg_offset, u16 data)
+{
+ struct ipq8064_mdio *priv = bus->priv;
+ u32 miiaddr = MII_WRITE | MII_BUSY | MII_CLKRANGE_250_300M;
+
+ regmap_write(priv->base, MII_DATA_REG_ADDR, data);
+
+ miiaddr |= ((phy_addr << MII_ADDR_SHIFT) & MII_ADDR_MASK) |
+ ((reg_offset << MII_REG_SHIFT) & MII_REG_MASK);
+
+ regmap_write(priv->base, MII_ADDR_REG_ADDR, miiaddr);
+ usleep_range(10, 20);
+
+ return ipq8064_mdio_wait_busy(priv);
+}
+
+static int
+ipq8064_mdio_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct ipq8064_mdio *priv;
+ struct mii_bus *bus;
+ int ret;
+
+ bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(*priv));
+ if (!bus)
+ return -ENOMEM;
+
+ bus->name = "ipq8064_mdio_bus";
+ bus->read = ipq8064_mdio_read;
+ bus->write = ipq8064_mdio_write;
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev));
+ bus->parent = &pdev->dev;
+
+ priv = bus->priv;
+ priv->base = syscon_node_to_regmap(np);
+ if (IS_ERR_OR_NULL(priv->base)) {
+ priv->base = syscon_regmap_lookup_by_phandle(np, "master");
+ if (IS_ERR_OR_NULL(priv->base)) {
+ pr_err("master phandle not found\n");
+ return -EINVAL;
+ }
+ }
+
+ ret = of_mdiobus_register(bus, np);
+ if (ret)
+ return ret;
+
+ platform_set_drvdata(pdev, bus);
+ return 0;
+}
+
+static int
+ipq8064_mdio_remove(struct platform_device *pdev)
+{
+ struct mii_bus *bus = platform_get_drvdata(pdev);
+
+ mdiobus_unregister(bus);
+
+ return 0;
+}
+
+static const struct of_device_id ipq8064_mdio_dt_ids[] = {
+ { .compatible = "qcom,ipq8064-mdio" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, ipq8064_mdio_dt_ids);
+
+static struct platform_driver ipq8064_mdio_driver = {
+ .probe = ipq8064_mdio_probe,
+ .remove = ipq8064_mdio_remove,
+ .driver = {
+ .name = "ipq8064-mdio",
+ .of_match_table = ipq8064_mdio_dt_ids,
+ },
+};
+
+module_platform_driver(ipq8064_mdio_driver);
+
+MODULE_DESCRIPTION("Qualcomm IPQ8064 MDIO interface driver");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@gmail.com>");
+MODULE_LICENSE("GPL");
--
2.25.0
^ permalink raw reply related
* [PATCH 2/2] Documentation: devictree: Add ipq806x mdio bindings
From: Ansuel Smith @ 2020-02-20 15:12 UTC (permalink / raw)
Cc: Ansuel Smith, Andy Gross, Bjorn Andersson, David S. Miller,
Rob Herring, Mark Rutland, Andrew Lunn, Florian Fainelli,
Heiner Kallweit, Russell King, linux-arm-msm, netdev, devicetree,
linux-kernel
In-Reply-To: <20200220151301.10564-1-ansuelsmth@gmail.com>
Add documentations for ipq806x mdio driver.
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
.../bindings/net/qcom,ipq8064-mdio.yaml | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
diff --git a/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
new file mode 100644
index 000000000000..c5a21c0b5325
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/qcom,ipq8064-mdio.yaml
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/qcom,ipq8064-mdio.txt
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm ipq806x MDIO bus controller
+
+description: |+
+ The ipq806x soc have a MDIO dedicated controller that is
+ used to comunicate with the gmac phy conntected.
+ Child nodes of this MDIO bus controller node are standard
+ Ethernet PHY device nodes as described in
+ Documentation/devicetree/bindings/net/phy.txt
+
+allOf:
+ - $ref: "mdio.yaml#"
+
+properties:
+ compatible:
+ const: qcom,ipq8064-mdio
+ reg:
+ maxItems: 1
+ description: address and length of the register set for the device
+ clocks:
+ maxItems: 1
+ description: A reference to the clock supplying the MDIO bus controller
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - "#address-cells"
+ - "#size-cells"
+
+examples:
+ - |
+ mdio@37000000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,ipq8064-mdio", "syscon";
+ reg = <0x37000000 0x200000>;
+ resets = <&gcc GMAC_CORE1_RESET>;
+ reset-names = "stmmaceth";
+ clocks = <&gcc GMAC_CORE1_CLK>;
+
+ switch@10 {
+ compatible = "qca,qca8337";
+ ...
+ }
+ };
\ No newline at end of file
--
2.25.0
^ permalink raw reply related
* RE: [PATCH] drm/amdgpu: Add a chunk ID for spm trace
From: He, Jacob @ 2020-02-20 15:13 UTC (permalink / raw)
To: Koenig, Christian, amd-gfx@lists.freedesktop.org
In-Reply-To: <e2fea4f5-0eea-75b5-9cd7-68b603629d8d@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 9924 bytes --]
[AMD Official Use Only - Internal Distribution Only]
Hi Christian,
This patch is just for a simple scenario. Multiple SPM processes is not supported. That is saying, it’s not necessary to take MCBP or other complicated cases into account. UMD waits GPU idle right before enabling SPM trace. Serialization is made by UMD.
It’s not necessary to clear mmRLC_SPM_MC_CNTL also. For those spm disabled submission, mmRLC_SPM_MC_CNTL is useless. For those spm enabled submission, it will require KMD to update mmRLC_SPM_MC_CNTL.
Thanks
Jacob
From: Christian König<mailto:ckoenig.leichtzumerken@gmail.com>
Sent: Wednesday, February 19, 2020 7:02 PM
To: He, Jacob<mailto:Jacob.He@amd.com>; amd-gfx@lists.freedesktop.org<mailto:amd-gfx@lists.freedesktop.org>
Subject: Re: [PATCH] drm/amdgpu: Add a chunk ID for spm trace
Am 19.02.20 um 11:15 schrieb Jacob He:
> [WHY]
> When SPM trace enabled, SPM_VMID should be updated with the current
> vmid.
>
> [HOW]
> Add a chunk id, AMDGPU_CHUNK_ID_SPM_TRACE, so that UMD can tell us
> which job should update SPM_VMID.
> Right before a job is submitted to GPU, set the SPM_VMID accordingly.
>
> [Limitation]
> Running more than one SPM trace enabled processes simultaneously is
> not supported.
Well there are multiple problems with that patch.
First of all you need to better describe what SPM tracing is in the
commit message.
Then the updating of mmRLC_SPM_MC_CNTL must be executed asynchronously
on the ring. Otherwise we might corrupt an already executing SPM trace.
And you also need to make sure to disable the tracing again or otherwise
we run into a bunch of trouble when the VMID is reused.
You also need to make sure that IBs using the SPM trace are serialized
with each other, e.g. hack into amdgpu_ids.c file and make sure that
only one VMID at a time can have that attribute.
Regards,
Christian.
>
> Change-Id: Ic932ef6ac9dbf244f03aaee90550e8ff3a675666
> Signed-off-by: Jacob He <jacob.he@amd.com>
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 7 +++++++
> drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 10 +++++++---
> drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 1 +
> drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h | 1 +
> drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 15 ++++++++++++++-
> drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 3 ++-
> drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 3 ++-
> drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 15 ++++++++++++++-
> 8 files changed, 48 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> index f9fa6e104fef..3f32c4db5232 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
> @@ -113,6 +113,7 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
> uint32_t uf_offset = 0;
> int i;
> int ret;
> + bool update_spm_vmid = false;
>
> if (cs->in.num_chunks == 0)
> return 0;
> @@ -221,6 +222,10 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
> case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
> break;
>
> + case AMDGPU_CHUNK_ID_SPM_TRACE:
> + update_spm_vmid = true;
> + break;
> +
> default:
> ret = -EINVAL;
> goto free_partial_kdata;
> @@ -231,6 +236,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs
> if (ret)
> goto free_all_kdata;
>
> + p->job->need_update_spm_vmid = update_spm_vmid;
> +
> if (p->ctx->vram_lost_counter != p->job->vram_lost_counter) {
> ret = -ECANCELED;
> goto free_all_kdata;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> index cae81914c821..36faab12b585 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
> @@ -156,9 +156,13 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
> return -EINVAL;
> }
>
> - if (vm && !job->vmid) {
> - dev_err(adev->dev, "VM IB without ID\n");
> - return -EINVAL;
> + if (vm) {
> + if (!job->vmid) {
> + dev_err(adev->dev, "VM IB without ID\n");
> + return -EINVAL;
> + } else if (adev->gfx.rlc.funcs->update_spm_vmid && job->need_update_spm_vmid) {
> + adev->gfx.rlc.funcs->update_spm_vmid(adev, job->vmid);
> + }
> }
>
> alloc_size = ring->funcs->emit_frame_size + num_ibs *
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> index 2e2110dddb76..4582536961c7 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h
> @@ -52,6 +52,7 @@ struct amdgpu_job {
> bool vm_needs_flush;
> uint64_t vm_pd_addr;
> unsigned vmid;
> + bool need_update_spm_vmid;
> unsigned pasid;
> uint32_t gds_base, gds_size;
> uint32_t gws_base, gws_size;
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
> index d3d4707f2168..52509c254cbd 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_rlc.h
> @@ -126,6 +126,7 @@ struct amdgpu_rlc_funcs {
> void (*stop)(struct amdgpu_device *adev);
> void (*reset)(struct amdgpu_device *adev);
> void (*start)(struct amdgpu_device *adev);
> + void (*update_spm_vmid)(struct amdgpu_device *adev, unsigned vmid);
> };
>
> struct amdgpu_rlc {
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
> index 5e9fb0976c6c..91eb788d6229 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c
> @@ -4214,6 +4214,18 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev,
> return 0;
> }
>
> +static void gfx_v10_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid)
> +{
> + u32 data;
> +
> + data = RREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL);
> +
> + data &= ~RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK;
> + data |= (vmid & RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK) << RLC_SPM_MC_CNTL__RLC_SPM_VMID__SHIFT;
> +
> + WREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL, data);
> +}
> +
> static const struct amdgpu_rlc_funcs gfx_v10_0_rlc_funcs = {
> .is_rlc_enabled = gfx_v10_0_is_rlc_enabled,
> .set_safe_mode = gfx_v10_0_set_safe_mode,
> @@ -4224,7 +4236,8 @@ static const struct amdgpu_rlc_funcs gfx_v10_0_rlc_funcs = {
> .resume = gfx_v10_0_rlc_resume,
> .stop = gfx_v10_0_rlc_stop,
> .reset = gfx_v10_0_rlc_reset,
> - .start = gfx_v10_0_rlc_start
> + .start = gfx_v10_0_rlc_start,
> + .update_spm_vmid = gfx_v10_0_update_spm_vmid
> };
>
> static int gfx_v10_0_set_powergating_state(void *handle,
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> index 8f20a5dd44fe..b24fc55cf13a 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
> @@ -4221,7 +4221,8 @@ static const struct amdgpu_rlc_funcs gfx_v7_0_rlc_funcs = {
> .resume = gfx_v7_0_rlc_resume,
> .stop = gfx_v7_0_rlc_stop,
> .reset = gfx_v7_0_rlc_reset,
> - .start = gfx_v7_0_rlc_start
> + .start = gfx_v7_0_rlc_start,
> + .update_spm_vmid = NULL
> };
>
> static int gfx_v7_0_early_init(void *handle)
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> index fa245973de12..66640d2b6b37 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
> @@ -5600,7 +5600,8 @@ static const struct amdgpu_rlc_funcs iceland_rlc_funcs = {
> .resume = gfx_v8_0_rlc_resume,
> .stop = gfx_v8_0_rlc_stop,
> .reset = gfx_v8_0_rlc_reset,
> - .start = gfx_v8_0_rlc_start
> + .start = gfx_v8_0_rlc_start,
> + .update_spm_vmid = NULL
> };
>
> static void gfx_v8_0_update_medium_grain_clock_gating(struct amdgpu_device *adev,
> diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> index 9b7ff783e9a5..df872f949f68 100644
> --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
> @@ -4704,6 +4704,18 @@ static int gfx_v9_0_update_gfx_clock_gating(struct amdgpu_device *adev,
> return 0;
> }
>
> +static void gfx_v9_0_update_spm_vmid(struct amdgpu_device *adev, unsigned vmid)
> +{
> + u32 data;
> +
> + data = RREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL);
> +
> + data &= ~RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK;
> + data |= (vmid & RLC_SPM_MC_CNTL__RLC_SPM_VMID_MASK) << RLC_SPM_MC_CNTL__RLC_SPM_VMID__SHIFT;
> +
> + WREG32_SOC15(GC, 0, mmRLC_SPM_MC_CNTL, data);
> +}
> +
> static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = {
> .is_rlc_enabled = gfx_v9_0_is_rlc_enabled,
> .set_safe_mode = gfx_v9_0_set_safe_mode,
> @@ -4715,7 +4727,8 @@ static const struct amdgpu_rlc_funcs gfx_v9_0_rlc_funcs = {
> .resume = gfx_v9_0_rlc_resume,
> .stop = gfx_v9_0_rlc_stop,
> .reset = gfx_v9_0_rlc_reset,
> - .start = gfx_v9_0_rlc_start
> + .start = gfx_v9_0_rlc_start,
> + .update_spm_vmid = gfx_v9_0_update_spm_vmid
> };
>
> static int gfx_v9_0_set_powergating_state(void *handle,
[-- Attachment #1.2: Type: text/html, Size: 18875 bytes --]
[-- Attachment #2: Type: text/plain, Size: 154 bytes --]
_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx
^ permalink raw reply
* [PATCH v2 0/2] Migrate QRTR Nameservice to Kernel
From: Manivannan Sadhasivam @ 2020-02-20 15:13 UTC (permalink / raw)
To: davem, kuba
Cc: bjorn.andersson, netdev, linux-kernel, kvalo,
Manivannan Sadhasivam
Hello,
This patchset migrates the Qualcomm IPC Router (QRTR) Nameservice from userspace
to kernel under net/qrtr.
The userspace implementation of it can be found here:
https://github.com/andersson/qrtr/blob/master/src/ns.c
This change is required for enabling the WiFi functionality of some Qualcomm
WLAN devices using ATH11K without any dependency on a userspace daemon. Since
the QRTR NS is not usually packed in most of the distros, users need to clone,
build and install it to get the WiFi working. It will become a hassle when the
user doesn't have any other source of network connectivity.
The original userspace code is published under BSD3 license. For migrating it
to Linux kernel, I have adapted Dual BSD/GPL license.
This patchset has been verified on Dragonboard410c and Intel NUC with QCA6390
WLAN device.
Thanks,
Mani
Changes in v2:
* Sorted the local variables in reverse XMAS tree order
Manivannan Sadhasivam (2):
net: qrtr: Migrate nameservice to kernel from userspace
net: qrtr: Fix the local node ID as 1
net/qrtr/Makefile | 2 +-
net/qrtr/ns.c | 751 ++++++++++++++++++++++++++++++++++++++++++++++
net/qrtr/qrtr.c | 51 +---
net/qrtr/qrtr.h | 4 +
4 files changed, 767 insertions(+), 41 deletions(-)
create mode 100644 net/qrtr/ns.c
--
2.17.1
^ permalink raw reply
* [PATCH v2 1/2] net: qrtr: Migrate nameservice to kernel from userspace
From: Manivannan Sadhasivam @ 2020-02-20 15:13 UTC (permalink / raw)
To: davem, kuba
Cc: bjorn.andersson, netdev, linux-kernel, kvalo,
Manivannan Sadhasivam
In-Reply-To: <20200220151327.4823-1-manivannan.sadhasivam@linaro.org>
The QRTR nameservice has been maintained in userspace for some time. This
commit migrates it to Linux kernel. This change is required in order to
eliminate the need of starting a userspace daemon for making the WiFi
functional for ath11k based devices. Since the QRTR NS is not usually
packed in most of the distros, users need to clone, build and install it
to get the WiFi working. It will become a hassle when the user doesn't
have any other source of network connectivity.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
net/qrtr/Makefile | 2 +-
net/qrtr/ns.c | 751 ++++++++++++++++++++++++++++++++++++++++++++++
net/qrtr/qrtr.c | 48 +--
net/qrtr/qrtr.h | 4 +
4 files changed, 766 insertions(+), 39 deletions(-)
create mode 100644 net/qrtr/ns.c
diff --git a/net/qrtr/Makefile b/net/qrtr/Makefile
index 1c6d6c120fb7..32d4e923925d 100644
--- a/net/qrtr/Makefile
+++ b/net/qrtr/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_QRTR) := qrtr.o
+obj-$(CONFIG_QRTR) := qrtr.o ns.o
obj-$(CONFIG_QRTR_SMD) += qrtr-smd.o
qrtr-smd-y := smd.o
diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c
new file mode 100644
index 000000000000..67a4e59cdf4d
--- /dev/null
+++ b/net/qrtr/ns.c
@@ -0,0 +1,751 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (c) 2015, Sony Mobile Communications Inc.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2020, Linaro Ltd.
+ */
+
+#include <linux/module.h>
+#include <linux/qrtr.h>
+#include <linux/workqueue.h>
+#include <net/sock.h>
+
+#include "qrtr.h"
+
+static RADIX_TREE(nodes, GFP_KERNEL);
+
+static struct {
+ struct socket *sock;
+ struct sockaddr_qrtr bcast_sq;
+ struct list_head lookups;
+ struct workqueue_struct *workqueue;
+ struct work_struct work;
+ int local_node;
+} qrtr_ns;
+
+static const char * const qrtr_ctrl_pkt_strings[] = {
+ [QRTR_TYPE_HELLO] = "hello",
+ [QRTR_TYPE_BYE] = "bye",
+ [QRTR_TYPE_NEW_SERVER] = "new-server",
+ [QRTR_TYPE_DEL_SERVER] = "del-server",
+ [QRTR_TYPE_DEL_CLIENT] = "del-client",
+ [QRTR_TYPE_RESUME_TX] = "resume-tx",
+ [QRTR_TYPE_EXIT] = "exit",
+ [QRTR_TYPE_PING] = "ping",
+ [QRTR_TYPE_NEW_LOOKUP] = "new-lookup",
+ [QRTR_TYPE_DEL_LOOKUP] = "del-lookup",
+};
+
+struct qrtr_server_filter {
+ unsigned int service;
+ unsigned int instance;
+ unsigned int ifilter;
+};
+
+struct qrtr_lookup {
+ unsigned int service;
+ unsigned int instance;
+
+ struct sockaddr_qrtr sq;
+ struct list_head li;
+};
+
+struct qrtr_server {
+ unsigned int service;
+ unsigned int instance;
+
+ unsigned int node;
+ unsigned int port;
+
+ struct list_head qli;
+};
+
+struct qrtr_node {
+ unsigned int id;
+ struct radix_tree_root servers;
+};
+
+static struct qrtr_node *node_get(unsigned int node_id)
+{
+ struct qrtr_node *node;
+
+ node = radix_tree_lookup(&nodes, node_id);
+ if (node)
+ return node;
+
+ /* If node didn't exist, allocate and insert it to the tree */
+ node = kzalloc(sizeof(*node), GFP_KERNEL);
+ if (!node)
+ return ERR_PTR(-ENOMEM);
+
+ node->id = node_id;
+
+ radix_tree_insert(&nodes, node_id, node);
+
+ return node;
+}
+
+static int server_match(const struct qrtr_server *srv,
+ const struct qrtr_server_filter *f)
+{
+ unsigned int ifilter = f->ifilter;
+
+ if (f->service != 0 && srv->service != f->service)
+ return 0;
+ if (!ifilter && f->instance)
+ ifilter = ~0;
+
+ return (srv->instance & ifilter) == f->instance;
+}
+
+static int service_announce_new(struct sockaddr_qrtr *dest,
+ struct qrtr_server *srv)
+{
+ struct qrtr_ctrl_pkt pkt;
+ struct msghdr msg = { };
+ struct kvec iv;
+
+ trace_printk("advertising new server [%d:%x]@[%d:%d]\n",
+ srv->service, srv->instance, srv->node, srv->port);
+
+ iv.iov_base = &pkt;
+ iv.iov_len = sizeof(pkt);
+
+ memset(&pkt, 0, sizeof(pkt));
+ pkt.cmd = cpu_to_le32(QRTR_TYPE_NEW_SERVER);
+ pkt.server.service = cpu_to_le32(srv->service);
+ pkt.server.instance = cpu_to_le32(srv->instance);
+ pkt.server.node = cpu_to_le32(srv->node);
+ pkt.server.port = cpu_to_le32(srv->port);
+
+ msg.msg_name = (struct sockaddr *)dest;
+ msg.msg_namelen = sizeof(*dest);
+
+ return kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
+}
+
+static int service_announce_del(struct sockaddr_qrtr *dest,
+ struct qrtr_server *srv)
+{
+ struct qrtr_ctrl_pkt pkt;
+ struct msghdr msg = { };
+ struct kvec iv;
+ int ret;
+
+ trace_printk("advertising removal of server [%d:%x]@[%d:%d]\n",
+ srv->service, srv->instance, srv->node, srv->port);
+
+ iv.iov_base = &pkt;
+ iv.iov_len = sizeof(pkt);
+
+ memset(&pkt, 0, sizeof(pkt));
+ pkt.cmd = cpu_to_le32(QRTR_TYPE_DEL_SERVER);
+ pkt.server.service = cpu_to_le32(srv->service);
+ pkt.server.instance = cpu_to_le32(srv->instance);
+ pkt.server.node = cpu_to_le32(srv->node);
+ pkt.server.port = cpu_to_le32(srv->port);
+
+ msg.msg_name = (struct sockaddr *)dest;
+ msg.msg_namelen = sizeof(*dest);
+
+ ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
+ if (ret < 0)
+ pr_err("failed to announce del serivce\n");
+
+ return ret;
+}
+
+static void lookup_notify(struct sockaddr_qrtr *to, struct qrtr_server *srv,
+ bool new)
+{
+ struct qrtr_ctrl_pkt pkt;
+ struct msghdr msg = { };
+ struct kvec iv;
+ int ret;
+
+ iv.iov_base = &pkt;
+ iv.iov_len = sizeof(pkt);
+
+ memset(&pkt, 0, sizeof(pkt));
+ pkt.cmd = new ? cpu_to_le32(QRTR_TYPE_NEW_SERVER) :
+ cpu_to_le32(QRTR_TYPE_DEL_SERVER);
+ if (srv) {
+ pkt.server.service = cpu_to_le32(srv->service);
+ pkt.server.instance = cpu_to_le32(srv->instance);
+ pkt.server.node = cpu_to_le32(srv->node);
+ pkt.server.port = cpu_to_le32(srv->port);
+ }
+
+ msg.msg_name = (struct sockaddr *)to;
+ msg.msg_namelen = sizeof(*to);
+
+ ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
+ if (ret < 0)
+ pr_err("failed to send lookup notification\n");
+}
+
+static int announce_servers(struct sockaddr_qrtr *sq)
+{
+ struct radix_tree_iter iter;
+ struct qrtr_server *srv;
+ struct qrtr_node *node;
+ void __rcu **slot;
+ int ret;
+
+ node = node_get(qrtr_ns.local_node);
+ if (!node)
+ return 0;
+
+ /* Announce the list of servers registered in this node */
+ radix_tree_for_each_slot(slot, &node->servers, &iter, 0) {
+ srv = radix_tree_deref_slot(slot);
+
+ ret = service_announce_new(sq, srv);
+ if (ret < 0) {
+ pr_err("failed to announce new service\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static struct qrtr_server *server_add(unsigned int service,
+ unsigned int instance,
+ unsigned int node_id,
+ unsigned int port)
+{
+ struct qrtr_server *srv;
+ struct qrtr_server *old;
+ struct qrtr_node *node;
+
+ if (!service || !port)
+ return NULL;
+
+ srv = kzalloc(sizeof(*srv), GFP_KERNEL);
+ if (!srv)
+ return ERR_PTR(-ENOMEM);
+
+ srv->service = service;
+ srv->instance = instance;
+ srv->node = node_id;
+ srv->port = port;
+
+ node = node_get(node_id);
+ if (!node)
+ goto err;
+
+ /* Delete the old server on the same port */
+ old = radix_tree_lookup(&node->servers, port);
+ if (old) {
+ radix_tree_delete(&node->servers, port);
+ kfree(old);
+ }
+
+ radix_tree_insert(&node->servers, port, srv);
+
+ trace_printk("add server [%d:%x]@[%d:%d]\n", srv->service,
+ srv->instance, srv->node, srv->port);
+
+ return srv;
+
+err:
+ kfree(srv);
+ return NULL;
+}
+
+static int server_del(struct qrtr_node *node, unsigned int port)
+{
+ struct qrtr_lookup *lookup;
+ struct qrtr_server *srv;
+ struct list_head *li;
+
+ srv = radix_tree_lookup(&node->servers, port);
+ if (!srv)
+ return -ENOENT;
+
+ radix_tree_delete(&node->servers, port);
+
+ /* Broadcast the removal of local servers */
+ if (srv->node == qrtr_ns.local_node)
+ service_announce_del(&qrtr_ns.bcast_sq, srv);
+
+ /* Announce the service's disappearance to observers */
+ list_for_each(li, &qrtr_ns.lookups) {
+ lookup = container_of(li, struct qrtr_lookup, li);
+ if (lookup->service && lookup->service != srv->service)
+ continue;
+ if (lookup->instance && lookup->instance != srv->instance)
+ continue;
+
+ lookup_notify(&lookup->sq, srv, false);
+ }
+
+ kfree(srv);
+
+ return 0;
+}
+
+/* Announce the list of servers registered on the local node */
+static int ctrl_cmd_hello(struct sockaddr_qrtr *sq)
+{
+ return announce_servers(sq);
+}
+
+static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
+{
+ struct qrtr_node *local_node;
+ struct radix_tree_iter iter;
+ struct qrtr_ctrl_pkt pkt;
+ struct qrtr_server *srv;
+ struct sockaddr_qrtr sq;
+ struct msghdr msg = { };
+ struct qrtr_node *node;
+ void __rcu **slot;
+ struct kvec iv;
+ int ret;
+
+ iv.iov_base = &pkt;
+ iv.iov_len = sizeof(pkt);
+
+ node = node_get(from->sq_node);
+ if (!node)
+ return 0;
+
+ /* Advertise removal of this client to all servers of remote node */
+ radix_tree_for_each_slot(slot, &node->servers, &iter, 0) {
+ srv = radix_tree_deref_slot(slot);
+ server_del(node, srv->port);
+ }
+
+ /* Advertise the removal of this client to all local servers */
+ local_node = node_get(qrtr_ns.local_node);
+ if (!local_node)
+ return 0;
+
+ memset(&pkt, 0, sizeof(pkt));
+ pkt.cmd = cpu_to_le32(QRTR_TYPE_BYE);
+ pkt.client.node = cpu_to_le32(from->sq_node);
+
+ radix_tree_for_each_slot(slot, &local_node->servers, &iter, 0) {
+ srv = radix_tree_deref_slot(slot);
+
+ sq.sq_family = AF_QIPCRTR;
+ sq.sq_node = srv->node;
+ sq.sq_port = srv->port;
+
+ msg.msg_name = (struct sockaddr *)&sq;
+ msg.msg_namelen = sizeof(sq);
+
+ ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
+ if (ret < 0) {
+ pr_err("failed to send bye cmd\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
+ unsigned int node_id, unsigned int port)
+{
+ struct qrtr_node *local_node;
+ struct radix_tree_iter iter;
+ struct qrtr_lookup *lookup;
+ struct qrtr_ctrl_pkt pkt;
+ struct msghdr msg = { };
+ struct qrtr_server *srv;
+ struct sockaddr_qrtr sq;
+ struct qrtr_node *node;
+ struct list_head *tmp;
+ struct list_head *li;
+ void __rcu **slot;
+ struct kvec iv;
+ int ret;
+
+ iv.iov_base = &pkt;
+ iv.iov_len = sizeof(pkt);
+
+ /* Don't accept spoofed messages */
+ if (from->sq_node != node_id)
+ return -EINVAL;
+
+ /* Local DEL_CLIENT messages comes from the port being closed */
+ if (from->sq_node == qrtr_ns.local_node && from->sq_port != port)
+ return -EINVAL;
+
+ /* Remove any lookups by this client */
+ list_for_each_safe(li, tmp, &qrtr_ns.lookups) {
+ lookup = container_of(li, struct qrtr_lookup, li);
+ if (lookup->sq.sq_node != node_id)
+ continue;
+ if (lookup->sq.sq_port != port)
+ continue;
+
+ list_del(&lookup->li);
+ kfree(lookup);
+ }
+
+ /* Remove the server belonging to this port */
+ node = node_get(node_id);
+ if (node)
+ server_del(node, port);
+
+ /* Advertise the removal of this client to all local servers */
+ local_node = node_get(qrtr_ns.local_node);
+ if (!local_node)
+ return 0;
+
+ memset(&pkt, 0, sizeof(pkt));
+ pkt.cmd = cpu_to_le32(QRTR_TYPE_DEL_CLIENT);
+ pkt.client.node = cpu_to_le32(node_id);
+ pkt.client.port = cpu_to_le32(port);
+
+ radix_tree_for_each_slot(slot, &local_node->servers, &iter, 0) {
+ srv = radix_tree_deref_slot(slot);
+
+ sq.sq_family = AF_QIPCRTR;
+ sq.sq_node = srv->node;
+ sq.sq_port = srv->port;
+
+ msg.msg_name = (struct sockaddr *)&sq;
+ msg.msg_namelen = sizeof(sq);
+
+ ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
+ if (ret < 0) {
+ pr_err("failed to send del client cmd\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int ctrl_cmd_new_server(struct sockaddr_qrtr *from,
+ unsigned int service, unsigned int instance,
+ unsigned int node_id, unsigned int port)
+{
+ struct qrtr_lookup *lookup;
+ struct qrtr_server *srv;
+ struct list_head *li;
+ int ret = 0;
+
+ /* Ignore specified node and port for local servers */
+ if (from->sq_node == qrtr_ns.local_node) {
+ node_id = from->sq_node;
+ port = from->sq_port;
+ }
+
+ /* Don't accept spoofed messages */
+ if (from->sq_node != node_id)
+ return -EINVAL;
+
+ srv = server_add(service, instance, node_id, port);
+ if (!srv)
+ return -EINVAL;
+
+ if (srv->node == qrtr_ns.local_node) {
+ ret = service_announce_new(&qrtr_ns.bcast_sq, srv);
+ if (ret < 0) {
+ pr_err("failed to announce new service\n");
+ return ret;
+ }
+ }
+
+ /* Notify any potential lookups about the new server */
+ list_for_each(li, &qrtr_ns.lookups) {
+ lookup = container_of(li, struct qrtr_lookup, li);
+ if (lookup->service && lookup->service != service)
+ continue;
+ if (lookup->instance && lookup->instance != instance)
+ continue;
+
+ lookup_notify(&lookup->sq, srv, true);
+ }
+
+ return ret;
+}
+
+static int ctrl_cmd_del_server(struct sockaddr_qrtr *from,
+ unsigned int service, unsigned int instance,
+ unsigned int node_id, unsigned int port)
+{
+ struct qrtr_node *node;
+
+ /* Ignore specified node and port for local servers*/
+ if (from->sq_node == qrtr_ns.local_node) {
+ node_id = from->sq_node;
+ port = from->sq_port;
+ }
+
+ /* Don't accept spoofed messages */
+ if (from->sq_node != node_id)
+ return -EINVAL;
+
+ /* Local servers may only unregister themselves */
+ if (from->sq_node == qrtr_ns.local_node && from->sq_port != port)
+ return -EINVAL;
+
+ node = node_get(node_id);
+ if (!node)
+ return -ENOENT;
+
+ return server_del(node, port);
+}
+
+static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
+ unsigned int service, unsigned int instance)
+{
+ struct radix_tree_iter node_iter;
+ struct qrtr_server_filter filter;
+ struct radix_tree_iter srv_iter;
+ struct qrtr_lookup *lookup;
+ struct qrtr_node *node;
+ void __rcu **node_slot;
+ void __rcu **srv_slot;
+
+ /* Accept only local observers */
+ if (from->sq_node != qrtr_ns.local_node)
+ return -EINVAL;
+
+ lookup = kzalloc(sizeof(*lookup), GFP_KERNEL);
+ if (!lookup)
+ return -ENOMEM;
+
+ lookup->sq = *from;
+ lookup->service = service;
+ lookup->instance = instance;
+ list_add_tail(&lookup->li, &qrtr_ns.lookups);
+
+ memset(&filter, 0, sizeof(filter));
+ filter.service = service;
+ filter.instance = instance;
+
+ radix_tree_for_each_slot(node_slot, &nodes, &node_iter, 0) {
+ node = radix_tree_deref_slot(node_slot);
+
+ radix_tree_for_each_slot(srv_slot, &node->servers,
+ &srv_iter, 0) {
+ struct qrtr_server *srv;
+
+ srv = radix_tree_deref_slot(srv_slot);
+ if (!server_match(srv, &filter))
+ continue;
+
+ lookup_notify(from, srv, true);
+ }
+ }
+
+ /* Empty notification, to indicate end of listing */
+ lookup_notify(from, NULL, true);
+
+ return 0;
+}
+
+static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from,
+ unsigned int service, unsigned int instance)
+{
+ struct qrtr_lookup *lookup;
+ struct list_head *tmp;
+ struct list_head *li;
+
+ list_for_each_safe(li, tmp, &qrtr_ns.lookups) {
+ lookup = container_of(li, struct qrtr_lookup, li);
+ if (lookup->sq.sq_node != from->sq_node)
+ continue;
+ if (lookup->sq.sq_port != from->sq_port)
+ continue;
+ if (lookup->service != service)
+ continue;
+ if (lookup->instance && lookup->instance != instance)
+ continue;
+
+ list_del(&lookup->li);
+ kfree(lookup);
+ }
+}
+
+static int say_hello(void)
+{
+ struct qrtr_ctrl_pkt pkt;
+ struct msghdr msg = { };
+ struct kvec iv;
+ int ret;
+
+ iv.iov_base = &pkt;
+ iv.iov_len = sizeof(pkt);
+
+ memset(&pkt, 0, sizeof(pkt));
+ pkt.cmd = cpu_to_le32(QRTR_TYPE_HELLO);
+
+ msg.msg_name = (struct sockaddr *)&qrtr_ns.bcast_sq;
+ msg.msg_namelen = sizeof(qrtr_ns.bcast_sq);
+
+ ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
+ if (ret < 0)
+ pr_err("failed to send hello msg\n");
+
+ return ret;
+}
+
+static void qrtr_ns_worker(struct work_struct *work)
+{
+ const struct qrtr_ctrl_pkt *pkt;
+ size_t recv_buf_size = 4096;
+ struct sockaddr_qrtr sq;
+ struct msghdr msg = { };
+ unsigned int cmd;
+ ssize_t msglen;
+ void *recv_buf;
+ struct kvec iv;
+ int ret;
+
+ msg.msg_name = (struct sockaddr *)&sq;
+ msg.msg_namelen = sizeof(sq);
+
+ recv_buf = kzalloc(recv_buf_size, GFP_KERNEL);
+ if (!recv_buf)
+ return;
+
+ for (;;) {
+ iv.iov_base = recv_buf;
+ iv.iov_len = recv_buf_size;
+
+ msglen = kernel_recvmsg(qrtr_ns.sock, &msg, &iv, 1,
+ iv.iov_len, MSG_DONTWAIT);
+
+ if (msglen == -EAGAIN)
+ break;
+
+ if (msglen < 0) {
+ pr_err("error receiving packet: %zd\n", msglen);
+ break;
+ }
+
+ pkt = recv_buf;
+ cmd = le32_to_cpu(pkt->cmd);
+ if (cmd < ARRAY_SIZE(qrtr_ctrl_pkt_strings) &&
+ qrtr_ctrl_pkt_strings[cmd])
+ trace_printk("%s from %d:%d\n",
+ qrtr_ctrl_pkt_strings[cmd], sq.sq_node,
+ sq.sq_port);
+
+ ret = 0;
+ switch (cmd) {
+ case QRTR_TYPE_HELLO:
+ ret = ctrl_cmd_hello(&sq);
+ break;
+ case QRTR_TYPE_BYE:
+ ret = ctrl_cmd_bye(&sq);
+ break;
+ case QRTR_TYPE_DEL_CLIENT:
+ ret = ctrl_cmd_del_client(&sq,
+ le32_to_cpu(pkt->client.node),
+ le32_to_cpu(pkt->client.port));
+ break;
+ case QRTR_TYPE_NEW_SERVER:
+ ret = ctrl_cmd_new_server(&sq,
+ le32_to_cpu(pkt->server.service),
+ le32_to_cpu(pkt->server.instance),
+ le32_to_cpu(pkt->server.node),
+ le32_to_cpu(pkt->server.port));
+ break;
+ case QRTR_TYPE_DEL_SERVER:
+ ret = ctrl_cmd_del_server(&sq,
+ le32_to_cpu(pkt->server.service),
+ le32_to_cpu(pkt->server.instance),
+ le32_to_cpu(pkt->server.node),
+ le32_to_cpu(pkt->server.port));
+ break;
+ case QRTR_TYPE_EXIT:
+ case QRTR_TYPE_PING:
+ case QRTR_TYPE_RESUME_TX:
+ break;
+ case QRTR_TYPE_NEW_LOOKUP:
+ ret = ctrl_cmd_new_lookup(&sq,
+ le32_to_cpu(pkt->server.service),
+ le32_to_cpu(pkt->server.instance));
+ break;
+ case QRTR_TYPE_DEL_LOOKUP:
+ ctrl_cmd_del_lookup(&sq,
+ le32_to_cpu(pkt->server.service),
+ le32_to_cpu(pkt->server.instance));
+ break;
+ }
+
+ if (ret < 0)
+ pr_err("failed while handling packet from %d:%d",
+ sq.sq_node, sq.sq_port);
+ }
+
+ kfree(recv_buf);
+}
+
+static void qrtr_ns_data_ready(struct sock *sk)
+{
+ queue_work(qrtr_ns.workqueue, &qrtr_ns.work);
+}
+
+void qrtr_ns_init(struct work_struct *work)
+{
+ struct sockaddr_qrtr sq;
+ int ret;
+
+ INIT_LIST_HEAD(&qrtr_ns.lookups);
+ INIT_WORK(&qrtr_ns.work, qrtr_ns_worker);
+
+ ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM,
+ PF_QIPCRTR, &qrtr_ns.sock);
+ if (ret < 0)
+ return;
+
+ ret = kernel_getsockname(qrtr_ns.sock, (struct sockaddr *)&sq);
+ if (ret < 0) {
+ pr_err("failed to get socket name\n");
+ goto err_sock;
+ }
+
+ qrtr_ns.sock->sk->sk_data_ready = qrtr_ns_data_ready;
+
+ sq.sq_port = QRTR_PORT_CTRL;
+ qrtr_ns.local_node = sq.sq_node;
+
+ ret = kernel_bind(qrtr_ns.sock, (struct sockaddr *)&sq, sizeof(sq));
+ if (ret < 0) {
+ pr_err("failed to bind to socket\n");
+ goto err_sock;
+ }
+
+ qrtr_ns.bcast_sq.sq_family = AF_QIPCRTR;
+ qrtr_ns.bcast_sq.sq_node = QRTR_NODE_BCAST;
+ qrtr_ns.bcast_sq.sq_port = QRTR_PORT_CTRL;
+
+ qrtr_ns.workqueue = alloc_workqueue("qrtr_ns_handler", WQ_UNBOUND, 1);
+ if (!qrtr_ns.workqueue)
+ goto err_sock;
+
+ ret = say_hello();
+ if (ret < 0)
+ goto err_wq;
+
+ return;
+
+err_wq:
+ destroy_workqueue(qrtr_ns.workqueue);
+err_sock:
+ sock_release(qrtr_ns.sock);
+}
+EXPORT_SYMBOL_GPL(qrtr_ns_init);
+
+void qrtr_ns_remove(void)
+{
+ cancel_work_sync(&qrtr_ns.work);
+ destroy_workqueue(qrtr_ns.workqueue);
+ sock_release(qrtr_ns.sock);
+}
+EXPORT_SYMBOL_GPL(qrtr_ns_remove);
+
+MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
+MODULE_DESCRIPTION("Qualcomm IPC Router Nameservice");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index 5a8e42ad1504..c758383ba866 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -10,6 +10,7 @@
#include <linux/numa.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <net/sock.h>
@@ -110,6 +111,8 @@ static DEFINE_MUTEX(qrtr_node_lock);
static DEFINE_IDR(qrtr_ports);
static DEFINE_MUTEX(qrtr_port_lock);
+static struct delayed_work qrtr_ns_work;
+
/**
* struct qrtr_node - endpoint node
* @ep_lock: lock for endpoint management and callbacks
@@ -1241,38 +1244,6 @@ static int qrtr_create(struct net *net, struct socket *sock,
return 0;
}
-static const struct nla_policy qrtr_policy[IFA_MAX + 1] = {
- [IFA_LOCAL] = { .type = NLA_U32 },
-};
-
-static int qrtr_addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct netlink_ext_ack *extack)
-{
- struct nlattr *tb[IFA_MAX + 1];
- struct ifaddrmsg *ifm;
- int rc;
-
- if (!netlink_capable(skb, CAP_NET_ADMIN))
- return -EPERM;
-
- if (!netlink_capable(skb, CAP_SYS_ADMIN))
- return -EPERM;
-
- ASSERT_RTNL();
-
- rc = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFA_MAX,
- qrtr_policy, extack);
- if (rc < 0)
- return rc;
-
- ifm = nlmsg_data(nlh);
- if (!tb[IFA_LOCAL])
- return -EINVAL;
-
- qrtr_local_nid = nla_get_u32(tb[IFA_LOCAL]);
- return 0;
-}
-
static const struct net_proto_family qrtr_family = {
.owner = THIS_MODULE,
.family = AF_QIPCRTR,
@@ -1293,11 +1264,11 @@ static int __init qrtr_proto_init(void)
return rc;
}
- rc = rtnl_register_module(THIS_MODULE, PF_QIPCRTR, RTM_NEWADDR, qrtr_addr_doit, NULL, 0);
- if (rc) {
- sock_unregister(qrtr_family.family);
- proto_unregister(&qrtr_proto);
- }
+ /* FIXME: Currently, this 2s delay is required to catch the NEW_SERVER
+ * messages from routers. But the fix could be somewhere else.
+ */
+ INIT_DELAYED_WORK(&qrtr_ns_work, qrtr_ns_init);
+ schedule_delayed_work(&qrtr_ns_work, msecs_to_jiffies(2000));
return rc;
}
@@ -1305,7 +1276,8 @@ postcore_initcall(qrtr_proto_init);
static void __exit qrtr_proto_fini(void)
{
- rtnl_unregister(PF_QIPCRTR, RTM_NEWADDR);
+ cancel_delayed_work_sync(&qrtr_ns_work);
+ qrtr_ns_remove();
sock_unregister(qrtr_family.family);
proto_unregister(&qrtr_proto);
}
diff --git a/net/qrtr/qrtr.h b/net/qrtr/qrtr.h
index b81e6953c04b..53a237a28971 100644
--- a/net/qrtr/qrtr.h
+++ b/net/qrtr/qrtr.h
@@ -29,4 +29,8 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep);
int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len);
+void qrtr_ns_init(struct work_struct *work);
+
+void qrtr_ns_remove(void);
+
#endif
--
2.17.1
^ permalink raw reply related
* [PATCH v2 2/2] net: qrtr: Fix the local node ID as 1
From: Manivannan Sadhasivam @ 2020-02-20 15:13 UTC (permalink / raw)
To: davem, kuba
Cc: bjorn.andersson, netdev, linux-kernel, kvalo,
Manivannan Sadhasivam
In-Reply-To: <20200220151327.4823-1-manivannan.sadhasivam@linaro.org>
In order to start the QRTR nameservice, the local node ID needs to be
valid. Hence, fix it to 1. Previously, the node ID was configured through
a userspace tool before starting the nameservice daemon. Since we have now
integrated the nameservice handling to kernel, this change is necessary
for making it functional.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
net/qrtr/qrtr.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index c758383ba866..423310896285 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -7,7 +7,6 @@
#include <linux/netlink.h>
#include <linux/qrtr.h>
#include <linux/termios.h> /* For TIOCINQ/OUTQ */
-#include <linux/numa.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
@@ -97,7 +96,7 @@ static inline struct qrtr_sock *qrtr_sk(struct sock *sk)
return container_of(sk, struct qrtr_sock, sk);
}
-static unsigned int qrtr_local_nid = NUMA_NO_NODE;
+static unsigned int qrtr_local_nid = 1;
/* for node ids */
static RADIX_TREE(qrtr_nodes, GFP_ATOMIC);
--
2.17.1
^ permalink raw reply related
* [GIT PULL] context_tracking: Remove TIF_NOHZ from 3 archs
From: Frederic Weisbecker @ 2020-02-20 15:13 UTC (permalink / raw)
To: Thomas Gleixner, Ingo Molnar
Cc: LKML, Frederic Weisbecker, Paul Burton, Peter Zijlstra,
David S . Miller, Borislav Petkov, Benjamin Herrenschmidt,
Paul Mackerras, Andy Lutomirski, Ralf Baechle, Ingo Molnar,
Will Deacon, Catalin Marinas, Michael Ellerman, Russell King
In-Reply-To: <20200214152615.25447-1-frederic@kernel.org>
Ingo, Thomas,
Please pull the arch/nohz branch that can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks.git
arch/nohz
HEAD: 320a4fc2d1b0c2314342dfdd3348270f126196a4
---
TIF_NOHZ is getting deprecated by static keys which avoid to invoke
syscall slow path on every syscall. So remove that flag from
architectures that don't need it anymore (or worse yet: that spuriously
triggered syscall slow path when it's not needed anymore).
We hope to remove TIF_NOHZ entirely in the long run (PPC, MIPS, SPARC).
If we want to be able to enable/disable nohz full dynamically on runtime,
freezing all tasks and iterating through the whole tasklist to set/clear
TIF_NOHZ doesn't sound very appealing.
Thanks,
Frederic
---
Frederic Weisbecker (4):
context-tracking: Introduce CONFIG_HAVE_TIF_NOHZ
x86: Remove TIF_NOHZ
arm: Remove TIF_NOHZ
arm64: Remove TIF_NOHZ
Thomas Gleixner (1):
x86/entry: Remove _TIF_NOHZ from _TIF_WORK_SYSCALL_ENTRY
arch/Kconfig | 16 +++++++++++-----
arch/arm/include/asm/thread_info.h | 1 -
arch/arm64/include/asm/thread_info.h | 4 +---
arch/mips/Kconfig | 1 +
arch/powerpc/Kconfig | 1 +
arch/sparc/Kconfig | 1 +
arch/x86/include/asm/thread_info.h | 10 ++--------
kernel/context_tracking.c | 2 ++
8 files changed, 19 insertions(+), 17 deletions(-)
^ permalink raw reply
* Re: [PATCH V4 3/5] vDPA: introduce vDPA bus
From: Jason Gunthorpe @ 2020-02-20 15:14 UTC (permalink / raw)
To: Jason Wang
Cc: mst@redhat.com, linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
virtualization@lists.linux-foundation.org, netdev@vger.kernel.org,
tiwei.bie@intel.com, maxime.coquelin@redhat.com,
cunming.liang@intel.com, zhihong.wang@intel.com,
rob.miller@broadcom.com, xiao.w.wang@intel.com,
haotian.wang@sifive.com, lingshan.zhu@intel.com,
eperezma@redhat.com, lulu@redhat.com
In-Reply-To: <20200220061141.29390-4-jasowang@redhat.com>
On Thu, Feb 20, 2020 at 02:11:39PM +0800, Jason Wang wrote:
> vDPA device is a device that uses a datapath which complies with the
> virtio specifications with vendor specific control path. vDPA devices
> can be both physically located on the hardware or emulated by
> software. vDPA hardware devices are usually implemented through PCIE
> with the following types:
>
> - PF (Physical Function) - A single Physical Function
> - VF (Virtual Function) - Device that supports single root I/O
> virtualization (SR-IOV). Its Virtual Function (VF) represents a
> virtualized instance of the device that can be assigned to different
> partitions
> - ADI (Assignable Device Interface) and its equivalents - With
> technologies such as Intel Scalable IOV, a virtual device (VDEV)
> composed by host OS utilizing one or more ADIs. Or its equivalent
> like SF (Sub function) from Mellanox.
>
> From a driver's perspective, depends on how and where the DMA
> translation is done, vDPA devices are split into two types:
>
> - Platform specific DMA translation - From the driver's perspective,
> the device can be used on a platform where device access to data in
> memory is limited and/or translated. An example is a PCIE vDPA whose
> DMA request was tagged via a bus (e.g PCIE) specific way. DMA
> translation and protection are done at PCIE bus IOMMU level.
> - Device specific DMA translation - The device implements DMA
> isolation and protection through its own logic. An example is a vDPA
> device which uses on-chip IOMMU.
>
> To hide the differences and complexity of the above types for a vDPA
> device/IOMMU options and in order to present a generic virtio device
> to the upper layer, a device agnostic framework is required.
>
> This patch introduces a software vDPA bus which abstracts the
> common attributes of vDPA device, vDPA bus driver and the
> communication method (vdpa_config_ops) between the vDPA device
> abstraction and the vDPA bus driver. This allows multiple types of
> drivers to be used for vDPA device like the virtio_vdpa and vhost_vdpa
> driver to operate on the bus and allow vDPA device could be used by
> either kernel virtio driver or userspace vhost drivers as:
>
> virtio drivers vhost drivers
> | |
> [virtio bus] [vhost uAPI]
> | |
> virtio device vhost device
> virtio_vdpa drv vhost_vdpa drv
> \ /
> [vDPA bus]
> |
> vDPA device
> hardware drv
> |
> [hardware bus]
> |
> vDPA hardware
I still don't like this strange complexity, vhost should have been
layered on top of the virtio device instead of adding an extra bus
just for vdpa.
However, I don't see any technical problems with this patch now.
Thanks,
Jason
^ permalink raw reply
* Re: [PATCH -next] pinctrl: mediatek: remove set but not used variable 'e'
From: Linus Walleij @ 2020-02-20 15:14 UTC (permalink / raw)
To: YueHaibing
Cc: Sean Wang, Matthias Brugger, Light Hsieh,
moderated list:ARM/Mediatek SoC support, open list:GPIO SUBSYSTEM,
linux-arm-kernel, linux-kernel@vger.kernel.org
In-Reply-To: <20200218023625.14324-1-yuehaibing@huawei.com>
On Tue, Feb 18, 2020 at 3:36 AM YueHaibing <yuehaibing@huawei.com> wrote:
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c: In function mtk_hw_pin_field_lookup:
> drivers/pinctrl/mediatek/pinctrl-mtk-common-v2.c:70:39: warning:
> variable e set but not used [-Wunused-but-set-variable]
>
> Since commit 3de7deefce69 ("pinctrl: mediatek: Check gpio pin
> number and use binary search in mtk_hw_pin_field_lookup()"),
> it is not used any more, so remove it, also remove redundant
> assignment to variable c, it will be assigned a new value later
> before used.
>
> Reported-by: Hulk Robot <hulkci@huawei.com>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Patch applied with Matthias Review tag.
Yours,
Linus Walleij
^ permalink raw reply
* RE: [External] Re: [PATCH] thinkpad_acpi: Add sysfs entry for lcdshadow feature
From: Mark Pearson @ 2020-02-20 15:14 UTC (permalink / raw)
To: Andy Shevchenko, Nitin Joshi, Mat King, Jani Nikula,
Daniel Thompson, Jingoo Han, Rajat Jain
Cc: Henrique de Moraes Holschuh, Darren Hart, Andy Shevchenko,
Thinkpad-acpi devel ML, Platform Driver, Nitin Joshi1,
Benjamin Berg, Linux Kernel Mailing List, dri-devel,
Greg Kroah-Hartman
In-Reply-To: <CAHp75VcJmEOu1-b7F2UAsv=Gujb=pPLzjz2ye9t4=Q68+ors-w@mail.gmail.com>
Hi Andy
> -----Original Message-----
> From: Andy Shevchenko <andy.shevchenko@gmail.com>
> Sent: Thursday, February 20, 2020 5:43 AM
>
> On Thu, Feb 20, 2020 at 9:48 AM Nitin Joshi <nitjoshi@gmail.com> wrote:
> >
> > This feature is supported on some Thinkpad products like T490s, Thinkpad
> > X1 yoga 4th Gen etc . The lcdshadow feature can be enabled and disabled
> > when user press "Fn" + "D" key. Currently, no user feedback is given for
> > this action. Adding as sysfs entry allows userspace to show an On Screen
> > Display whenever the setting changes.
> >
> > Summary of changes is mentioned below :
> >
> > - Added TP_HKEY_EV_LCDSHADOW_CHANGED for consistency inside the
> driver
> > - Added unmapped LCDSHADOW to keymap
> > - Added lcdshadow_get function to read value using ACPI
> > - Added lcdshadow_refresh function to re-read value and send notification
> > - Added sysfs group creation to tpaci_lcdshadow_init
> > - Added lcdshadow_exit to remove sysfs group again
> > - Implemented lcdshadow_enable_show/lcdshadow_enable_store
> > - Added handler to tpacpi_driver_event to update refresh lcdshadow
> > - Explicitly call tpacpi_driver_event for extended keyset
>
> Adding custom PrivacyGuard support to this driver was my mistake,
> There is a discussion [1] how to do this in generic way to cover other
> possible users.
> I Cc this to people from that discussion.
>
> [1]: https://lore.kernel.org/dri-
> devel/CAL_quvRknSSVvXN3q_Se0hrziw2oTNS3ENNoeHYhvciCRq9Yww@mail
> .gmail.com/
>
Thanks for the pointer to that thread - really useful and interesting, we weren't aware there was an ongoing exercise to do this.
I work with Nitin as part of the Linux team at Lenovo. We're trying to get more directly and actively involved in the open source community to improve the Linux experience on Lenovo devices and of course want to make sure we contribute the right way. We're all still pretty new so pointers and help are very much appreciated (we've been getting some great support from the distros to get us started).
For this particular issue what is the best way to contribute and get involved? We'd like to make it so ePrivacy can be used more easily from Linux. I agree a more generic way of controlling it would be good.
I looked at the proposed patch from Rajat (https://lkml.org/lkml/2019/10/22/967) - it seems like a good solution to me. We can help with testing that on our platforms if that would be useful.
I need to understand how we connect that implementation with the ACPI controls we have (as I believe what we have are thinkpad specific and not to a drm spec; we need to confirm that). We also have the ACPI events that notify if ePrivacy was changed by the hotkeys and that seems like something that should be done in thinkpad_acpi.c and not the drm code. Not sure if the two need to be connected somehow (or if handling the event is actually not important and polling is acceptable)?
As a note Nitin has been working with the Red Hat folk and is looking at the user space aspect of this (in particularl gnome settings) as well.
Thanks
Mark Pearson
^ permalink raw reply
* Re: [PATCH V4 3/5] vDPA: introduce vDPA bus
From: Jason Gunthorpe @ 2020-02-20 15:14 UTC (permalink / raw)
To: Jason Wang
Cc: mst@redhat.com, linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
virtualization@lists.linux-foundation.org, netdev@vger.kernel.org,
tiwei.bie@intel.com, maxime.coquelin@redhat.com,
cunming.liang@intel.com, zhihong.wang@intel.com,
rob.miller@broadcom.com, xiao.w.wang@intel.com,
haotian.wang@sifive.com, lingshan.zhu@intel.com,
eperezma@redhat.com, lulu@redhat.com, Parav Pandit,
kevin.tian@intel.com, stefanha@redhat.com, rdunlap@infradead.org,
hch@infradead.org, aadam@redhat.com, Jiri Pirko, Shahaf Shuler,
hanand@xilinx.com, mhabets@solarflare.com
In-Reply-To: <20200220061141.29390-4-jasowang@redhat.com>
On Thu, Feb 20, 2020 at 02:11:39PM +0800, Jason Wang wrote:
> vDPA device is a device that uses a datapath which complies with the
> virtio specifications with vendor specific control path. vDPA devices
> can be both physically located on the hardware or emulated by
> software. vDPA hardware devices are usually implemented through PCIE
> with the following types:
>
> - PF (Physical Function) - A single Physical Function
> - VF (Virtual Function) - Device that supports single root I/O
> virtualization (SR-IOV). Its Virtual Function (VF) represents a
> virtualized instance of the device that can be assigned to different
> partitions
> - ADI (Assignable Device Interface) and its equivalents - With
> technologies such as Intel Scalable IOV, a virtual device (VDEV)
> composed by host OS utilizing one or more ADIs. Or its equivalent
> like SF (Sub function) from Mellanox.
>
> From a driver's perspective, depends on how and where the DMA
> translation is done, vDPA devices are split into two types:
>
> - Platform specific DMA translation - From the driver's perspective,
> the device can be used on a platform where device access to data in
> memory is limited and/or translated. An example is a PCIE vDPA whose
> DMA request was tagged via a bus (e.g PCIE) specific way. DMA
> translation and protection are done at PCIE bus IOMMU level.
> - Device specific DMA translation - The device implements DMA
> isolation and protection through its own logic. An example is a vDPA
> device which uses on-chip IOMMU.
>
> To hide the differences and complexity of the above types for a vDPA
> device/IOMMU options and in order to present a generic virtio device
> to the upper layer, a device agnostic framework is required.
>
> This patch introduces a software vDPA bus which abstracts the
> common attributes of vDPA device, vDPA bus driver and the
> communication method (vdpa_config_ops) between the vDPA device
> abstraction and the vDPA bus driver. This allows multiple types of
> drivers to be used for vDPA device like the virtio_vdpa and vhost_vdpa
> driver to operate on the bus and allow vDPA device could be used by
> either kernel virtio driver or userspace vhost drivers as:
>
> virtio drivers vhost drivers
> | |
> [virtio bus] [vhost uAPI]
> | |
> virtio device vhost device
> virtio_vdpa drv vhost_vdpa drv
> \ /
> [vDPA bus]
> |
> vDPA device
> hardware drv
> |
> [hardware bus]
> |
> vDPA hardware
I still don't like this strange complexity, vhost should have been
layered on top of the virtio device instead of adding an extra bus
just for vdpa.
However, I don't see any technical problems with this patch now.
Thanks,
Jason
^ permalink raw reply
* Re: [PATCH] pinctrl: mediatek: Fix some off by one bugs
From: Linus Walleij @ 2020-02-20 15:14 UTC (permalink / raw)
To: Dan Carpenter, Matthias Brugger
Cc: Sean Wang, Light Hsieh, moderated list:ARM/Mediatek SoC support,
open list:GPIO SUBSYSTEM, kernel-janitors
In-Reply-To: <20200218055247.74s2xa7veqx2do34@kili.mountain>
On Tue, Feb 18, 2020 at 6:55 AM Dan Carpenter <dan.carpenter@oracle.com> wrote:
> These comparisons should be >= instead of > to prevent accessing one
> element beyond the end of the hw->soc->pins[] array.
>
> Fixes: 3de7deefce69 ("pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Matthias could you have a look at this patch?
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v6 05/16] arc/mm: Use helper fault_signal_pending()
From: Peter Xu @ 2020-02-20 15:08 UTC (permalink / raw)
To: peterx, linux-mm, linux-kernel
Cc: Martin Cracauer, Mike Rapoport, Hugh Dickins, Jerome Glisse,
Kirill A . Shutemov, Matthew Wilcox, Pavel Emelyanov,
Brian Geffon, Maya Gokhale, Denis Plotnikov, Andrea Arcangeli,
Johannes Weiner, Dr . David Alan Gilbert, Linus Torvalds,
Mike Kravetz, Marty McFadden, David Hildenbrand, Bobby Powers,
Mel Gorman
In-Reply-To: <20200220145432.4561-1-peterx@redhat.com>
Let ARC to use the new helper fault_signal_pending() by moving the
signal check out of the retry logic as standalone. This should also
helps to simplify the code a bit.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
arch/arc/mm/fault.c | 34 +++++++++++++---------------------
1 file changed, 13 insertions(+), 21 deletions(-)
diff --git a/arch/arc/mm/fault.c b/arch/arc/mm/fault.c
index fb86bc3e9b35..6eb821a59b49 100644
--- a/arch/arc/mm/fault.c
+++ b/arch/arc/mm/fault.c
@@ -133,29 +133,21 @@ void do_page_fault(unsigned long address, struct pt_regs *regs)
fault = handle_mm_fault(vma, address, flags);
+ /* Quick path to respond to signals */
+ if (fault_signal_pending(fault, regs)) {
+ if (!user_mode(regs))
+ goto no_context;
+ return;
+ }
+
/*
- * Fault retry nuances
+ * Fault retry nuances, mmap_sem already relinquished by core mm
*/
- if (unlikely(fault & VM_FAULT_RETRY)) {
-
- /*
- * If fault needs to be retried, handle any pending signals
- * first (by returning to user mode).
- * mmap_sem already relinquished by core mm for RETRY case
- */
- if (fatal_signal_pending(current)) {
- if (!user_mode(regs))
- goto no_context;
- return;
- }
- /*
- * retry state machine
- */
- if (flags & FAULT_FLAG_ALLOW_RETRY) {
- flags &= ~FAULT_FLAG_ALLOW_RETRY;
- flags |= FAULT_FLAG_TRIED;
- goto retry;
- }
+ if (unlikely((fault & VM_FAULT_RETRY) &&
+ (flags & FAULT_FLAG_ALLOW_RETRY))) {
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+ flags |= FAULT_FLAG_TRIED;
+ goto retry;
}
bad_area:
--
2.24.1
^ permalink raw reply related
* Re: [PATCH 1/3] xfs: ensure that the inode uid/gid match values match the icdinode ones
From: Chandan Rajendra @ 2020-02-19 14:47 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-xfs, linux-fsdevel
In-Reply-To: <20200218210020.40846-2-hch@lst.de>
On Wednesday, February 19, 2020 2:30 AM Christoph Hellwig wrote:
> Instead of only synchronizing the uid/gid values in xfs_setup_inode,
> ensure that they always match to prepare for removing the icdinode
> fields.
>
The changes indeed keep the uid and gid values the same across icdinode and
vfs inode.
Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/libxfs/xfs_inode_buf.c | 2 ++
> fs/xfs/xfs_icache.c | 4 ++++
> fs/xfs/xfs_inode.c | 8 ++++++--
> fs/xfs/xfs_iops.c | 3 ---
> 4 files changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index 8afacfe4be0a..cc4efd34843a 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -223,7 +223,9 @@ xfs_inode_from_disk(
>
> to->di_format = from->di_format;
> to->di_uid = be32_to_cpu(from->di_uid);
> + inode->i_uid = xfs_uid_to_kuid(to->di_uid);
> to->di_gid = be32_to_cpu(from->di_gid);
> + inode->i_gid = xfs_gid_to_kgid(to->di_gid);
> to->di_flushiter = be16_to_cpu(from->di_flushiter);
>
> /*
> diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
> index 8dc2e5414276..a7be7a9e5c1a 100644
> --- a/fs/xfs/xfs_icache.c
> +++ b/fs/xfs/xfs_icache.c
> @@ -289,6 +289,8 @@ xfs_reinit_inode(
> uint64_t version = inode_peek_iversion(inode);
> umode_t mode = inode->i_mode;
> dev_t dev = inode->i_rdev;
> + kuid_t uid = inode->i_uid;
> + kgid_t gid = inode->i_gid;
>
> error = inode_init_always(mp->m_super, inode);
>
> @@ -297,6 +299,8 @@ xfs_reinit_inode(
> inode_set_iversion_queried(inode, version);
> inode->i_mode = mode;
> inode->i_rdev = dev;
> + inode->i_uid = uid;
> + inode->i_gid = gid;
> return error;
> }
>
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index c5077e6326c7..938b0943bd95 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -812,15 +812,19 @@ xfs_ialloc(
>
> inode->i_mode = mode;
> set_nlink(inode, nlink);
> - ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid());
> - ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid());
> + inode->i_uid = current_fsuid();
> + ip->i_d.di_uid = xfs_kuid_to_uid(inode->i_uid);
> inode->i_rdev = rdev;
> ip->i_d.di_projid = prid;
>
> if (pip && XFS_INHERIT_GID(pip)) {
> + inode->i_gid = VFS_I(pip)->i_gid;
> ip->i_d.di_gid = pip->i_d.di_gid;
> if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(mode))
> inode->i_mode |= S_ISGID;
> + } else {
> + inode->i_gid = current_fsgid();
> + ip->i_d.di_gid = xfs_kgid_to_gid(inode->i_gid);
> }
>
> /*
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index 81f2f93caec0..b818b261918f 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -1304,9 +1304,6 @@ xfs_setup_inode(
> /* make the inode look hashed for the writeback code */
> inode_fake_hash(inode);
>
> - inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid);
> - inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid);
> -
> i_size_write(inode, ip->i_d.di_size);
> xfs_diflags_to_iflags(inode, ip);
>
>
--
chandan
^ permalink raw reply
* Re: [PATCH] pinctrl: mediatek: Fix some off by one bugs
From: Linus Walleij @ 2020-02-20 15:14 UTC (permalink / raw)
To: Dan Carpenter, Matthias Brugger
Cc: Sean Wang, Light Hsieh, moderated list:ARM/Mediatek SoC support,
open list:GPIO SUBSYSTEM, kernel-janitors
In-Reply-To: <20200218055247.74s2xa7veqx2do34@kili.mountain>
On Tue, Feb 18, 2020 at 6:55 AM Dan Carpenter <dan.carpenter@oracle.com> wrote:
> These comparisons should be >= instead of > to prevent accessing one
> element beyond the end of the hw->soc->pins[] array.
>
> Fixes: 3de7deefce69 ("pinctrl: mediatek: Check gpio pin number and use binary search in mtk_hw_pin_field_lookup()")
> Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Matthias could you have a look at this patch?
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH 2/3] xfs: remove the icdinode di_uid/di_gid members
From: Chandan Rajendra @ 2020-02-19 16:25 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-xfs, linux-fsdevel
In-Reply-To: <20200218210020.40846-3-hch@lst.de>
On Wednesday, February 19, 2020 2:30 AM Christoph Hellwig wrote:
> Use the Linux inode i_uid/i_gid members everywhere and just convert
> from/to the scalar value when reading or writing the on-disk inode.
>
The conversion b/w kuid and on-disk uid is correct.
Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/xfs/libxfs/xfs_inode_buf.c | 10 ++++-----
> fs/xfs/libxfs/xfs_inode_buf.h | 2 --
> fs/xfs/xfs_dquot.c | 4 ++--
> fs/xfs/xfs_inode.c | 14 ++++--------
> fs/xfs/xfs_inode_item.c | 4 ++--
> fs/xfs/xfs_ioctl.c | 6 +++---
> fs/xfs/xfs_iops.c | 6 +-----
> fs/xfs/xfs_itable.c | 4 ++--
> fs/xfs/xfs_qm.c | 40 ++++++++++++++++++++++-------------
> fs/xfs/xfs_quota.h | 4 ++--
> fs/xfs/xfs_symlink.c | 4 +---
> 11 files changed, 46 insertions(+), 52 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c
> index cc4efd34843a..bc72b575ceed 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.c
> +++ b/fs/xfs/libxfs/xfs_inode_buf.c
> @@ -222,10 +222,8 @@ xfs_inode_from_disk(
> }
>
> to->di_format = from->di_format;
> - to->di_uid = be32_to_cpu(from->di_uid);
> - inode->i_uid = xfs_uid_to_kuid(to->di_uid);
> - to->di_gid = be32_to_cpu(from->di_gid);
> - inode->i_gid = xfs_gid_to_kgid(to->di_gid);
> + inode->i_uid = xfs_uid_to_kuid(be32_to_cpu(from->di_uid));
> + inode->i_gid = xfs_gid_to_kgid(be32_to_cpu(from->di_gid));
> to->di_flushiter = be16_to_cpu(from->di_flushiter);
>
> /*
> @@ -278,8 +276,8 @@ xfs_inode_to_disk(
>
> to->di_version = from->di_version;
> to->di_format = from->di_format;
> - to->di_uid = cpu_to_be32(from->di_uid);
> - to->di_gid = cpu_to_be32(from->di_gid);
> + to->di_uid = cpu_to_be32(xfs_kuid_to_uid(inode->i_uid));
> + to->di_gid = cpu_to_be32(xfs_kgid_to_gid(inode->i_gid));
> to->di_projid_lo = cpu_to_be16(from->di_projid & 0xffff);
> to->di_projid_hi = cpu_to_be16(from->di_projid >> 16);
>
> diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h
> index fd94b1078722..2683e1e2c4a6 100644
> --- a/fs/xfs/libxfs/xfs_inode_buf.h
> +++ b/fs/xfs/libxfs/xfs_inode_buf.h
> @@ -19,8 +19,6 @@ struct xfs_icdinode {
> int8_t di_version; /* inode version */
> int8_t di_format; /* format of di_c data */
> uint16_t di_flushiter; /* incremented on flush */
> - uint32_t di_uid; /* owner's user id */
> - uint32_t di_gid; /* owner's group id */
> uint32_t di_projid; /* owner's project id */
> xfs_fsize_t di_size; /* number of bytes in file */
> xfs_rfsblock_t di_nblocks; /* # of direct & btree blocks used */
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index d223e1ae90a6..3579de9306c1 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -829,9 +829,9 @@ xfs_qm_id_for_quotatype(
> {
> switch (type) {
> case XFS_DQ_USER:
> - return ip->i_d.di_uid;
> + return xfs_kuid_to_uid(VFS_I(ip)->i_uid);
> case XFS_DQ_GROUP:
> - return ip->i_d.di_gid;
> + return xfs_kgid_to_gid(VFS_I(ip)->i_gid);
> case XFS_DQ_PROJ:
> return ip->i_d.di_projid;
> }
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index 938b0943bd95..3324e1696354 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -813,18 +813,15 @@ xfs_ialloc(
> inode->i_mode = mode;
> set_nlink(inode, nlink);
> inode->i_uid = current_fsuid();
> - ip->i_d.di_uid = xfs_kuid_to_uid(inode->i_uid);
> inode->i_rdev = rdev;
> ip->i_d.di_projid = prid;
>
> if (pip && XFS_INHERIT_GID(pip)) {
> inode->i_gid = VFS_I(pip)->i_gid;
> - ip->i_d.di_gid = pip->i_d.di_gid;
> if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(mode))
> inode->i_mode |= S_ISGID;
> } else {
> inode->i_gid = current_fsgid();
> - ip->i_d.di_gid = xfs_kgid_to_gid(inode->i_gid);
> }
>
> /*
> @@ -832,9 +829,8 @@ xfs_ialloc(
> * ID or one of the supplementary group IDs, the S_ISGID bit is cleared
> * (and only if the irix_sgid_inherit compatibility variable is set).
> */
> - if ((irix_sgid_inherit) &&
> - (inode->i_mode & S_ISGID) &&
> - (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid))))
> + if (irix_sgid_inherit &&
> + (inode->i_mode & S_ISGID) && !in_group_p(inode->i_gid))
> inode->i_mode &= ~S_ISGID;
>
> ip->i_d.di_size = 0;
> @@ -1162,8 +1158,7 @@ xfs_create(
> /*
> * Make sure that we have allocated dquot(s) on disk.
> */
> - error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()),
> - xfs_kgid_to_gid(current_fsgid()), prid,
> + error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
> XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
> &udqp, &gdqp, &pdqp);
> if (error)
> @@ -1313,8 +1308,7 @@ xfs_create_tmpfile(
> /*
> * Make sure that we have allocated dquot(s) on disk.
> */
> - error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()),
> - xfs_kgid_to_gid(current_fsgid()), prid,
> + error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
> XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
> &udqp, &gdqp, &pdqp);
> if (error)
> diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
> index 8bd5d0de6321..83d7914556ef 100644
> --- a/fs/xfs/xfs_inode_item.c
> +++ b/fs/xfs/xfs_inode_item.c
> @@ -308,8 +308,8 @@ xfs_inode_to_log_dinode(
>
> to->di_version = from->di_version;
> to->di_format = from->di_format;
> - to->di_uid = from->di_uid;
> - to->di_gid = from->di_gid;
> + to->di_uid = xfs_kuid_to_uid(inode->i_uid);
> + to->di_gid = xfs_kgid_to_gid(inode->i_gid);
> to->di_projid_lo = from->di_projid & 0xffff;
> to->di_projid_hi = from->di_projid >> 16;
>
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index d42de92cb283..0f85bedc5977 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -1434,9 +1434,9 @@ xfs_ioctl_setattr(
> * because the i_*dquot fields will get updated anyway.
> */
> if (XFS_IS_QUOTA_ON(mp)) {
> - code = xfs_qm_vop_dqalloc(ip, ip->i_d.di_uid,
> - ip->i_d.di_gid, fa->fsx_projid,
> - XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
> + code = xfs_qm_vop_dqalloc(ip, VFS_I(ip)->i_uid,
> + VFS_I(ip)->i_gid, fa->fsx_projid,
> + XFS_QMOPT_PQUOTA, &udqp, NULL, &pdqp);
> if (code)
> return code;
> }
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index b818b261918f..a5b7c3100a2f 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -692,9 +692,7 @@ xfs_setattr_nonsize(
> */
> ASSERT(udqp == NULL);
> ASSERT(gdqp == NULL);
> - error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(uid),
> - xfs_kgid_to_gid(gid),
> - ip->i_d.di_projid,
> + error = xfs_qm_vop_dqalloc(ip, uid, gid, ip->i_d.di_projid,
> qflags, &udqp, &gdqp, NULL);
> if (error)
> return error;
> @@ -763,7 +761,6 @@ xfs_setattr_nonsize(
> olddquot1 = xfs_qm_vop_chown(tp, ip,
> &ip->i_udquot, udqp);
> }
> - ip->i_d.di_uid = xfs_kuid_to_uid(uid);
> inode->i_uid = uid;
> }
> if (!gid_eq(igid, gid)) {
> @@ -775,7 +772,6 @@ xfs_setattr_nonsize(
> olddquot2 = xfs_qm_vop_chown(tp, ip,
> &ip->i_gdquot, gdqp);
> }
> - ip->i_d.di_gid = xfs_kgid_to_gid(gid);
> inode->i_gid = gid;
> }
> }
> diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
> index 4b31c29b7e6b..497db4160283 100644
> --- a/fs/xfs/xfs_itable.c
> +++ b/fs/xfs/xfs_itable.c
> @@ -86,8 +86,8 @@ xfs_bulkstat_one_int(
> */
> buf->bs_projectid = ip->i_d.di_projid;
> buf->bs_ino = ino;
> - buf->bs_uid = dic->di_uid;
> - buf->bs_gid = dic->di_gid;
> + buf->bs_uid = xfs_kuid_to_uid(inode->i_uid);
> + buf->bs_gid = xfs_kgid_to_gid(inode->i_gid);
> buf->bs_size = dic->di_size;
>
> buf->bs_nlink = inode->i_nlink;
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index 0b0909657bad..54dda7d982c9 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -326,16 +326,18 @@ xfs_qm_dqattach_locked(
> ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
>
> if (XFS_IS_UQUOTA_ON(mp) && !ip->i_udquot) {
> - error = xfs_qm_dqattach_one(ip, ip->i_d.di_uid, XFS_DQ_USER,
> - doalloc, &ip->i_udquot);
> + error = xfs_qm_dqattach_one(ip,
> + xfs_kuid_to_uid(VFS_I(ip)->i_uid),
> + XFS_DQ_USER, doalloc, &ip->i_udquot);
> if (error)
> goto done;
> ASSERT(ip->i_udquot);
> }
>
> if (XFS_IS_GQUOTA_ON(mp) && !ip->i_gdquot) {
> - error = xfs_qm_dqattach_one(ip, ip->i_d.di_gid, XFS_DQ_GROUP,
> - doalloc, &ip->i_gdquot);
> + error = xfs_qm_dqattach_one(ip,
> + xfs_kgid_to_gid(VFS_I(ip)->i_gid),
> + XFS_DQ_GROUP, doalloc, &ip->i_gdquot);
> if (error)
> goto done;
> ASSERT(ip->i_gdquot);
> @@ -1613,8 +1615,8 @@ xfs_qm_dqfree_one(
> int
> xfs_qm_vop_dqalloc(
> struct xfs_inode *ip,
> - xfs_dqid_t uid,
> - xfs_dqid_t gid,
> + kuid_t uid,
> + kgid_t gid,
> prid_t prid,
> uint flags,
> struct xfs_dquot **O_udqpp,
> @@ -1622,6 +1624,7 @@ xfs_qm_vop_dqalloc(
> struct xfs_dquot **O_pdqpp)
> {
> struct xfs_mount *mp = ip->i_mount;
> + struct inode *inode = VFS_I(ip);
> struct xfs_dquot *uq = NULL;
> struct xfs_dquot *gq = NULL;
> struct xfs_dquot *pq = NULL;
> @@ -1635,7 +1638,7 @@ xfs_qm_vop_dqalloc(
> xfs_ilock(ip, lockflags);
>
> if ((flags & XFS_QMOPT_INHERIT) && XFS_INHERIT_GID(ip))
> - gid = ip->i_d.di_gid;
> + gid = inode->i_gid;
>
> /*
> * Attach the dquot(s) to this inode, doing a dquot allocation
> @@ -1650,7 +1653,7 @@ xfs_qm_vop_dqalloc(
> }
>
> if ((flags & XFS_QMOPT_UQUOTA) && XFS_IS_UQUOTA_ON(mp)) {
> - if (ip->i_d.di_uid != uid) {
> + if (!uid_eq(inode->i_uid, uid)) {
> /*
> * What we need is the dquot that has this uid, and
> * if we send the inode to dqget, the uid of the inode
> @@ -1661,7 +1664,8 @@ xfs_qm_vop_dqalloc(
> * holding ilock.
> */
> xfs_iunlock(ip, lockflags);
> - error = xfs_qm_dqget(mp, uid, XFS_DQ_USER, true, &uq);
> + error = xfs_qm_dqget(mp, xfs_kuid_to_uid(uid),
> + XFS_DQ_USER, true, &uq);
> if (error) {
> ASSERT(error != -ENOENT);
> return error;
> @@ -1682,9 +1686,10 @@ xfs_qm_vop_dqalloc(
> }
> }
> if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) {
> - if (ip->i_d.di_gid != gid) {
> + if (!gid_eq(inode->i_gid, gid)) {
> xfs_iunlock(ip, lockflags);
> - error = xfs_qm_dqget(mp, gid, XFS_DQ_GROUP, true, &gq);
> + error = xfs_qm_dqget(mp, xfs_kgid_to_gid(gid),
> + XFS_DQ_GROUP, true, &gq);
> if (error) {
> ASSERT(error != -ENOENT);
> goto error_rele;
> @@ -1810,7 +1815,8 @@ xfs_qm_vop_chown_reserve(
> XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS;
>
> if (XFS_IS_UQUOTA_ON(mp) && udqp &&
> - ip->i_d.di_uid != be32_to_cpu(udqp->q_core.d_id)) {
> + xfs_kuid_to_uid(VFS_I(ip)->i_uid) !=
> + be32_to_cpu(udqp->q_core.d_id)) {
> udq_delblks = udqp;
> /*
> * If there are delayed allocation blocks, then we have to
> @@ -1823,7 +1829,8 @@ xfs_qm_vop_chown_reserve(
> }
> }
> if (XFS_IS_GQUOTA_ON(ip->i_mount) && gdqp &&
> - ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) {
> + xfs_kgid_to_gid(VFS_I(ip)->i_gid) !=
> + be32_to_cpu(gdqp->q_core.d_id)) {
> gdq_delblks = gdqp;
> if (delblks) {
> ASSERT(ip->i_gdquot);
> @@ -1920,14 +1927,17 @@ xfs_qm_vop_create_dqattach(
>
> if (udqp && XFS_IS_UQUOTA_ON(mp)) {
> ASSERT(ip->i_udquot == NULL);
> - ASSERT(ip->i_d.di_uid == be32_to_cpu(udqp->q_core.d_id));
> + ASSERT(xfs_kuid_to_uid(VFS_I(ip)->i_uid) ==
> + be32_to_cpu(udqp->q_core.d_id));
>
> ip->i_udquot = xfs_qm_dqhold(udqp);
> xfs_trans_mod_dquot(tp, udqp, XFS_TRANS_DQ_ICOUNT, 1);
> }
> if (gdqp && XFS_IS_GQUOTA_ON(mp)) {
> ASSERT(ip->i_gdquot == NULL);
> - ASSERT(ip->i_d.di_gid == be32_to_cpu(gdqp->q_core.d_id));
> + ASSERT(xfs_kgid_to_gid(VFS_I(ip)->i_gid) ==
> + be32_to_cpu(gdqp->q_core.d_id));
> +
> ip->i_gdquot = xfs_qm_dqhold(gdqp);
> xfs_trans_mod_dquot(tp, gdqp, XFS_TRANS_DQ_ICOUNT, 1);
> }
> diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
> index efe42ae7a2f3..aa8fc1f55fbd 100644
> --- a/fs/xfs/xfs_quota.h
> +++ b/fs/xfs/xfs_quota.h
> @@ -86,7 +86,7 @@ extern int xfs_trans_reserve_quota_bydquots(struct xfs_trans *,
> struct xfs_mount *, struct xfs_dquot *,
> struct xfs_dquot *, struct xfs_dquot *, int64_t, long, uint);
>
> -extern int xfs_qm_vop_dqalloc(struct xfs_inode *, xfs_dqid_t, xfs_dqid_t,
> +extern int xfs_qm_vop_dqalloc(struct xfs_inode *, kuid_t, kgid_t,
> prid_t, uint, struct xfs_dquot **, struct xfs_dquot **,
> struct xfs_dquot **);
> extern void xfs_qm_vop_create_dqattach(struct xfs_trans *, struct xfs_inode *,
> @@ -109,7 +109,7 @@ extern void xfs_qm_unmount_quotas(struct xfs_mount *);
>
> #else
> static inline int
> -xfs_qm_vop_dqalloc(struct xfs_inode *ip, xfs_dqid_t uid, xfs_dqid_t gid,
> +xfs_qm_vop_dqalloc(struct xfs_inode *ip, kuid_t kuid, kgid_t kgid,
> prid_t prid, uint flags, struct xfs_dquot **udqp,
> struct xfs_dquot **gdqp, struct xfs_dquot **pdqp)
> {
> diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
> index d762d42ed0ff..ea42e25ec1bf 100644
> --- a/fs/xfs/xfs_symlink.c
> +++ b/fs/xfs/xfs_symlink.c
> @@ -182,9 +182,7 @@ xfs_symlink(
> /*
> * Make sure that we have allocated dquot(s) on disk.
> */
> - error = xfs_qm_vop_dqalloc(dp,
> - xfs_kuid_to_uid(current_fsuid()),
> - xfs_kgid_to_gid(current_fsgid()), prid,
> + error = xfs_qm_vop_dqalloc(dp, current_fsuid(), current_fsgid(), prid,
> XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
> &udqp, &gdqp, &pdqp);
> if (error)
>
--
chandan
^ permalink raw reply
* Re: S variable for svn fetcher Was: State of OE world - 2020-02-18
From: Adrian Bunk @ 2020-02-20 15:16 UTC (permalink / raw)
To: Martin Jansa; +Cc: openembeded-devel
In-Reply-To: <20200220144848.msiyguq2bsmqokxc@jama>
On Thu, Feb 20, 2020 at 03:48:48PM +0100, Martin Jansa wrote:
>...
> Any idea why these aren't shown in our build?
>...
What is your mirror configuration?
Default configuration downloads the tarball from [1].
> Cheers,
cu
Adrian
[1] http://downloads.yoctoproject.org/mirror/sources/
^ permalink raw reply
* Re: [PATCH 3/4] Btrfs: resurrect extent_read_full_page_nolock()
From: Josef Bacik @ 2020-02-20 15:16 UTC (permalink / raw)
To: fdmanana, linux-btrfs
In-Reply-To: <20200219140606.1641625-1-fdmanana@kernel.org>
On 2/19/20 9:06 AM, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
>
> Commit 7f042a8370a5bb ("Btrfs: remove no longer used function
> extent_read_full_page_nolock()") removed extent_read_full_page_nolock()
> because it was not needed anymore.
>
> This function was used to read a page while holding the respective range
> locked in the inode's iotree, to avoid deadlocks when using the other
> APIs we have for reading a page (which lock and unlock the range
> themselves).
>
> Since this type of functionality is needed for the upcoming changes to
> the reflink implementation dealing with cloning of inline extents, bring
> back this function to life.
>
> Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Josef Bacik <josef@toxicpanda.com>
Thanks,
Josef
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.