Messages in this thread | | | From | Ankit Jindal <> | Date | Wed, 19 Aug 2015 15:25:09 +0530 | Subject | Re: Unmapping of UIO logical memory causing a trace |
| |
Hi Greg,
On Wed, Aug 12, 2015 at 10:41 PM, Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote: > On Wed, Aug 12, 2015 at 01:25:53PM +0530, Ankit Jindal wrote: >> Hi Greg, >> >> On Wed, Aug 12, 2015 at 3:15 AM, Greg Kroah-Hartman >> <gregkh@linuxfoundation.org> wrote: >> > On Tue, Aug 11, 2015 at 04:39:08PM +0530, Ankit Jindal wrote: >> >> Hi, >> >> >> >> We have observed an issue where kmalloc of a small sized memory causes >> >> an occasional trace when unmapping the mmaped memory via UIO framework >> >> This trace is coming when kernel sees a negative value in >> >> page->_mapcount. Trace is pasted at the end of the mail. >> >> >> >> After debugging this issue further, we realized following sequence >> >> occurs when kmalloc is used to allocate small memory using slub >> >> allocator: >> >> 1. Frozen bit (msb) of the page from which memory has been allocated >> >> is set (which is an union with _mapcount). >> >> 2. If there are free objects in the the same page then this frozen bit >> >> remains set even after kernel boots completely. >> >> 3. When user space calls unmap of this memory, vma_unmap_single() >> >> treats the _mapcount as a negative (as frozen bit is set), causing a >> >> trace. >> >> >> >> We are not sure whether exposing kernel memory of size >> >> less than PAGE_SIZE via UIO is a valid use case ? In case this is an invalid >> >> use case then shouldn't the UIO framework restrict mapping of non >> >> PAGE_SIZE aligned memory and size not in order of PAGE_SIZE. >> > >> > We've had a few discussions about this in the past, and one proposed >> > patch which had to be reverted because it broke some working systems, so >> > it's a messy thing. >> > >> > What UIO driver are you using that causes this behavior? >> >> We have observed this during the development of new UIO driver for our >> soc. In our driver, we need to parse non probable properties of device >> and provide these details to our user application. > > What exactly do you mean by this?
There are certain the device specific properties (coming from device tree) which we are exposing using UIO_LOGICAL_MEM to the user space.
> >> For this we do a kmalloc of device info(approx size 80 bytes) and pass >> this address to user space via UIO mem logical. > > For such tiny sizes, why not just use a normal sysfs file?
We did not think of sysfs as an option, since UIO_MEM_LOGICAL seems to address our use case.
> > Do you have a pointer to your driver so that I can see exactly what it > is doing here?
Below is the code snippet of my driver.
struct reserved_qgroup { uint32_t qstart; uint32_t qend; uint32_t valid; };
struct my_dev_info { uint32_t num_queues; uint32_t version; struct reserved_qgroup resvd_qgrps[MAX_RESVD_QGROUPS]; };
static int my_dev_probe(struct platform_device *pdev) {
struct property *prop; struct my_dev_info *dev_info;
dev_info = devm_kzalloc(&pdev->dev, sizeof(*dev_info), GFP_KERNEL);
if (!dev_info) return -ENOMEM;
prop = of_find_property(pdev->dev.of_node, "reserved-qgroups", NULL);
if (prop) { const __be32 *reserved_qid = NULL; unsigned int i; uint32_t qid_start, qid_end;
for (i = 0; i < MAX_RESVD_QGROUPS; i++) { reserved_qid = of_prop_next_u32(prop, reserved_qid, &qid_start); if (!reserved_qid) break; reserved_qid = of_prop_next_u32(prop, reserved_qid, &qid_end); if (!reserved_qid) break;
dev_info->resvd_qgrps[i].qstart = qid_start; dev_info->resvd_qgrps[i].qend = qid_end; dev_info->resvd_qgrps[i].valid = 1; } }
ret = of_property_read_u32(pdev->dev.of_node, "num-queues", dev_info->num_queues); if (ret < 0) { dev_err(&pdev->dev, "No num-queues resource specified\n"); goto out_err; }
info->mem[3].name = "dev-info"; info->mem[3].addr = (phys_addr_t) dev_info; info->mem[3].size = sizeof(struct dev_info); info->mem[3].memtype = UIO_MEM_LOGICAL;
...... }
Thanks, Ankit
| |